diff --git a/app/Lila.scala b/app/Lila.scala
index b98bb8b0034c2..54647dde208ea 100644
--- a/app/Lila.scala
+++ b/app/Lila.scala
@@ -1,6 +1,6 @@
package lila.app
-import java.io._
+import java.io.*
import play.api.{ Application, Environment, Play, Configuration, Mode }
import play.core.server.{ RealServerProcess, ServerProcess, Server, ServerStartException, ServerConfig }
@@ -96,7 +96,7 @@ object Lila:
val address = configuration.getOptional[String]("play.server.http.address").getOrElse("0.0.0.0")
val mode =
- if (configuration.getOptional[String]("play.mode").contains("prod")) Mode.Prod
+ if configuration.getOptional[String]("play.mode").contains("prod") then Mode.Prod
else Mode.Dev
ServerConfig(rootDir, httpPort, address, mode, process.properties, configuration)
diff --git a/app/LoggerConfigurator.scala b/app/LoggerConfigurator.scala
index 3b0df5592d950..b67d87184ee50 100644
--- a/app/LoggerConfigurator.scala
+++ b/app/LoggerConfigurator.scala
@@ -3,12 +3,12 @@ package lila.app
import java.io.File
import java.net.URL
-import ch.qos.logback.classic._
+import ch.qos.logback.classic.*
import ch.qos.logback.classic.jul.LevelChangePropagator
import ch.qos.logback.classic.util.ContextInitializer
-import ch.qos.logback.core.util._
+import ch.qos.logback.core.util.*
import org.slf4j.{ LoggerFactory, ILoggerFactory }
-import org.slf4j.bridge._
+import org.slf4j.bridge.*
private object LoggerConfigurator:
@@ -20,7 +20,7 @@ private object LoggerConfigurator:
new File(sys.props.get("logger.file").getOrElse("conf/logger.dev.xml")).toURI.toURL
)
- def configure(properties: Map[String, String], configUrl: URL): Unit = {
+ def configure(properties: Map[String, String], configUrl: URL): Unit =
// Touching LoggerContext is not thread-safe, and so if you run several
// application tests at the same time (spec2 / scalatest with "new WithApplication()")
// then you will see NullPointerException as the array list loggerContextListenerList
@@ -71,7 +71,6 @@ private object LoggerConfigurator:
StatusPrinter.printIfErrorsOccured(ctx)
// }
- }
def shutdown(): Unit =
val ctx = loggerFactory.asInstanceOf[LoggerContext]
diff --git a/app/controllers/Api.scala b/app/controllers/Api.scala
index 4eb5eeeb65437..793b342b90b93 100644
--- a/app/controllers/Api.scala
+++ b/app/controllers/Api.scala
@@ -215,7 +215,7 @@ final class Api(
val result =
if csv then csvDownload(lila.tournament.TournamentCsv(source))
else jsonDownload(source.map(lila.tournament.JsonView.playerResultWrites.writes))
- result.pipe(asAttachment(env.api.gameApiV2.filename(tour, if (csv) "csv" else "ndjson")))
+ result.pipe(asAttachment(env.api.gameApiV2.filename(tour, if csv then "csv" else "ndjson")))
}
def tournamentTeams(id: TourId) = Anon:
@@ -306,7 +306,7 @@ final class Api(
transform: String => Option[Id]
)(f: Set[Id] => Result): Result =
val ids = req.body.split(',').view.filter(_.nonEmpty).flatMap(s => transform(s.trim)).toSet
- if (ids.size > max) JsonBadRequest(jsonError(s"Too many ids: ${ids.size}, expected up to $max"))
+ if ids.size > max then JsonBadRequest(jsonError(s"Too many ids: ${ids.size}, expected up to $max"))
else f(ids)
val cloudEval =
diff --git a/app/controllers/Auth.scala b/app/controllers/Auth.scala
index 68c86263ffdd0..fad94cce8868e 100644
--- a/app/controllers/Auth.scala
+++ b/app/controllers/Auth.scala
@@ -88,7 +88,7 @@ final class Auth(
def authenticate = OpenBody:
NoCrawlers:
Firewall:
- def redirectTo(url: String) = if (HTTPRequest isXhr ctx.req) Ok(s"ok:$url") else Redirect(url)
+ def redirectTo(url: String) = if HTTPRequest isXhr ctx.req then Ok(s"ok:$url") else Redirect(url)
val referrer = get("referrer").filterNot(env.api.referrerRedirect.sillyLoginReferrers)
api.loginForm
.bindFromRequest()
@@ -204,7 +204,7 @@ final class Auth(
ctx: Context
): Funit =
garbageCollect(user)(email)
- if (sendWelcomeEmail) env.mailer.automaticEmail.welcomeEmail(user, email)
+ if sendWelcomeEmail then env.mailer.automaticEmail.welcomeEmail(user, email)
env.mailer.automaticEmail.welcomePM(user)
env.pref.api.saveNewUserPrefs(user, ctx.req)
@@ -382,7 +382,7 @@ final class Auth(
def magicLinkApply = OpenBody:
Firewall:
env.security.hcaptcha.verify() flatMap { captcha =>
- if (captcha.ok)
+ if captcha.ok then
forms.magicLink flatMap {
_.form
.bindFromRequest()
@@ -401,8 +401,7 @@ final class Auth(
}
)
}
- else
- renderMagicLink(none, fail = true) map { BadRequest(_) }
+ else renderMagicLink(none, fail = true) map { BadRequest(_) }
}
def magicLinkSent = Open:
diff --git a/app/controllers/Challenge.scala b/app/controllers/Challenge.scala
index dc2d69fbd6408..1fa6072eeb38a 100644
--- a/app/controllers/Challenge.scala
+++ b/app/controllers/Challenge.scala
@@ -129,7 +129,7 @@ final class Challenge(
_ map { game =>
env.lilaCookie.cookie(
AnonCookie.name,
- game.player(if (owner) c.finalColor else !c.finalColor).id.value,
+ game.player(if owner then c.finalColor else !c.finalColor).id.value,
maxAge = AnonCookie.maxAge.some,
httpOnly = false.some
)
diff --git a/app/controllers/Clas.scala b/app/controllers/Clas.scala
index 51ff080747c0d..89383f550d4f0 100644
--- a/app/controllers/Clas.scala
+++ b/app/controllers/Clas.scala
@@ -10,7 +10,7 @@ import views.*
import lila.app.{ given, * }
import lila.clas.ClasInvite
-import lila.clas.Clas.{ Id => ClasId }
+import lila.clas.Clas.{ Id as ClasId }
final class Clas(env: Env, authC: Auth) extends LilaController(env):
@@ -107,7 +107,7 @@ final class Clas(env: Env, authC: Auth) extends LilaController(env):
else
Found(env.clas.api.clas.byId(id)): clas =>
env.clas.api.student.activeWithUsers(clas) flatMap { students =>
- if (students.exists(_.student is me)) forStudent(clas, students)
+ if students.exists(_.student is me) then forStudent(clas, students)
else orDefault(ctx)
}
}
@@ -173,7 +173,7 @@ final class Clas(env: Env, authC: Auth) extends LilaController(env):
env.clas.api.student.activeWithUsers(clas) flatMap { students =>
Reasonable(clas, students, "notify"):
val url = routes.Clas.show(clas.id.value).url
- val full = if (text contains url) text else s"$text\n\n${env.net.baseUrl}$url"
+ val full = if text contains url then text else s"$text\n\n${env.net.baseUrl}$url"
env.msg.api
.multiPost(Source(students.map(_.user.id)), full)
.addEffect: nb =>
diff --git a/app/controllers/Dasher.scala b/app/controllers/Dasher.scala
index 454d6d41e0f54..13586e6ad01a3 100644
--- a/app/controllers/Dasher.scala
+++ b/app/controllers/Dasher.scala
@@ -43,12 +43,12 @@ final class Dasher(env: Env)(using ws: StandaloneWSClient) extends LilaControlle
private def translations(using Context) =
lila.i18n.JsDump.keysToObject(
- if (ctx.isAnon) translationsAnon else translationsAuth,
+ if ctx.isAnon then translationsAnon else translationsAuth,
ctx.lang
) ++ lila.i18n.JsDump.keysToObject(
// the language settings should never be in a totally foreign language
List(trans.language),
- if (I18nLangPicker.allFromRequestHeaders(ctx.req).has(ctx.lang)) ctx.lang
+ if I18nLangPicker.allFromRequestHeaders(ctx.req).has(ctx.lang) then ctx.lang
else I18nLangPicker.bestFromRequestHeaders(ctx.req) | enLang
)
diff --git a/app/controllers/Editor.scala b/app/controllers/Editor.scala
index de10189225a59..7c9e8fc4b6ab2 100644
--- a/app/controllers/Editor.scala
+++ b/app/controllers/Editor.scala
@@ -48,7 +48,7 @@ final class Editor(env: Env) extends LilaController(env):
else editorUrl(get("fen").fold(Fen.write(game.chess))(Fen.Epd.clean), game.variant)
private[controllers] def editorUrl(fen: Fen.Epd, variant: Variant): String =
- if (fen == Fen.initial && variant.standard) routes.Editor.index.url
+ if fen == Fen.initial && variant.standard then routes.Editor.index.url
else
val params = variant.exotic so s"?variant=${variant.key}"
routes.Editor.load(lila.common.String.underscoreFen(fen)).url + params
diff --git a/app/controllers/Export.scala b/app/controllers/Export.scala
index 1cbe4dc567aca..fae66c5236abd 100644
--- a/app/controllers/Export.scala
+++ b/app/controllers/Export.scala
@@ -38,7 +38,7 @@ final class Export(env: Env) extends LilaController(env):
g.fen,
Theme(theme).name,
PieceSet.get(piece).name
- ) pipe stream(cacheSeconds = if (g.game.finishedOrAborted) 3600 * 24 else 10)
+ ) pipe stream(cacheSeconds = if g.game.finishedOrAborted then 3600 * 24 else 10)
}
def legacyGameThumbnail(id: GameId, theme: Option[String], piece: Option[String]) = Anon:
@@ -47,7 +47,7 @@ final class Export(env: Env) extends LilaController(env):
def gameThumbnail(id: GameId, theme: Option[String], piece: Option[String]) =
exportImageOf(env.game.gameRepo game id) { game =>
env.game.gifExport.gameThumbnail(game, Theme(theme).name, PieceSet.get(piece).name) pipe
- stream(cacheSeconds = if (game.finishedOrAborted) 3600 * 24 else 10)
+ stream(cacheSeconds = if game.finishedOrAborted then 3600 * 24 else 10)
}
def puzzleThumbnail(id: PuzzleId, theme: Option[String], piece: Option[String]) =
diff --git a/app/controllers/ForumController.scala b/app/controllers/ForumController.scala
index c70318a6634db..14bdba201b937 100644
--- a/app/controllers/ForumController.scala
+++ b/app/controllers/ForumController.scala
@@ -5,7 +5,8 @@ import play.api.mvc.*
import lila.app.{ given, * }
import lila.forum.ForumTopic
-private[controllers] trait ForumController { self: LilaController =>
+private[controllers] trait ForumController:
+ self: LilaController =>
protected def categApi = env.forum.categApi
protected def topicApi = env.forum.topicApi
@@ -55,4 +56,3 @@ private[controllers] trait ForumController { self: LilaController =>
else Forbidden("You cannot moderate this forum")
}
}
-}
diff --git a/app/controllers/ForumPost.scala b/app/controllers/ForumPost.scala
index 1543a039b823e..b18f27c5e75f7 100644
--- a/app/controllers/ForumPost.scala
+++ b/app/controllers/ForumPost.scala
@@ -97,8 +97,8 @@ final class ForumPost(env: Env) extends LilaController(env) with ForumController
topic <- topicRepo.forUser(me.some).byId(post.topicId)
reason <- reasonOpt.filter(MsgPreset.forumDeletion.presets.contains)
preset =
- if (isGranted(_.ModerateForum)) MsgPreset.forumDeletion.byModerator
- else if (topic.exists(_ isUblogAuthor me))
+ if isGranted(_.ModerateForum) then MsgPreset.forumDeletion.byModerator
+ else if topic.exists(_ isUblogAuthor me) then
MsgPreset.forumDeletion.byBlogAuthor(me.username)
else MsgPreset.forumDeletion.byTeamLeader(categId)
do env.msg.api.systemPost(userId, preset(reason))
diff --git a/app/controllers/Game.scala b/app/controllers/Game.scala
index 317f582fbe1e3..dbd05ca1c10b5 100644
--- a/app/controllers/Game.scala
+++ b/app/controllers/Game.scala
@@ -35,7 +35,7 @@ final class Game(env: Env, apiC: => Api) extends LilaController(env):
case None => NotFound
case Some(game) =>
val config = GameApiV2.OneConfig(
- format = if (HTTPRequest acceptsJson req) GameApiV2.Format.JSON else GameApiV2.Format.PGN,
+ format = if HTTPRequest acceptsJson req then GameApiV2.Format.JSON else GameApiV2.Format.PGN,
imported = getBool("imported"),
flags = requestPgnFlags(extended = true),
playerFile = get("players")
@@ -72,7 +72,8 @@ final class Game(env: Env, apiC: => Api) extends LilaController(env):
color = get("color") flatMap chess.Color.fromName,
analysed = getBoolOpt("analysed"),
flags = requestPgnFlags(extended = false),
- sort = if (get("sort") has "dateAsc") GameApiV2.GameSort.DateAsc else GameApiV2.GameSort.DateDesc,
+ sort =
+ if get("sort") has "dateAsc" then GameApiV2.GameSort.DateAsc else GameApiV2.GameSort.DateDesc,
perSecond = MaxPerSecond(ctx.me match
case Some(m) if m is lila.user.User.explorerId => env.apiExplorerGamesPerSecond.get()
case Some(m) if m is user.id => 60
diff --git a/app/controllers/I18n.scala b/app/controllers/I18n.scala
index 104c4065a7012..cb86cd7f51421 100644
--- a/app/controllers/I18n.scala
+++ b/app/controllers/I18n.scala
@@ -31,7 +31,7 @@ final class I18n(env: Env) extends LilaController(env):
val pageUrl = new java.net.URI(str).parseServerAuthority().toURL()
val path = pageUrl.getPath
val query = pageUrl.getQuery
- if (query == null) path
+ if query == null then path
else path + "?" + query
catch case _: Exception => routes.Lobby.home.url
if ctx.isAnon
diff --git a/app/controllers/Main.scala b/app/controllers/Main.scala
index b3d1b11f09df2..ea44b710e8bc1 100644
--- a/app/controllers/Main.scala
+++ b/app/controllers/Main.scala
@@ -39,7 +39,7 @@ final class Main(
def captchaCheck(id: GameId) = Open:
import makeTimeout.long
env.hub.captcher.actor ? ValidCaptcha(id, ~get("solution")) map { case valid: Boolean =>
- Ok(if (valid) 1 else 0)
+ Ok(if valid then 1 else 0)
}
def webmasters = Open:
diff --git a/app/controllers/Mod.scala b/app/controllers/Mod.scala
index 51adf77537525..130fab5c9f100 100644
--- a/app/controllers/Mod.scala
+++ b/app/controllers/Mod.scala
@@ -185,7 +185,7 @@ final class Mod(
case _ if Granter(_.BoostHunter) => ModDomain.Boost
case _ => ModDomain.Admin
,
- room = if (report.isSpontaneous) "Spontaneous inquiry" else report.room.name
+ room = if report.isSpontaneous then "Spontaneous inquiry" else report.room.name
) inject NoContent
}
}
@@ -301,10 +301,10 @@ final class Mod(
.flashFailure(s"Currently processed by ${mod.name}")
case _ =>
val f =
- if (isAppeal) env.report.api.inquiries.appeal
+ if isAppeal then env.report.api.inquiries.appeal
else env.report.api.inquiries.spontaneous
f(Suspect(user)) inject {
- if (isAppeal) Redirect(s"${appeal.routes.Appeal.show(user.username)}#appeal-actions")
+ if isAppeal then Redirect(s"${appeal.routes.Appeal.show(user.username)}#appeal-actions")
else redirect(user.username, mod = true)
}
}
diff --git a/app/controllers/Opening.scala b/app/controllers/Opening.scala
index 075a1200646af..500b103b8d8c7 100644
--- a/app/controllers/Opening.scala
+++ b/app/controllers/Opening.scala
@@ -31,10 +31,9 @@ final class Opening(env: Env) extends LilaController(env):
case None => Redirect(routes.Opening.index(key.some))
case Some(page) =>
val query = page.query.query
- if (query.key.isEmpty) Redirect(routes.Opening.index(key.some))
- else if (query.key != key)
- Redirect(routes.Opening.byKeyAndMoves(query.key, moves))
- else if (moves.nonEmpty && page.query.pgnUnderscored != moves && !getBool("r"))
+ if query.key.isEmpty then Redirect(routes.Opening.index(key.some))
+ else if query.key != key then Redirect(routes.Opening.byKeyAndMoves(query.key, moves))
+ else if moves.nonEmpty && page.query.pgnUnderscored != moves && !getBool("r") then
Redirect:
s"${routes.Opening.byKeyAndMoves(query.key, page.query.pgnUnderscored)}?r=1"
else
diff --git a/app/controllers/Puzzle.scala b/app/controllers/Puzzle.scala
index 735e0377ec926..cc86abae739ea 100644
--- a/app/controllers/Puzzle.scala
+++ b/app/controllers/Puzzle.scala
@@ -163,7 +163,7 @@ final class Puzzle(env: Env, apiC: => Api) extends LilaController(env):
"voted" -> round.vote
)
else
- (data.replayDays, angle.asTheme) match {
+ (data.replayDays, angle.asTheme) match
case (Some(replayDays), Some(theme)) =>
for
_ <- env.puzzle.replay.onComplete(round, replayDays, angle)
@@ -187,12 +187,11 @@ final class Puzzle(env: Env, apiC: => Api) extends LilaController(env):
"round" -> env.puzzle.jsonView.roundJson.web(round, perf)(using me),
"next" -> nextJson
)
- }
yield json
}
case None =>
env.puzzle.finisher.incPuzzlePlays(id)
- if (mobileBc) fuccess(Json.obj("user" -> false))
+ if mobileBc then fuccess(Json.obj("user" -> false))
else
nextPuzzleForMe(angle, data.color map some)
.flatMap:
diff --git a/app/controllers/RelayRound.scala b/app/controllers/RelayRound.scala
index c005dc0b0309c..5d73506884862 100644
--- a/app/controllers/RelayRound.scala
+++ b/app/controllers/RelayRound.scala
@@ -95,11 +95,10 @@ final class RelayRound(
val sc =
if rt.round.sync.ongoing then
env.study.chapterRepo relaysAndTagsByStudyId rt.round.studyId flatMap { chapters =>
- chapters.find(_.looksAlive) orElse chapters.headOption match {
+ chapters.find(_.looksAlive) orElse chapters.headOption match
case Some(chapter) =>
env.study.api.byIdWithChapterOrFallback(rt.round.studyId, chapter.id)
case None => env.study.api byIdWithChapter rt.round.studyId
- }
}
else env.study.api byIdWithChapter rt.round.studyId
sc orNotFound { doShow(rt, _) }
diff --git a/app/controllers/Report.scala b/app/controllers/Report.scala
index d05bc1567913e..2970478573ca8 100644
--- a/app/controllers/Report.scala
+++ b/app/controllers/Report.scala
@@ -60,8 +60,8 @@ final class Report(
}
private def onInquiryStart(inquiry: ReportModel): Result =
- if (inquiry.isRecentComm) Redirect(controllers.routes.Mod.communicationPrivate(inquiry.user))
- else if (inquiry.isComm) Redirect(controllers.routes.Mod.communicationPublic(inquiry.user))
+ if inquiry.isRecentComm then Redirect(controllers.routes.Mod.communicationPrivate(inquiry.user))
+ else if inquiry.isComm then Redirect(controllers.routes.Mod.communicationPublic(inquiry.user))
else modC.redirect(inquiry.user)
protected[controllers] def onModAction(goTo: Suspect)(using ctx: BodyContext[?], me: Me): Fu[Result] =
@@ -131,7 +131,7 @@ final class Report(
def form = Auth { _ ?=> _ ?=>
getUserStr("username") so env.user.repo.byId flatMap { user =>
- if (user.map(_.id) has UserModel.lichessId) Redirect(controllers.routes.Main.contact)
+ if user.map(_.id) has UserModel.lichessId then Redirect(controllers.routes.Main.contact)
else
Ok.pageAsync:
val form = env.report.forms.create
diff --git a/app/controllers/Round.scala b/app/controllers/Round.scala
index c98a94b7d3657..482d5c0970e0c 100644
--- a/app/controllers/Round.scala
+++ b/app/controllers/Round.scala
@@ -138,7 +138,7 @@ final class Round(
playablePovForReq(pov.game) match
case Some(player) if userTv.isEmpty => renderPlayer(pov withColor player.color)
case _ if pov.game.variant == chess.variant.RacingKings && pov.color.black =>
- if (userTv.isDefined) watch(!pov, userTv)
+ if userTv.isDefined then watch(!pov, userTv)
else Redirect(routes.Round.watcher(pov.gameId, "white"))
case _ =>
negotiateApi(
diff --git a/app/controllers/Simul.scala b/app/controllers/Simul.scala
index fdbf988b5677d..6ab0ae5914a01 100644
--- a/app/controllers/Simul.scala
+++ b/app/controllers/Simul.scala
@@ -143,7 +143,7 @@ final class Simul(env: Env) extends LilaController(env):
def withdraw(id: SimulId) = Auth { ctx ?=> me ?=>
env.simul.api.removeApplicant(id, me) inject {
- if (HTTPRequest isXhr ctx.req) jsonOkResult
+ if HTTPRequest isXhr ctx.req then jsonOkResult
else Redirect(routes.Simul.show(id))
}
}
diff --git a/app/controllers/Storm.scala b/app/controllers/Storm.scala
index 8d4ab1a330549..902f98896fbe8 100644
--- a/app/controllers/Storm.scala
+++ b/app/controllers/Storm.scala
@@ -49,7 +49,7 @@ final class Storm(env: Env) extends LilaController(env):
def apiDashboardOf(username: UserStr, days: Int) = Open:
lila.user.User.validateId(username).so { userId =>
- if (days < 0 || days > 365) notFoundJson("Invalid days parameter")
+ if days < 0 || days > 365 then notFoundJson("Invalid days parameter")
else
((days > 0) so env.storm.dayApi.apiHistory(userId, days)) zip env.storm.highApi.get(userId) map {
case (history, high) => Ok(env.storm.json.apiDashboard(high, history))
diff --git a/app/controllers/Streamer.scala b/app/controllers/Streamer.scala
index 1070d29b14d1b..70e3d33903934 100644
--- a/app/controllers/Streamer.scala
+++ b/app/controllers/Streamer.scala
@@ -105,7 +105,7 @@ final class Streamer(env: Env, apiC: => Api) extends LilaController(env):
BadRequest.page(html.streamer.edit(sws, error, forMod)),
data =>
api.update(sws.streamer, data, isGranted(_.Streamers)) flatMap { change =>
- if (change.decline) logApi.streamerDecline(s.user.id)
+ if change.decline then logApi.streamerDecline(s.user.id)
change.list foreach { logApi.streamerList(s.user.id, _) }
change.tier foreach { logApi.streamerTier(s.user.id, _) }
if data.approval.flatMap(_.quick).isDefined
@@ -115,7 +115,7 @@ final class Streamer(env: Env, apiC: => Api) extends LilaController(env):
nextId.fold(s"${routes.Streamer.index()}?requests=1"): id =>
s"${routes.Streamer.edit.url}?u=$id"
else
- val next = if (sws.streamer is me) "" else s"?u=${sws.user.id}"
+ val next = if sws.streamer is me then "" else s"?u=${sws.user.id}"
Redirect(s"${routes.Streamer.edit.url}$next")
}
)
diff --git a/app/controllers/Study.scala b/app/controllers/Study.scala
index cf1ecd8732d02..cb5c02bb31112 100644
--- a/app/controllers/Study.scala
+++ b/app/controllers/Study.scala
@@ -393,7 +393,7 @@ final class Study(
)
def cloneApply(id: StudyId) = Auth { ctx ?=> me ?=>
- val cost = if (isGranted(_.Coach) || me.hasTitle) 1 else 3
+ val cost = if isGranted(_.Coach) || me.hasTitle then 1 else 3
CloneLimitPerUser(me, rateLimited, cost = cost):
CloneLimitPerIP(ctx.ip, rateLimited, cost = cost):
Found(env.study.api.byId(id)) { prev =>
@@ -483,7 +483,7 @@ final class Study(
akka.stream.ActorAttributes.supervisionStrategy(akka.stream.Supervision.resumingDecider)
apiC.GlobalConcurrencyLimitPerIpAndUserOption(userId.some)(makeStream): source =>
Ok.chunked(source)
- .pipe(asAttachmentStream(s"${name}-${if (isMe) "all" else "public"}-studies.pgn"))
+ .pipe(asAttachmentStream(s"${name}-${if isMe then "all" else "public"}-studies.pgn"))
.as(pgnContentType)
def apiListByOwner(username: UserStr) = OpenOrScoped(_.Study.Read): ctx ?=>
diff --git a/app/controllers/TheftPrevention.scala b/app/controllers/TheftPrevention.scala
index 3a9dd51f2fcf4..88a74a1d84a3a 100644
--- a/app/controllers/TheftPrevention.scala
+++ b/app/controllers/TheftPrevention.scala
@@ -4,7 +4,8 @@ import lila.app.{ given, * }
import lila.game.{ AnonCookie, Game as GameModel, Pov }
import play.api.mvc.*
-private[controllers] trait TheftPrevention { self: LilaController =>
+private[controllers] trait TheftPrevention:
+ self: LilaController =>
protected def PreventTheft(pov: Pov)(ok: => Fu[Result])(using Context): Fu[Result] =
if isTheft(pov) then Redirect(routes.Round.watcher(pov.gameId, pov.color.name))
@@ -38,4 +39,3 @@ private[controllers] trait TheftPrevention { self: LilaController =>
protected lazy val theftResponse = Unauthorized(
jsonError("This game requires authentication")
) as JSON
-}
diff --git a/app/controllers/Tournament.scala b/app/controllers/Tournament.scala
index fb0400fea6711..c6fd3b4713c42 100644
--- a/app/controllers/Tournament.scala
+++ b/app/controllers/Tournament.scala
@@ -25,10 +25,10 @@ final class Tournament(env: Env, apiC: => Api)(using akka.stream.Materializer) e
private[controllers] val upcomingCache = env.memo.cacheApi.unit[(VisibleTournaments, List[Tour])] {
_.refreshAfterWrite(3.seconds)
.buildAsyncFuture { _ =>
- for {
+ for
visible <- api.fetchVisibleTournaments
scheduled <- repo.allScheduledDedup
- } yield (visible, scheduled)
+ yield (visible, scheduled)
}
}
diff --git a/app/controllers/TournamentCrud.scala b/app/controllers/TournamentCrud.scala
index dc12bc99c2cd4..27973c21dfaa4 100644
--- a/app/controllers/TournamentCrud.scala
+++ b/app/controllers/TournamentCrud.scala
@@ -42,7 +42,7 @@ final class TournamentCrud(env: Env) extends LilaController(env):
data =>
crud.create(data, me.value) map { tour =>
Redirect {
- if (tour.isTeamBattle) routes.Tournament.teamBattleEdit(tour.id)
+ if tour.isTeamBattle then routes.Tournament.teamBattleEdit(tour.id)
else routes.TournamentCrud.edit(tour.id)
}.flashSuccess
}
diff --git a/app/controllers/Tv.scala b/app/controllers/Tv.scala
index cdd9f5cde5fe9..ab3c087cd8706 100644
--- a/app/controllers/Tv.scala
+++ b/app/controllers/Tv.scala
@@ -39,7 +39,7 @@ final class Tv(env: Env, apiC: => Api, gameC: => Game) extends LilaController(en
Found(env.tv.tv getGameAndHistory channel): (game, history) =>
val flip = getBool("flip")
val natural = Pov naturalOrientation game
- val pov = if (flip) !natural else natural
+ val pov = if flip then !natural else natural
val onTv = lila.round.OnTv.Lichess(channel.key, flip)
negotiateApi(
html = for
diff --git a/app/controllers/Ublog.scala b/app/controllers/Ublog.scala
index 29717a565155b..e3bc2863f2849 100644
--- a/app/controllers/Ublog.scala
+++ b/app/controllers/Ublog.scala
@@ -222,7 +222,7 @@ final class Ublog(env: Env) extends LilaController(env):
case ByHref.Redir(code) => Redirect(routes.Ublog.communityLang(code, page))
case ByHref.Refused(lang) => communityIndex(lang.some, page)
case ByHref.Found(lang) =>
- if (ctx.isAuth) communityIndex(lang.some, page)
+ if ctx.isAuth then communityIndex(lang.some, page)
else communityIndex(lang.some, page)(using ctx.withLang(lang))
def communityAll(page: Int) = Open:
diff --git a/app/http/ContentSecurityPolicy.scala b/app/http/ContentSecurityPolicy.scala
index 75b888bcf8768..85dfb27f1fd48 100644
--- a/app/http/ContentSecurityPolicy.scala
+++ b/app/http/ContentSecurityPolicy.scala
@@ -71,7 +71,7 @@ case class ContentSecurityPolicy(
def withPeer = copy(connectSrc = "wss://0.peerjs.com" :: connectSrc)
private def withPrismicEditor(maybe: Boolean): ContentSecurityPolicy =
- if (maybe)
+ if maybe then
copy(
scriptSrc = "https://static.cdn.prismic.io" :: scriptSrc,
frameSrc = "https://lichess.prismic.io" :: "https://lichess.cdn.prismic.io" :: frameSrc,
diff --git a/app/http/HttpFilter.scala b/app/http/HttpFilter.scala
index f47312387a4d0..4dd2e96fe22de 100644
--- a/app/http/HttpFilter.scala
+++ b/app/http/HttpFilter.scala
@@ -44,7 +44,7 @@ final class HttpFilter(env: Env)(using val mat: Materializer)(using Executor)
!HTTPRequest.isProgrammatic(req) &&
// asset request going through the CDN, don't redirect
!(req.host == env.net.assetDomain.value && HTTPRequest.hasFileExtension(req))
- } option Results.MovedPermanently(s"http${if (req.secure) "s" else ""}://${env.net.domain}${req.uri}")
+ } option Results.MovedPermanently(s"http${if req.secure then "s" else ""}://${env.net.domain}${req.uri}")
private def addApiResponseHeaders(req: RequestHeader)(result: Result) =
if HTTPRequest.isApiOrApp(req)
diff --git a/app/http/PageCache.scala b/app/http/PageCache.scala
index a023cbd76f811..f1a2b066a94ed 100644
--- a/app/http/PageCache.scala
+++ b/app/http/PageCache.scala
@@ -12,10 +12,9 @@ final class PageCache(cacheApi: lila.memo.CacheApi):
}
def apply(compute: () => Fu[Result])(using ctx: Context): Fu[Result] =
- if (ctx.isAnon && langs(ctx.lang.language) && defaultPrefs(ctx.req) && !hasCookies(ctx.req))
+ if ctx.isAnon && langs(ctx.lang.language) && defaultPrefs(ctx.req) && !hasCookies(ctx.req) then
cache.getFuture(cacheKey(ctx), _ => compute())
- else
- compute()
+ else compute()
private def cacheKey(ctx: Context) =
s"${HTTPRequest actionName ctx.req}(${ctx.lang.language})"
diff --git a/app/mashup/TeamInfo.scala b/app/mashup/TeamInfo.scala
index f989be2f899b8..7d122d4bfbf4f 100644
--- a/app/mashup/TeamInfo.scala
+++ b/app/mashup/TeamInfo.scala
@@ -65,7 +65,7 @@ final class TeamInfoApi(
}
def apply(team: Team, me: Option[User], withForum: Boolean => Boolean): Fu[TeamInfo] =
- for {
+ for
requests <- (team.enabled && me.exists(m => team.leaders(m.id))) so api.requestsWithUsers(team)
mine <- me.so(m => api.belongsTo(team.id, m.id))
myRequest <- !mine so me.so(m => requestRepo.find(team.id, m.id))
@@ -73,7 +73,7 @@ final class TeamInfoApi(
forumPosts <- withForum(mine) soFu forumRecent(team.id)
tours <- tournaments(team, 5, 5)
simuls <- simulApi.byTeamLeaders(team.id, team.leaders.toSeq)
- } yield TeamInfo(
+ yield TeamInfo(
mine = mine,
ledByMe = me.exists(m => team.leaders(m.id)),
myRequest = myRequest,
diff --git a/app/router.scala b/app/router.scala
index d3b509d18227e..73a0fa99551f8 100644
--- a/app/router.scala
+++ b/app/router.scala
@@ -1,6 +1,6 @@
package router
-import lila.app._
+import lila.app.*
import lila.rating.Perf
import lila.puzzle.PuzzleTheme
import lila.report.Report
diff --git a/app/templating/AiHelper.scala b/app/templating/AiHelper.scala
index 421596135962a..ad5dfc54a5fcd 100644
--- a/app/templating/AiHelper.scala
+++ b/app/templating/AiHelper.scala
@@ -5,11 +5,11 @@ import play.api.i18n.Lang
import lila.app.ui.ScalatagsTemplate.*
-trait AiHelper { self: I18nHelper =>
+trait AiHelper:
+ self: I18nHelper =>
def aiName(level: Int)(using Lang): String =
trans.aiNameLevelAiLevel.txt("Stockfish", level)
def aiNameFrag(level: Int)(using Lang) =
raw(aiName(level).replace(" ", " "))
-}
diff --git a/app/templating/AssetHelper.scala b/app/templating/AssetHelper.scala
index ecba8740f618b..4e6d7cbfc86c8 100644
--- a/app/templating/AssetHelper.scala
+++ b/app/templating/AssetHelper.scala
@@ -8,7 +8,8 @@ import lila.app.ui.ScalatagsTemplate.*
import lila.common.AssetVersion
import lila.common.String.html.safeJsonValue
-trait AssetHelper extends HasEnv { self: I18nHelper with SecurityHelper =>
+trait AssetHelper extends HasEnv:
+ self: I18nHelper with SecurityHelper =>
private lazy val netDomain = env.net.domain
private lazy val assetDomain = env.net.assetDomain
@@ -32,7 +33,7 @@ trait AssetHelper extends HasEnv { self: I18nHelper with SecurityHelper =>
cssTagWithDirAndTheme(name, isRTL, ctx.pref.currentBg)
def cssTagWithDirAndTheme(name: String, isRTL: Boolean, theme: String): Frag =
- if (theme == "system")
+ if theme == "system" then
frag(
cssTagWithDirAndSimpleTheme(name, isRTL, "light")(media := "(prefers-color-scheme: light)"),
cssTagWithDirAndSimpleTheme(name, isRTL, "dark")(media := "(prefers-color-scheme: dark)")
@@ -40,10 +41,12 @@ trait AssetHelper extends HasEnv { self: I18nHelper with SecurityHelper =>
else cssTagWithDirAndSimpleTheme(name, isRTL, theme)
private def cssTagWithDirAndSimpleTheme(name: String, isRTL: Boolean, theme: String): Tag =
- cssAt(s"css/$name.${if (isRTL) "rtl" else "ltr"}.$theme.${if (minifiedAssets) "min" else "dev"}.css")
+ cssAt(
+ s"css/$name.${if isRTL then "rtl" else "ltr"}.$theme.${if minifiedAssets then "min" else "dev"}.css"
+ )
def cssTagNoTheme(name: String): Frag =
- cssAt(s"css/$name.${if (minifiedAssets) "min" else "dev"}.css")
+ cssAt(s"css/$name.${if minifiedAssets then "min" else "dev"}.css")
private def cssAt(path: String): Tag =
link(href := assetUrl(path), rel := "stylesheet")
@@ -128,4 +131,3 @@ if (window.matchMedia('(prefers-color-scheme: dark)').media === 'not all')
def embedJsUnsafeLoadThen(js: String, nonce: lila.api.Nonce): Frag =
embedJsUnsafe(s"""lichess.load.then(()=>{$js})""", nonce)
-}
diff --git a/app/templating/ChessgroundHelper.scala b/app/templating/ChessgroundHelper.scala
index 67a5828f5b53b..2f5adbde39deb 100644
--- a/app/templating/ChessgroundHelper.scala
+++ b/app/templating/ChessgroundHelper.scala
@@ -17,7 +17,7 @@ trait ChessgroundHelper:
wrap {
cgBoard {
raw {
- if (ctx.pref.is3d) ""
+ if ctx.pref.is3d then ""
else
def top(p: Square) = orient.fold(7 - p.rank.index, p.rank.index) * 12.5
def left(p: Square) = orient.fold(p.file.index, 7 - p.file.index) * 12.5
@@ -25,7 +25,7 @@ trait ChessgroundHelper:
s"""
Beginners may be best served by playing conventional e4/d4 systems as white and the French as black. Avoid pawn moves which weaken key squares; fortify weak squares around your king. Maintain the initiative and attack. Sac when it draws the king out and you have a follow-up. Emphasize king safety over material gain. Calculate what your opponent (and you) can do with exchanged pieces before entering into tactical complications. Go crazy!
""" } -} diff --git a/modules/blog/src/test/YoutubeTest.scala b/modules/blog/src/test/YoutubeTest.scala index df3b69089484f..5fd2b1275bf20 100644 --- a/modules/blog/src/test/YoutubeTest.scala +++ b/modules/blog/src/test/YoutubeTest.scala @@ -1,6 +1,6 @@ package lila.blog -class YoutubeTest extends munit.FunSuite { +class YoutubeTest extends munit.FunSuite: test("no youtube embed") { assertEquals(Youtube.fixStartTimes(Fixtures.noYoutube), Fixtures.noYoutube) @@ -18,4 +18,3 @@ class YoutubeTest extends munit.FunSuite { ) ) } -} diff --git a/modules/bookmark/src/main/Env.scala b/modules/bookmark/src/main/Env.scala index d2cd71feb8bd9..cba6805dad3fd 100644 --- a/modules/bookmark/src/main/Env.scala +++ b/modules/bookmark/src/main/Env.scala @@ -31,11 +31,12 @@ final class Env( lazy val api = wire[BookmarkApi] system.actorOf( - Props(new Actor { - def receive = { - case Toggle(gameId, userId) => api.toggle(gameId, userId).unit - case Remove(gameId) => api.removeByGameId(gameId).unit - } - }), + Props( + new Actor: + def receive = { + case Toggle(gameId, userId) => api.toggle(gameId, userId).unit + case Remove(gameId) => api.removeByGameId(gameId).unit + } + ), name = config.actorName ) diff --git a/modules/bot/src/main/BotJsonView.scala b/modules/bot/src/main/BotJsonView.scala index 53823364d9233..d8360af1e1b91 100644 --- a/modules/bot/src/main/BotJsonView.scala +++ b/modules/bot/src/main/BotJsonView.scala @@ -65,7 +65,7 @@ final class BotJsonView( def chatLine(username: UserName, text: String, player: Boolean) = Json.obj( "type" -> "chatLine", - "room" -> (if (player) "player" else "spectator"), + "room" -> (if player then "player" else "spectator"), "username" -> username, "text" -> text ) diff --git a/modules/bot/src/main/BotPlayer.scala b/modules/bot/src/main/BotPlayer.scala index 3741ea9cd192e..e8f423764273f 100644 --- a/modules/bot/src/main/BotPlayer.scala +++ b/modules/bot/src/main/BotPlayer.scala @@ -25,8 +25,8 @@ final class BotPlayer( if !pov.isMyTurn then clientError("Not your turn, or game already over") else val promise = Promise[Unit]() - if (pov.player.isOfferingDraw && offeringDraw.has(false)) declineDraw(pov) - else if (!pov.player.isOfferingDraw && ~offeringDraw) offerDraw(pov) + if pov.player.isOfferingDraw && offeringDraw.has(false) then declineDraw(pov) + else if !pov.player.isOfferingDraw && ~offeringDraw then offerDraw(pov) tellRound(pov.gameId, BotPlay(pov.playerId, uci, promise.some)) promise.future.recover: case _: lila.round.GameIsFinishedError if ~offeringDraw => () @@ -35,7 +35,7 @@ final class BotPlayer( !spam.detect(d.text) so fuccess: lila.mon.bot.chats(me.username.value).increment() - val chatId = ChatId(if (d.room == "player") gameId.value else s"$gameId/w") + val chatId = ChatId(if d.room == "player" then gameId.value else s"$gameId/w") val source = d.room == "spectator" option { lila.hub.actorApi.shutup.PublicSource.Watcher(gameId) } @@ -49,9 +49,9 @@ final class BotPlayer( rematches.prevGameIdOffering(challengeId) so gameRepo.game map { _.flatMap(Pov(_, me)) so { pov => // delay so it feels more natural - lila.common.LilaFuture.delay(if (accept) 100.millis else 1.second) { + lila.common.LilaFuture.delay(if accept then 100.millis else 1.second) { fuccess { - tellRound(pov.gameId, if (accept) RematchYes(pov.playerId) else RematchNo(pov.playerId)) + tellRound(pov.gameId, if accept then RematchYes(pov.playerId) else RematchNo(pov.playerId)) } } true @@ -62,34 +62,35 @@ final class BotPlayer( Bus.publish(Tell(id.value, msg), "roundSocket") def abort(pov: Pov): Funit = - if (!pov.game.abortableByUser) clientError("This game can no longer be aborted") + if !pov.game.abortableByUser then clientError("This game can no longer be aborted") else fuccess { tellRound(pov.gameId, Abort(pov.playerId)) } def resign(pov: Pov): Funit = - if (pov.game.abortableByUser) fuccess { - tellRound(pov.gameId, Abort(pov.playerId)) - } - else if (pov.game.resignable) fuccess { - tellRound(pov.gameId, Resign(pov.playerId)) - } + if pov.game.abortableByUser then + fuccess { + tellRound(pov.gameId, Abort(pov.playerId)) + } + else if pov.game.resignable then + fuccess { + tellRound(pov.gameId, Resign(pov.playerId)) + } else clientError("This game cannot be resigned") private def declineDraw(pov: Pov): Unit = - if (pov.game.drawable && pov.opponent.isOfferingDraw) - tellRound(pov.gameId, DrawNo(pov.playerId)) + if pov.game.drawable && pov.opponent.isOfferingDraw then tellRound(pov.gameId, DrawNo(pov.playerId)) private def offerDraw(pov: Pov): Unit = - if (pov.game.drawable && (pov.game.playerCanOfferDraw(pov.color) || pov.opponent.isOfferingDraw)) + if pov.game.drawable && (pov.game.playerCanOfferDraw(pov.color) || pov.opponent.isOfferingDraw) then tellRound(pov.gameId, DrawYes(pov.playerId)) def setDraw(pov: Pov, v: Boolean): Unit = - if (v) offerDraw(pov) else declineDraw(pov) + if v then offerDraw(pov) else declineDraw(pov) def setTakeback(pov: Pov, v: Boolean): Unit = - if (pov.game.playable && pov.game.canTakebackOrAddTime) + if pov.game.playable && pov.game.canTakebackOrAddTime then tellRound(pov.gameId, if v then TakebackYes(pov.playerId) else TakebackNo(pov.playerId)) def claimVictory(pov: Pov): Funit = diff --git a/modules/bot/src/main/GameStateStream.scala b/modules/bot/src/main/GameStateStream.scala index 6c92c91431b35..7c9838755220b 100644 --- a/modules/bot/src/main/GameStateStream.scala +++ b/modules/bot/src/main/GameStateStream.scala @@ -87,7 +87,7 @@ final class GameStateStream( // prepend the full game JSON at the start of the stream queue offer json.some // close stream if game is over - if (init.game.finished) onGameOver(none) + if init.game.finished then onGameOver(none) else self ! SetOnline } lila.mon.bot.gameStream("start").increment() @@ -98,7 +98,7 @@ final class GameStateStream( Bus.unsubscribe(self, classifiers) // hang around if game is over // so the opponent has a chance to rematch - context.system.scheduler.scheduleOnce(if (gameOver) 10 second else 1 second): + context.system.scheduler.scheduleOnce(if gameOver then 10 second else 1 second): Bus.publish(Tell(init.game.id.value, BotConnected(as, v = false)), "roundSocket") queue.complete() lila.mon.bot.gameStream("stop").increment().unit diff --git a/modules/bot/src/main/OnlineApiUsers.scala b/modules/bot/src/main/OnlineApiUsers.scala index 7362cc2cddd50..b3f3d93e6830a 100644 --- a/modules/bot/src/main/OnlineApiUsers.scala +++ b/modules/bot/src/main/OnlineApiUsers.scala @@ -19,7 +19,7 @@ final class OnlineApiUsers( def setOnline(userId: UserId): Unit = val wasOffline = !isOnline(userId) && !cache.get(userId) cache.put(userId) - if (wasOffline) publish(userId, isOnline = true) + if wasOffline then publish(userId, isOnline = true) def get: Set[UserId] = cache.keySet diff --git a/modules/challenge/src/main/BSONHandlers.scala b/modules/challenge/src/main/BSONHandlers.scala index 45c5df80a4486..c9c3f1c32490f 100644 --- a/modules/challenge/src/main/BSONHandlers.scala +++ b/modules/challenge/src/main/BSONHandlers.scala @@ -63,8 +63,8 @@ private object BSONHandlers: given BSON[Challenger] with def reads(r: Reader) = - if (r contains "id") registeredHandler reads r - else if (r contains "s") anonHandler reads r + if r contains "id" then registeredHandler reads r + else if r contains "s" then anonHandler reads r else Challenger.Open def writes(w: Writer, c: Challenger) = c match diff --git a/modules/challenge/src/main/ChallengeApi.scala b/modules/challenge/src/main/ChallengeApi.scala index 02f2c002a6ea6..175b53d410d32 100644 --- a/modules/challenge/src/main/ChallengeApi.scala +++ b/modules/challenge/src/main/ChallengeApi.scala @@ -84,7 +84,7 @@ final class ChallengeApi( def createdByChallengerId = repo.createdByChallengerId() def createdByDestId(userId: UserId, max: Int = 50) = countInFor get userId flatMap { nb => - if (nb > 5) repo.createdByPopularDestId(max)(userId) + if nb > 5 then repo.createdByPopularDestId(max)(userId) else repo.createdByDestId()(userId) } @@ -213,4 +213,4 @@ final class ChallengeApi( // work around circular dependency private var socket: Option[ChallengeSocket] = None - private[challenge] def registerSocket(s: ChallengeSocket) = { socket = s.some } + private[challenge] def registerSocket(s: ChallengeSocket) = socket = s.some diff --git a/modules/challenge/src/main/ChallengeJoiner.scala b/modules/challenge/src/main/ChallengeJoiner.scala index 7ac69e4794b55..e40ec4edd8612 100644 --- a/modules/challenge/src/main/ChallengeJoiner.scala +++ b/modules/challenge/src/main/ChallengeJoiner.scala @@ -40,7 +40,7 @@ private object ChallengeJoiner: chess = chessGame, whitePlayer = Player.make(chess.White, c.finalColor.fold(origUser, destUser).map(_ only c.perfType)), blackPlayer = Player.make(chess.Black, c.finalColor.fold(destUser, origUser).map(_ only c.perfType)), - mode = if (chessGame.board.variant.fromPosition) Mode.Casual else c.mode, + mode = if chessGame.board.variant.fromPosition then Mode.Casual else c.mode, source = Source.Friend, daysPerTurn = c.daysPerTurn, pgnImport = None, @@ -70,9 +70,8 @@ private object ChallengeJoiner: startedAtPly = sp.ply, clock = tc.realTime.map(_.toClock) ) - if (variant.fromPosition && Fen.write(game).isInitial) - makeChess(chess.variant.Standard) -> none - else game -> baseState + if variant.fromPosition && Fen.write(game).isInitial then makeChess(chess.variant.Standard) -> none + else game -> baseState def addGameHistory(position: Option[Situation.AndFullMoveNumber])(game: Game): Game = position.fold(game): sp => diff --git a/modules/challenge/src/main/ChallengeRepo.scala b/modules/challenge/src/main/ChallengeRepo.scala index cf10a12810298..c5eda616a6bd3 100644 --- a/modules/challenge/src/main/ChallengeRepo.scala +++ b/modules/challenge/src/main/ChallengeRepo.scala @@ -38,13 +38,13 @@ final private class ChallengeRepo(colls: ChallengeColls)(using def createdByDestId(max: Int = 50)(userId: UserId): Fu[List[Challenge]] = createdList($doc("destUser.id" -> userId), max) - def createdByPopularDestId(max: Int = 50)(userId: UserId): Fu[List[Challenge]] = for { + def createdByPopularDestId(max: Int = 50)(userId: UserId): Fu[List[Challenge]] = for realTime <- createdList($doc("destUser.id" -> userId, "timeControl.l" $exists true), max) corres <- (realTime.sizeIs < max) so createdList( $doc($doc("destUser.id" -> userId), "timeControl.l" $exists false), max - realTime.size ) - } yield realTime ::: corres + yield realTime ::: corres def setChallenger(c: Challenge, color: Option[chess.Color]) = coll.update diff --git a/modules/challenge/src/test/JoinerTest.scala b/modules/challenge/src/test/JoinerTest.scala index c6fa872b6dc8e..647940c59fec7 100644 --- a/modules/challenge/src/test/JoinerTest.scala +++ b/modules/challenge/src/test/JoinerTest.scala @@ -6,7 +6,7 @@ import chess.variant.{ FromPosition, Standard } import lila.game.Game import chess.Clock -final class JoinerTest extends munit.FunSuite { +final class JoinerTest extends munit.FunSuite: val timeControl = Challenge.TimeControl.Clock(Clock.Config(Clock.LimitSeconds(300), Clock.IncrementSeconds(0))) @@ -38,4 +38,3 @@ final class JoinerTest extends munit.FunSuite { ) assertEquals(ChallengeJoiner.createGame(challenge, None, None).chess.startedAtPly, Ply(6)) } -} diff --git a/modules/chat/src/main/ChatApi.scala b/modules/chat/src/main/ChatApi.scala index 6d6996ecbcd41..71004e406f7aa 100644 --- a/modules/chat/src/main/ChatApi.scala +++ b/modules/chat/src/main/ChatApi.scala @@ -134,7 +134,7 @@ final class ChatApi( publish(chatId, ChatLine(chatId, line), busChan) def service(chatId: ChatId, text: String, busChan: BusChan.Select, isVolatile: Boolean): Unit = - (if (isVolatile) volatile else system) (chatId, text, busChan).unit + (if isVolatile then volatile else system) (chatId, text, busChan).unit def timeout( chatId: ChatId, @@ -160,12 +160,11 @@ final class ChatApi( reason = reason, scope = ChatTimeout.Scope.Global, text = data.text, - busChan = data.chan match { + busChan = data.chan match case "tournament" => _.Tournament case "swiss" => _.Swiss case "team" => _.Team case _ => _.Study - } ) } @@ -203,7 +202,7 @@ final class ChatApi( line foreach { l => publish(chat.id, ChatLine(chat.id, l), busChan) } - if (isMod(mod) || isRelayMod(mod)) + if isMod(mod) || isRelayMod(mod) then lila.common.Bus.publish( lila.hub.actorApi.mod.ChatTimeout( mod = mod.userId, @@ -213,7 +212,7 @@ final class ChatApi( ), "chatTimeout" ) - if (isNew) + if isNew then lila.common.Bus .publish(lila.hub.actorApi.security.DeletePublicChats(user.id), "deletePublicChats") else logger.info(s"${mod.username} times out ${user.username} in #${c.id} for ${reason.key}") @@ -265,7 +264,7 @@ final class ChatApi( findOption(chatId) dmap (_ | Chat.makeMixed(chatId)) def findIf(chatId: ChatId, cond: Boolean): Fu[MixedChat] = - if (cond) find(chatId) + if cond then find(chatId) else fuccess(Chat.makeMixed(chatId)) def findNonEmpty(chatId: ChatId): Fu[Option[MixedChat]] = @@ -323,7 +322,7 @@ final class ChatApi( out2.take(Line.textMaxSize).some.filter(_.nonEmpty) private def removeSelfMention(in: String, username: UserName) = - if (in.contains('@')) + if in.contains('@') then ("""(?i)@(? Fu[Option[User]]): Fu[Boolean] = - if (enabled) fetch(id) dmap { _ so allowed } + if enabled then fetch(id) dmap { _ so allowed } else fuTrue def enabled = @@ -33,4 +33,4 @@ final class ChatPanic: logger.warn("Chat Panic disabled") until = none - def set(v: Boolean) = if (v) start() else stop() + def set(v: Boolean) = if v then start() else stop() diff --git a/modules/chat/src/main/ChatTimeout.scala b/modules/chat/src/main/ChatTimeout.scala index a6c3a26391844..dc7ecb8ef2486 100644 --- a/modules/chat/src/main/ChatTimeout.scala +++ b/modules/chat/src/main/ChatTimeout.scala @@ -21,7 +21,7 @@ final class ChatTimeout( isActive(chat.id, user.id) flatMap { if _ then fuccess(false) else - if (scope == Scope.Global) global put user.id + if scope == Scope.Global then global put user.id coll.insert .one( $doc( diff --git a/modules/chat/src/main/Line.scala b/modules/chat/src/main/Line.scala index 82312df6916d8..39a26312f24c2 100644 --- a/modules/chat/src/main/Line.scala +++ b/modules/chat/src/main/Line.scala @@ -78,9 +78,9 @@ object Line: case _ => none def userLineToStr(x: UserLine): String = val sep = - if (x.troll) trollChar - else if (x.deleted) deletedChar - else if (x.patron) patronChar + if x.troll then trollChar + else if x.deleted then deletedChar + else if x.patron then patronChar else " " val tit = x.title.so(_.value + titleSep) s"$tit${x.username}$sep${x.text}" diff --git a/modules/clas/src/main/ClasApi.scala b/modules/clas/src/main/ClasApi.scala index 3f1222ee03679..70efc9493f2cd 100644 --- a/modules/clas/src/main/ClasApi.scala +++ b/modules/clas/src/main/ClasApi.scala @@ -115,7 +115,7 @@ final class ClasApi( coll.update .one( $id(c.id), - if (v) $set("archived" -> Clas.Recorded(t.id, nowInstant)) + if v then $set("archived" -> Clas.Recorded(t.id, nowInstant)) else $unset("archived") ) .void @@ -367,7 +367,7 @@ ${clas.desc}""", invite: ClasInvite ): Fu[ClasInvite.Feedback] = val url = s"$baseUrl/class/invitation/${invite._id}" - if (student.kid) fuccess(ClasInvite.Feedback.CantMsgKid(url)) + if student.kid then fuccess(ClasInvite.Feedback.CantMsgKid(url)) else import lila.i18n.I18nKeys.clas.* given play.api.i18n.Lang = student.realLang | lila.i18n.defaultLang diff --git a/modules/clas/src/main/ClasForm.scala b/modules/clas/src/main/ClasForm.scala index b242ee93af4e9..017a1d1bd6c46 100644 --- a/modules/clas/src/main/ClasForm.scala +++ b/modules/clas/src/main/ClasForm.scala @@ -21,12 +21,11 @@ final class ClasForm( "desc" -> cleanText(minLength = 0, maxLength = 2000), "teachers" -> nonEmptyText.verifying( "Invalid teacher list", - str => { + str => val ids = readTeacherIds(str) ids.nonEmpty && ids.sizeIs <= 10 && ids.forall { id => blockingFetchUser(id into UserStr).isDefined } - } ) )(ClasData.apply)(unapply) ) diff --git a/modules/clas/src/main/ClasProgress.scala b/modules/clas/src/main/ClasProgress.scala index ba74b5c820165..2a73dea01355f 100644 --- a/modules/clas/src/main/ClasProgress.scala +++ b/modules/clas/src/main/ClasProgress.scala @@ -35,7 +35,7 @@ case class StudentProgress( rating: (IntRating, IntRating) ): def ratingProgress = (rating._2 - rating._1) into IntRatingDiff - def winRate = if (nb > 0) wins * 100 / nb else 0 + def winRate = if nb > 0 then wins * 100 / nb else 0 def duration = Duration.ofMillis(millis) final class ClasProgressApi( @@ -156,4 +156,4 @@ final class ClasProgressApi( .toMap private[clas] def onFinishGame(game: lila.game.Game): Unit = - if (game.userIds.exists(studentCache.isStudent)) gameRepo.denormalizePerfType(game) + if game.userIds.exists(studentCache.isStudent) then gameRepo.denormalizePerfType(game) diff --git a/modules/clas/src/main/ClasStudentCache.scala b/modules/clas/src/main/ClasStudentCache.scala index eb5b1a117db68..88e0795365cf4 100644 --- a/modules/clas/src/main/ClasStudentCache.scala +++ b/modules/clas/src/main/ClasStudentCache.scala @@ -27,7 +27,7 @@ final class ClasStudentCache(colls: ClasColls)(using scheduler: Scheduler)(using .documentSource() .throttle(300, 1.second) .toMat(Sink.fold[Int, Bdoc](0) { case (counter, doc) => - if (counter % 500 == 0) logger.info(s"ClasStudentCache.rebuild $counter") + if counter % 500 == 0 then logger.info(s"ClasStudentCache.rebuild $counter") doc.string("userId") foreach nextBloom.add counter + 1 })(Keep.right) diff --git a/modules/coach/src/main/CoachProfileForm.scala b/modules/coach/src/main/CoachProfileForm.scala index 1865f467ce87f..f99ac9337aa08 100644 --- a/modules/coach/src/main/CoachProfileForm.scala +++ b/modules/coach/src/main/CoachProfileForm.scala @@ -52,9 +52,9 @@ object CoachProfileForm: listed = Coach.Listed(listed), available = Coach.Available(available), profile = profile, - languages = Json.parse(languages).validate[List[TagifyLang]] match { + languages = Json.parse(languages).validate[List[TagifyLang]] match case JsSuccess(langs, _) => langs.take(10).map(_.code).flatMap(Lang.get).map(_.code).distinct case _ => Nil - }, + , updatedAt = nowInstant ) diff --git a/modules/common/src/main/Bus.scala b/modules/common/src/main/Bus.scala index 8fcf4d0ad2d16..9b83b45863e1c 100644 --- a/modules/common/src/main/Bus.scala +++ b/modules/common/src/main/Bus.scala @@ -79,7 +79,7 @@ final private class EventBus[Event, Channel, Subscriber]( channel, (_: Channel, subs: Set[Subscriber]) => val newSubs = subs - subscriber - if (newSubs.isEmpty) null + if newSubs.isEmpty then null else newSubs ) .unit diff --git a/modules/common/src/main/Chronometer.scala b/modules/common/src/main/Chronometer.scala index b2a3a6cf272dd..55e65c8d6c308 100644 --- a/modules/common/src/main/Chronometer.scala +++ b/modules/common/src/main/Chronometer.scala @@ -12,7 +12,7 @@ object Chronometer: def seconds = (millis / 1000).toInt def logIfSlow(threshold: Int, logger: lila.log.Logger)(msg: A => String) = - if (millis >= threshold) log(logger)(msg) + if millis >= threshold then log(logger)(msg) else this def log(logger: lila.log.Logger)(msg: A => String) = logger.info(s"<${millis}ms> ${msg(result)}") @@ -34,10 +34,10 @@ object Chronometer: println(s"chrono $msg - $showDuration") result def ppIfGt(msg: String, duration: FiniteDuration): A = - if (nanos > duration.toNanos) pp(msg) + if nanos > duration.toNanos then pp(msg) else result - def showDuration: String = if (millis >= 1) s"$millis ms" else s"$micros micros" + def showDuration: String = if millis >= 1 then s"$millis ms" else s"$micros micros" case class LapTry[A](result: Try[A], nanos: Long): def millis = (nanos / 1000000).toInt diff --git a/modules/common/src/main/CuteNameGenerator.scala b/modules/common/src/main/CuteNameGenerator.scala index 8790c35a49f04..a43fd2e941bf9 100644 --- a/modules/common/src/main/CuteNameGenerator.scala +++ b/modules/common/src/main/CuteNameGenerator.scala @@ -8,8 +8,8 @@ object CuteNameGenerator: def make(maxSize: Int = 20, triesLeft: Int = 100): Option[UserName] = val name = makeForSure - if (name.value.sizeIs <= maxSize) name.some - else if (triesLeft <= 0) none + if name.value.sizeIs <= maxSize then name.some + else if triesLeft <= 0 then none else make(maxSize, triesLeft - 1) def makeForSure: UserName = UserName(anyOf(combinations).map(anyOf).mkString) diff --git a/modules/common/src/main/EmailAddress.scala b/modules/common/src/main/EmailAddress.scala index 4fc062a4581dc..3f6f73b0c3f05 100644 --- a/modules/common/src/main/EmailAddress.scala +++ b/modules/common/src/main/EmailAddress.scala @@ -18,7 +18,7 @@ object EmailAddress extends OpaqueString[EmailAddress]: val normalizedName = name .replace(".", "") // remove all dots .takeWhile('+' != _) // skip everything after the first '+' - if (normalizedName.isEmpty) lower else s"$normalizedName@$domain" + if normalizedName.isEmpty then lower else s"$normalizedName@$domain" case _ => lower def domain: Option[Domain] = diff --git a/modules/common/src/main/Form.scala b/modules/common/src/main/Form.scala index f3160051dd57f..78e364bf67f2f 100644 --- a/modules/common/src/main/Form.scala +++ b/modules/common/src/main/Form.scala @@ -6,7 +6,7 @@ import play.api.data.format.Formats.* import play.api.data.format.Formatter import play.api.data.Forms.* import play.api.data.validation.{ Constraint, Constraints } -import play.api.data.{ Field, FormError, Mapping, Form => PlayForm } +import play.api.data.{ Field, FormError, Mapping, Form as PlayForm } import play.api.data.validation as V import scala.util.Try import java.time.LocalDate @@ -109,8 +109,7 @@ object Form: // \u0131\u0307 is ı (\u0131) with an i dot (\u0307) private val regex = "(?iu)l(?:[i\u0456]|\u0131\u0307?)[c\u0441][h\u04bb][e\u0435][s\u0455]".r def apply(verifiedUser: Boolean) = Constraint[String] { (t: String) => - if (regex.find(t) && !verifiedUser) - V.Invalid(V.ValidationError("Must not contain \"lichess\"")) + if regex.find(t) && !verifiedUser then V.Invalid(V.ValidationError("Must not contain \"lichess\"")) else V.Valid } @@ -136,7 +135,7 @@ object Form: .transform[Color](c => Color.fromWhite(c == "white"), _.name) private def pluralize(pattern: String, nb: Int) = - pattern.replace("{s}", if (nb == 1) "" else "s") + pattern.replace("{s}", if nb == 1 then "" else "s") given intBase: Formatter[Int] = intFormat given strBase: Formatter[String] = stringFormat @@ -164,22 +163,24 @@ object Form: object constraint: def minLength[A](from: A => String)(length: Int): Constraint[A] = Constraint[A]("constraint.minLength", length) { o => - if (from(o).lengthIs >= length) V.Valid else V.Invalid(V.ValidationError("error.minLength", length)) + if from(o).lengthIs >= length then V.Valid + else V.Invalid(V.ValidationError("error.minLength", length)) } def maxLength[A](from: A => String)(length: Int): Constraint[A] = Constraint[A]("constraint.maxLength", length) { o => - if (from(o).lengthIs <= length) V.Valid else V.Invalid(V.ValidationError("error.maxLength", length)) + if from(o).lengthIs <= length then V.Valid + else V.Invalid(V.ValidationError("error.maxLength", length)) } object fen: val mapping = trim(of[String]).into[Fen.Epd] def playable(strict: Boolean) = mapping .verifying("Invalid position", fen => Fen.read(fen).exists(_ playable strict)) - .transform[Fen.Epd](if (strict) truncateMoveNumber else identity, identity) + .transform[Fen.Epd](if strict then truncateMoveNumber else identity, identity) val playableStrict = playable(strict = true) def truncateMoveNumber(fen: Fen.Epd) = Fen.readWithMoveNumber(fen).fold(fen) { g => - if (g.fullMoveNumber >= 150) + if g.fullMoveNumber >= 150 then Fen write g.copy(fullMoveNumber = g.fullMoveNumber.map(_ % 100)) // keep the start ply low else fen } @@ -206,10 +207,9 @@ object Form: def bind(key: String, data: Map[String, String]) = base.bind(key, data) map sr.apply def unbind(key: String, value: T) = base.unbind(key, rs(value)) - given Formatter[chess.variant.Variant] = { + given Formatter[chess.variant.Variant] = import chess.variant.Variant formatter.stringFormatter[Variant](_.key.value, str => Variant.orDefault(Variant.LilaKey(str))) - } extension [A](f: Formatter[A]) def transform[B](to: A => B, from: B => A): Formatter[B] = new: diff --git a/modules/common/src/main/Heapsort.scala b/modules/common/src/main/Heapsort.scala index 5426f92199ff9..1f1c9490ee581 100644 --- a/modules/common/src/main/Heapsort.scala +++ b/modules/common/src/main/Heapsort.scala @@ -13,7 +13,7 @@ object Heapsort: private[this] def moveN[T](p: PriorityQueue[T], g: Growable[T], n: Int): Unit = // Only the dequeue and dequeueAll methods will return elements in priority order (while removing elements from the heap). var k = p.length atMost n - while (k > 0) + while k > 0 do g += p.dequeue() k -= 1 diff --git a/modules/common/src/main/LilaCookie.scala b/modules/common/src/main/LilaCookie.scala index 5c2d2d8d99e3d..d74db3bb5e83f 100644 --- a/modules/common/src/main/LilaCookie.scala +++ b/modules/common/src/main/LilaCookie.scala @@ -34,7 +34,7 @@ final class LilaCookie(domain: NetDomain, baker: SessionCookieBaker): ) ) ), - if (remember) none else 0.some + if remember then none else 0.some ) def cookie(name: String, value: String, maxAge: Option[Int] = None, httpOnly: Option[Boolean] = None)(using @@ -43,7 +43,7 @@ final class LilaCookie(domain: NetDomain, baker: SessionCookieBaker): Cookie( name, value, - if (maxAge has 0) none + if maxAge has 0 then none else maxAge orElse baker.maxAge orElse 86400.some, "/", cookieDomain.some, @@ -57,7 +57,7 @@ final class LilaCookie(domain: NetDomain, baker: SessionCookieBaker): DiscardingCookie(name, "/", cookieDomain.some, baker.httpOnly) def ensure(req: RequestHeader)(res: Result): Result = - if (req.session.data.contains(LilaCookie.sessionId)) res + if req.session.data.contains(LilaCookie.sessionId) then res else res withCookies makeSessionId(using req) def ensureAndGet(req: RequestHeader)(res: String => Fu[Result])(using Executor): Fu[Result] = diff --git a/modules/common/src/main/MarkdownRender.scala b/modules/common/src/main/MarkdownRender.scala index f999ced990fb8..df4980b7803ec 100644 --- a/modules/common/src/main/MarkdownRender.scala +++ b/modules/common/src/main/MarkdownRender.scala @@ -49,11 +49,11 @@ final class MarkdownRender( ): private val extensions = java.util.ArrayList[Extension]() - if (table) + if table then extensions.add(TablesExtension.create()) extensions.add(MarkdownRender.tableWrapperExtension) - if (strikeThrough) extensions.add(StrikethroughExtension.create()) - if (autoLink) + if strikeThrough then extensions.add(StrikethroughExtension.create()) + if autoLink then extensions.add(AutolinkExtension.create()) extensions.add(MarkdownRender.WhitelistedImage.create(assetDomain)) extensions.add( @@ -70,10 +70,10 @@ final class MarkdownRender( .set(Parser.FENCED_CODE_BLOCK_PARSER, Boolean box code) // configurable - if (table) options.set(TablesExtension.CLASS_NAME, "slist") - if (!header) options.set(Parser.HEADING_PARSER, Boolean box false) - if (!blockQuote) options.set(Parser.BLOCK_QUOTE_PARSER, Boolean box false) - if (!list) options.set(Parser.LIST_BLOCK_PARSER, Boolean box false) + if table then options.set(TablesExtension.CLASS_NAME, "slist") + if !header then options.set(Parser.HEADING_PARSER, Boolean box false) + if !blockQuote then options.set(Parser.BLOCK_QUOTE_PARSER, Boolean box false) + if !list then options.set(Parser.LIST_BLOCK_PARSER, Boolean box false) private val immutableOptions = options.toImmutable @@ -146,15 +146,16 @@ object MarkdownRender: override def rendererOptions(options: MutableDataHolder) = () override def extend(htmlRendererBuilder: HtmlRenderer.Builder, rendererType: String) = htmlRendererBuilder - .nodeRendererFactory(new NodeRendererFactory { - override def apply(options: DataHolder) = new NodeRenderer: - override def getNodeRenderingHandlers() = - Set(NodeRenderingHandler(classOf[Image], render _)).asJava - }) + .nodeRendererFactory( + new NodeRendererFactory: + override def apply(options: DataHolder) = new NodeRenderer: + override def getNodeRenderingHandlers() = + Set(NodeRenderingHandler(classOf[Image], render _)).asJava + ) private def render(node: Image, context: NodeRendererContext, html: HtmlWriter): Unit = // Based on implementation in CoreNodeRenderer. - if (context.isDoNotRenderLinks || CoreNodeRenderer.isSuppressedLinkPrefix(node.getUrl(), context)) + if context.isDoNotRenderLinks || CoreNodeRenderer.isSuppressedLinkPrefix(node.getUrl(), context) then context.renderChildren(node) else { @@ -185,9 +186,10 @@ object MarkdownRender: override def rendererOptions(options: MutableDataHolder) = () override def extend(htmlRendererBuilder: HtmlRenderer.Builder, rendererType: String) = htmlRendererBuilder - .nodeRendererFactory(new NodeRendererFactory { - override def apply(options: DataHolder) = new PgnEmbedNodeRenderer(expander) - }) + .nodeRendererFactory( + new NodeRendererFactory: + override def apply(options: DataHolder) = new PgnEmbedNodeRenderer(expander) + ) .unit private class PgnEmbedNodeRenderer(expander: PgnSourceExpand) extends NodeRenderer: override def getNodeRenderingHandlers() = @@ -215,7 +217,7 @@ object MarkdownRender: private def renderLinkNode(node: LinkNode, context: NodeRendererContext, html: HtmlWriter) = // Based on implementation in CoreNodeRenderer. - if (context.isDoNotRenderLinks || CoreNodeRenderer.isSuppressedLinkPrefix(node.getUrl(), context)) + if context.isDoNotRenderLinks || CoreNodeRenderer.isSuppressedLinkPrefix(node.getUrl(), context) then context.renderChildren(node) else val link = context.resolveLink(LinkType.LINK, node.getUrl().unescape(), null, null) @@ -237,7 +239,7 @@ object MarkdownRender: html: HtmlWriter, baseLink: ResolvedLink ) = - val link = if (node.getTitle.isNotNull) baseLink.withTitle(node.getTitle().unescape()) else baseLink + val link = if node.getTitle.isNotNull then baseLink.withTitle(node.getTitle().unescape()) else baseLink html.attr("href", link.getUrl) html.attr(link.getNonNullAttributes()) html.srcPos(node.getChars()).withAttr(link).tag("a") @@ -270,14 +272,15 @@ object MarkdownRender: override def rendererOptions(options: MutableDataHolder) = () override def extend(htmlRendererBuilder: HtmlRenderer.Builder, rendererType: String) = htmlRendererBuilder - .attributeProviderFactory(new IndependentAttributeProviderFactory { - override def apply(context: LinkResolverContext): AttributeProvider = lilaLinkAttributeProvider - }) + .attributeProviderFactory( + new IndependentAttributeProviderFactory: + override def apply(context: LinkResolverContext): AttributeProvider = lilaLinkAttributeProvider + ) .unit private val lilaLinkAttributeProvider = new AttributeProvider: override def setAttributes(node: Node, part: AttributablePart, attributes: MutableAttributes) = - if ((node.isInstanceOf[Link] || node.isInstanceOf[AutoLink]) && part == AttributablePart.LINK) + if (node.isInstanceOf[Link] || node.isInstanceOf[AutoLink]) && part == AttributablePart.LINK then attributes.replaceValue("rel", rel).unit attributes.replaceValue("href", RawHtml.removeUrlTrackingParameters(attributes.getValue("href"))).unit diff --git a/modules/common/src/main/Maths.scala b/modules/common/src/main/Maths.scala index ba045fc92084e..0e84c46add628 100644 --- a/modules/common/src/main/Maths.scala +++ b/modules/common/src/main/Maths.scala @@ -55,7 +55,7 @@ object Maths: @scala.annotation.tailrec def boxedNormalDistribution(mean: Int, deviation: Int, factor: Double): Int = val normal = mean + deviation * ThreadLocalRandom.nextGaussian() * factor.atMost(1) - if (normal > mean - deviation && normal < mean + deviation) normal.toInt + if normal > mean - deviation && normal < mean + deviation then normal.toInt else boxedNormalDistribution(mean, deviation, factor) // https://www.scribbr.com/statistics/standard-deviation/ diff --git a/modules/common/src/main/SimpleOpening.scala b/modules/common/src/main/SimpleOpening.scala index 7b13b07668fc9..61edbbb62d6ff 100644 --- a/modules/common/src/main/SimpleOpening.scala +++ b/modules/common/src/main/SimpleOpening.scala @@ -14,7 +14,7 @@ case class SimpleOpening(ref: Opening, name: SimpleOpening.Name, family: LilaOpe import SimpleOpening.* val key = nameToKey(name into OpeningName) into Key def isFamily = ref.variation.isEmpty - def familyKeyOrKey = if (isFamily) Key(family.key.value) else key + def familyKeyOrKey = if isFamily then Key(family.key.value) else key def variation = ref.variation | otherVariations inline def nbMoves = ref.nbMoves inline def lastUci = ref.lastUci @@ -42,7 +42,7 @@ object SimpleOpening: LilaOpeningFamily(ref.family.key into LilaOpeningFamily.Key).fold(acc): fam => val op = SimpleOpening(ref, nameOf(ref), fam) val prev = acc get op.key - if (prev.fold(true)(_.nbMoves > op.nbMoves)) acc.updated(op.key, op) + if prev.fold(true)(_.nbMoves > op.nbMoves) then acc.updated(op.key, op) else acc lazy val openingList = openings.values.toList.sortBy(_.name.value) diff --git a/modules/common/src/main/String.scala b/modules/common/src/main/String.scala index a48695870a50d..206cd33ed7cda 100644 --- a/modules/common/src/main/String.scala +++ b/modules/common/src/main/String.scala @@ -108,7 +108,7 @@ object String: def shorten(text: String, length: Int): String = shorten(text, length, "…") def shorten(text: String, length: Int, sep: String): String = val oneline = onelineR.replaceAllIn(text, " ") - if (oneline.lengthIs > length + sep.length) oneline.take(length) ++ sep + if oneline.lengthIs > length + sep.length then oneline.take(length) ++ sep else oneline def isShouting(text: String) = @@ -122,7 +122,7 @@ object String: case _ => i } > 0 } - def noShouting(str: String): String = if (isShouting(str)) str.toLowerCase else str + def noShouting(str: String): String = if isShouting(str) then str.toLowerCase else str object base64: import java.util.Base64 @@ -145,7 +145,7 @@ object String: ): Frag = raw: val withLinks = RawHtml.addLinks(rawText, expandImg) - if (nl2br) RawHtml.nl2br(withLinks.value) else withLinks + if nl2br then RawHtml.nl2br(withLinks.value) else withLinks def nl2brUnsafe(text: String): Frag = raw: @@ -163,7 +163,7 @@ object String: def markdownLinksOrRichText(text: String)(using config.NetDomain): Frag = val escaped = Html(escapeHtmlRaw(text)) val marked = RawHtml.justMarkdownLinks(escaped) - if (marked == escaped) richText(text) + if marked == escaped then richText(text) else nl2brUnsafe(marked.value) def safeJsonValue(jsValue: JsValue): String = diff --git a/modules/common/src/main/WMMatching.scala b/modules/common/src/main/WMMatching.scala index 44846e334988b..dc485143e6399 100644 --- a/modules/common/src/main/WMMatching.scala +++ b/modules/common/src/main/WMMatching.scala @@ -35,7 +35,7 @@ object WMMatching: // founds minimum-weighted matching among maximum-cardinality matchings private[this] def lowLevel(nvertex: Int, pairScore: (Int, Int) => Option[Int]): List[(Int, Int)] = val (endpoint, weights) = fullGraph(nvertex, pairScore) - if (endpoint.isEmpty) Nil + if endpoint.isEmpty then Nil else val maxweight = weights.max maxWeightMatching(endpoint, weights.mapInPlace { maxweight - _ }, maxcardinality = true) @@ -75,11 +75,11 @@ object WMMatching: private[this] def mateToList(endpoint: Array[Int], mate: Array[Int]): List[(Int, Int)] = // Transform mate such that mate(v) is the vertex to which v is paired. var l: List[(Int, Int)] = Nil - for (v <- Range(mate.length - 2, -1, -1)) + for v <- Range(mate.length - 2, -1, -1) do val k = mate(v) - if (k >= 0) + if k >= 0 then val e = endpoint(k) - if (v < e) l ::= ((v, e)) + if v < e then l ::= ((v, e)) l private[this] def fullGraph( @@ -91,15 +91,14 @@ object WMMatching: e.sizeHint(m) val w = Array.newBuilder[Int] w.sizeHint(m >> 1) - for { + for i <- 0 until (nvertex - 1) j <- (i + 1) until nvertex p <- pairScore(i, j) - } yield { + yield e += i e += j w += p - } (e.result(), w.result()) private class BlossomIdAllocator(n: Int): @@ -108,7 +107,7 @@ object WMMatching: private[this] var freeIds = SortedSet.empty[Int] private[this] var top = n def allocateId(): Int = - val i = if (freeIds.isEmpty) + val i = if freeIds.isEmpty then top += 1 top else @@ -124,7 +123,7 @@ object WMMatching: private class DuelDelta(val tp: Int, var delta: Int): var extra = -1 def update(d: Int, e: Int): Unit = - if (delta > d) + if delta > d then delta = d extra = e private object Impl: @@ -190,7 +189,7 @@ object WMMatching: // If b is a (sub-)blossom, // blossombase(b) is its base VERTEX (i.e. recursive sub-blossom). - private[this] val blossombase = Array.tabulate[Int](2 * nvertex) { i => if (i < nvertex) i else -1 } + private[this] val blossombase = Array.tabulate[Int](2 * nvertex) { i => if i < nvertex then i else -1 } /* If b is a non-trivial (sub-)blossom, @@ -227,7 +226,7 @@ object WMMatching: private[this] val dualvar = // Find the maximum edge weight. val maxweight = weights.max - Array.tabulate[Int](2 * nvertex) { i => if (i < nvertex) maxweight else 0 } + Array.tabulate[Int](2 * nvertex) { i => if i < nvertex then maxweight else 0 } // slack function optimization private[this] val dw = weights.map { _ * 2 } @@ -248,7 +247,7 @@ object WMMatching: // Generate the leaf vertices of a blossom. private[this] def blossomLeaves(b: Int): Iterator[Int] = - if (b < nvertex) Iterator(b) else blossomLeavesG(b) + if b < nvertex then Iterator(b) else blossomLeavesG(b) // Assign label t to the top-level blossom containing vertex w // and record the fact that w was reached through the edge with @@ -263,7 +262,7 @@ object WMMatching: labelend(b) = p bestedge(w) = -1 bestedge(b) = -1 - if (t == 1) + if t == 1 then // b became an S-vertex/blossom; add it(s vertices) to the queue. blossomLeaves(b).foreach(queue ::= _) else @@ -275,23 +274,23 @@ object WMMatching: // Trace back from v and w, placing breadcrumbs as we go. @tailrec private[this] def scan(v: Int, w: Int, path: List[Int]): (Int, List[Int]) = - if (v == -1 && w == -1) (-1, path) // not found + if v == -1 && w == -1 then (-1, path) // not found else // Look for a breadcrumb in v's blossom or put a new breadcrumb. val b = inblossom(v) - if (label(b) == 3) (blossombase(b), path) + if label(b) == 3 then (blossombase(b), path) else label(b) = 3 // Trace one step back. val nv = - if (labelend(b) == -1) -1 + if labelend(b) == -1 then -1 else val t = endpoint(labelend(b)) val c = inblossom(t) // c is a T-blossom; trace one more step back. endpoint(labelend(c)) // Swap v and w so that we alternate between both paths. - if (w != -1) scan(w, nv, b :: path) + if w != -1 then scan(w, nv, b :: path) else scan(nv, w, b :: path) // Trace back from vertices v and w to discover either a new blossom // or an augmenting path. Return the base vertex of the new blossom or -1. @@ -318,7 +317,7 @@ object WMMatching: endps: List[Int] ): (List[Int], List[Int]) = val bv = inblossom(v) - if (bv == bb) (path, endps) + if bv == bb then (path, endps) else // Add bv to the new blossom. blossomparent(bv) = b @@ -331,7 +330,7 @@ object WMMatching: val bb = inblossom(base) // Create blossom. val b = blossomIdAllocator.allocateId() - if (allocatedvertex <= b) allocatedvertex = b + 1 + if allocatedvertex <= b then allocatedvertex = b + 1 blossombase(b) = base blossomparent(b) = -1 blossomparent(bb) = b @@ -348,8 +347,8 @@ object WMMatching: // Set dual variable to zero. dualvar(b) = 0 // Relabel vertices. - for (v <- blossomLeaves(b)) - if (label(inblossom(v)) == 2) + for v <- blossomLeaves(b) do + if label(inblossom(v)) == 2 then // This T-vertex now turns into an S-vertex because it becomes // part of an S-blossom; add it to the queue. queue ::= v @@ -357,42 +356,39 @@ object WMMatching: // Compute blossombestedges(b). val bestedgeto = Array.fill(allocatedvertex)(-1) - for (bv <- blossomchilds(b)) + for bv <- blossomchilds(b) do val nblists = - if (blossombestedges(bv) == null) + if blossombestedges(bv) == null then blossomLeaves(bv).flatMap(neighbend(_).view.map { p => p >> 1 }) else blossombestedges(bv).iterator - for (k <- nblists) + for k <- nblists do val kk = 2 * k - val j = if (inblossom(endpoint(kk + 1)) == b) endpoint(kk) else endpoint(kk + 1) + val j = if inblossom(endpoint(kk + 1)) == b then endpoint(kk) else endpoint(kk + 1) val bj = inblossom(j) - if (bj != b && label(bj) == 1) + if bj != b && label(bj) == 1 then val i = bestedgeto(bj) - if (i == -1 || slack(k) < slack(i)) - bestedgeto(bj) = k + if i == -1 || slack(k) < slack(i) then bestedgeto(bj) = k // Forget about least-slack edges of the subblossom. blossombestedges(bv) = null bestedge(bv) = -1 val a = bestedgeto.filter { _ != -1 } blossombestedges(b) = a // Select bestedge(b). - bestedge(b) = if (a.nonEmpty) a.minBy(slack) else -1 + bestedge(b) = if a.nonEmpty then a.minBy(slack) else -1 // Expand the given top-level blossom. private[this] def expandBlossom(b: Int, endstage: Boolean): Unit = // Convert sub-blossoms into top-level blossoms. - for (s <- blossomchilds(b)) + for s <- blossomchilds(b) do blossomparent(s) = -1 - if (s < nvertex) - inblossom(s) = s - else if (endstage && dualvar(s) == 0) + if s < nvertex then inblossom(s) = s + else if endstage && dualvar(s) == 0 then // Recursively expand this sub-blossom. expandBlossom(s, endstage) - else - blossomLeaves(s).foreach(inblossom(_) = s) + else blossomLeaves(s).foreach(inblossom(_) = s) // If we expand a T-blossom during a stage, its sub-blossoms must be // relabeled. - if (!endstage && label(b) == 2) + if !endstage && label(b) == 2 then // Start at the sub-blossom through which the expanding // blossom obtained its label, and relabel sub-blossoms until // we reach the base. @@ -404,12 +400,12 @@ object WMMatching: val l1 = blossomchilds(b).length - 1 val (jstep, endptrick) = // Start index is odd; go forward and wrap. - if ((j & 1) != 0) ((j: Int) => { if (j == l1) 0 else j + 1 }, 0) + if (j & 1) != 0 then ((j: Int) => if j == l1 then 0 else j + 1, 0) // Start index is even; go backward. - else ((j: Int) => { if (j == 0) l1 else j - 1 }, 1) + else ((j: Int) => if j == 0 then l1 else j - 1, 1) // Move along the blossom until we get to the base. var p = labelend(b) - while (j != 0) + while j != 0 do // Relabel the T-sub-blossom. label(endpoint(p ^ 1)) = 0 label(endpoint(blossomendps(b)(j - endptrick) ^ endptrick ^ 1)) = 0 @@ -431,22 +427,22 @@ object WMMatching: bestedge(bv) = -1 // Continue along the blossom until we get back to entrychild. j = jstep(j) - while (blossomchilds(b)(j) != entrychild) + while blossomchilds(b)(j) != entrychild do // Examine the vertices of the sub-blossom to see whether // it is reachable from a neighbouring S-vertex outside the // expanding blossom. val bv = blossomchilds(b)(j) - if (label(bv) == 1) { + if label(bv) == 1 then { // This sub-blossom just got label S through one of its // neighbours; leave it. } else blossomLeaves(bv) .find(label(_) != 0) - .foreach(v => { + .foreach(v => label(v) = 0 label(endpoint(mate(blossombase(bv)))) = 0 assignLabel(v, 2, labelend(v)) - }) + ) j = jstep(j) // Recycle the blossom number. label(b) = -1 @@ -464,36 +460,32 @@ object WMMatching: // Bubble up through the blossom tree from vertex v to an immediate // isub-blossom of b. var t = v - while (blossomparent(t) != b) - t = blossomparent(t) + while blossomparent(t) != b do t = blossomparent(t) // Recursively deal with the first sub-blossom. - if (t >= nvertex) - augmentBlossom(t, v) + if t >= nvertex then augmentBlossom(t, v) // Decide in which direction we will go round the blossom. val l1 = blossomchilds(b).length - 1 val i = blossomchilds(b).indexOf(t) var j = i val (jstep, endptrick) = - if ((j & 1) != 0) ((j: Int) => { if (j == l1) 0 else j + 1 }, 0) - else ((j: Int) => { if (j == 0) l1 else j - 1 }, 1) + if (j & 1) != 0 then ((j: Int) => if j == l1 then 0 else j + 1, 0) + else ((j: Int) => if j == 0 then l1 else j - 1, 1) // Move along the blossom until we get to the base. - while (j != 0) + while j != 0 do // Step to the next sub-blossom and augment it recursively. j = jstep(j) t = blossomchilds(b)(j) val p = blossomendps(b)(j - endptrick) ^ endptrick - if (t >= nvertex) - augmentBlossom(t, endpoint(p)) + if t >= nvertex then augmentBlossom(t, endpoint(p)) // Step to the next sub-blossom and augment it recursively. j = jstep(j) t = blossomchilds(b)(j) - if (t >= nvertex) - augmentBlossom(t, endpoint(p ^ 1)) + if t >= nvertex then augmentBlossom(t, endpoint(p ^ 1)) // Match the edge connecting those sub-blossoms. mate(endpoint(p)) = p ^ 1 mate(endpoint(p ^ 1)) = p // Rotate the list of sub-blossoms to put the new base at the front. - if (i > 0) + if i > 0 then val n = blossomchilds(b).length val t1 = new Array[Int](n) Impl.rotate(blossomchilds(b), t1, n, i) @@ -513,11 +505,10 @@ object WMMatching: @tailrec def f(s: Int, p: Int): Unit = val bs = inblossom(s) // Augment through the S-blossom from s to base. - if (bs >= nvertex) - augmentBlossom(bs, s) + if bs >= nvertex then augmentBlossom(bs, s) mate(s) = p // Trace one step back. - if (labelend(bs) == -1) { + if labelend(bs) == -1 then { // Reached single vertex; stop. } else val t = endpoint(labelend(bs)) @@ -526,8 +517,7 @@ object WMMatching: val ns = endpoint(labelend(bt)) val j = endpoint(labelend(bt) ^ 1) // Augment through the T-blossom from j to base. - if (bt >= nvertex) - augmentBlossom(bt, j) + if bt >= nvertex then augmentBlossom(bt, j) // Update mate(j) mate(j) = labelend(bt) // Keep the opposite endpoint; @@ -538,7 +528,7 @@ object WMMatching: f(endpoint(kk + 1), kk) @tailrec private[this] def substage(): Boolean = - if (queue.isEmpty) false + if queue.isEmpty then false else // Take an S vertex from the queue. val v = queue.head @@ -547,27 +537,26 @@ object WMMatching: val k = p >> 1 val w = endpoint(p) // w is a neighbour to v - if (inblossom(v) == inblossom(w)) + if inblossom(v) == inblossom(w) then // this edge is internal to a blossom; ignore it false else var kslack = 0 - if (!allowedge(k)) + if !allowedge(k) then kslack = slack(k) - if (kslack <= 0) - allowedge(k) = true - if (allowedge(k)) - if (label(inblossom(w)) == 0) + if kslack <= 0 then allowedge(k) = true + if allowedge(k) then + if label(inblossom(w)) == 0 then // (C1) w is a free vertex; // label w with T and label its mate with S (R12). assignLabel(w, 2, p ^ 1) false - else if (label(inblossom(w)) == 1) + else if label(inblossom(w)) == 1 then // (C2) w is an S-vertex (not in the same blossom); // follow back-links to discover either an // augmenting path or a new blossom. val base = scanBlossom(v, w) - if (base >= 0) + if base >= 0 then // Found a new blossom; add it to the blossom // bookkeeping and turn it into an S-blossom. addBlossom(base, k) @@ -577,7 +566,7 @@ object WMMatching: // matching and end this stage. augmentMatching(k) true - else if (label(w) == 0) + else if label(w) == 0 then // w is inside a T-blossom, but w itself has not // yet been reached from outside the blossom; // mark it as reached (we need this to relabel @@ -586,25 +575,21 @@ object WMMatching: labelend(w) = p ^ 1 false else false - else if (label(inblossom(w)) == 1) + else if label(inblossom(w)) == 1 then // keep track of the least-slack non-allowable edge to // a different S-blossom. val b = inblossom(v) - if (bestedge(b) == -1 || kslack < slack(bestedge(b))) - bestedge(b) = k + if bestedge(b) == -1 || kslack < slack(bestedge(b)) then bestedge(b) = k false - else if (label(w) == 0) + else if label(w) == 0 then // w is a free vertex (or an unreached vertex inside // a T-blossom) but we can not reach it yet; // keep track of the least-slack edge that reaches w. - if (bestedge(w) == -1 || kslack < slack(bestedge(w))) - bestedge(w) = k + if bestedge(w) == -1 || kslack < slack(bestedge(w)) then bestedge(w) = k false else false - if (neighbend(v).exists(go)) - true - else - substage() + if neighbend(v).exists(go) then true + else substage() private[this] val vertices = 0 until nvertex private[this] def updateDual(): Boolean = // There is no augmenting path under these constraints; @@ -615,47 +600,41 @@ object WMMatching: val dt0 = new DuelDelta(0, Int.MaxValue) // Compute delta0: the minimum value of any vertex dual. - if (!maxcardinality) - dt0.update(dualvar.view.slice(0, nvertex).min, -1) + if !maxcardinality then dt0.update(dualvar.view.slice(0, nvertex).min, -1) // Compute delta1: the minimum slack on any edge between // an S-vertex and a free vertex. val dt1 = new DuelDelta(1, dt0.delta) - for { + for v <- vertices if label(inblossom(v)) == 0 - } yield { + yield val be = bestedge(v) - if (be != -1) - dt1.update(slack(be), be) - } + if be != -1 then dt1.update(slack(be), be) val dt2 = new DuelDelta(2, dt1.delta) // Compute delta2: half the minimum slack on any edge between // a pair of S-blossoms. - for { + for b <- 0 until allocatedvertex if blossomparent(b) == -1 && label(b) == 1 - } yield { + yield val be = bestedge(b) - if (be != -1) - dt2.update(slack(be) >> 1, be) - } + if be != -1 then dt2.update(slack(be) >> 1, be) val dt3 = new DuelDelta(3, dt2.delta) // Compute delta3: minimum z variable of any T-blossom. - for (b <- nvertex until allocatedvertex) - if (blossombase(b) >= 0 && blossomparent(b) == -1 && label(b) == 2) - dt3.update(dualvar(b), b) + for b <- nvertex until allocatedvertex do + if blossombase(b) >= 0 && blossomparent(b) == -1 && label(b) == 2 then dt3.update(dualvar(b), b) - if (dt3.delta == Int.MaxValue) + if dt3.delta == Int.MaxValue then // No further improvement possible; max-cardinality optimum reached. false else val dt = List(dt0, dt1, dt2, dt3).find(_.delta == dt3.delta).head // Update dual variables according to delta. - for (v <- vertices) + for v <- vertices do label(inblossom(v)) match case 0 => () case 1 => @@ -665,8 +644,8 @@ object WMMatching: // T-vertex: 2*u = 2*u + 2*delta dualvar(v) += dt.delta - for (b <- nvertex until allocatedvertex) - if (blossombase(b) >= 0 && blossomparent(b) == -1) + for b <- nvertex until allocatedvertex do + if blossombase(b) >= 0 && blossomparent(b) == -1 then label(b) match case 0 => () case 1 => dualvar(b) += dt.delta @@ -680,7 +659,7 @@ object WMMatching: allowedge(dt.extra) = true val kk = 2 * dt.extra val ei = endpoint(kk) - queue ::= (if (label(inblossom(ei)) == 0) endpoint(kk + 1) else ei) + queue ::= (if label(inblossom(ei)) == 0 then endpoint(kk + 1) else ei) true case 2 => // Use the least-slack edge to continue the search. @@ -692,8 +671,8 @@ object WMMatching: true @tailrec private[this] def stage(): Boolean = - if (substage()) true - else if (!updateDual()) false + if substage() then true + else if !updateDual() then false else stage() // Main loop: continue until no further improvement is possible. @@ -717,10 +696,7 @@ object WMMatching: queue = Nil // Label single blossoms/vertices with S and put them in the queue. - for (v <- vertices) - if (mate(v) == -1 && label(inblossom(v)) == 0) - assignLabel(v, 1, -1) - if (stage() && iterations > 1) - mainLoop(iterations - 1) + for v <- vertices do if mate(v) == -1 && label(inblossom(v)) == 0 then assignLabel(v, 1, -1) + if stage() && iterations > 1 then mainLoop(iterations - 1) mainLoop(nvertex) def result: Array[Int] = mate diff --git a/modules/common/src/main/base/LilaJsonExtensions.scala b/modules/common/src/main/base/LilaJsonExtensions.scala index 22c7ac1c56d8a..2167cbb7ca03b 100644 --- a/modules/common/src/main/base/LilaJsonExtensions.scala +++ b/modules/common/src/main/base/LilaJsonExtensions.scala @@ -45,13 +45,13 @@ trait JsonExtensions: } def add(pair: (String, Boolean)): JsObject = - if (pair._2) js + (pair._1 -> JsBoolean(true)) + if pair._2 then js + (pair._1 -> JsBoolean(true)) else js def add[A](pair: (String, A))(using sr: SameRuntime[A, Boolean]): JsObject = add(pair._1, sr(pair._2)) def add(key: String, value: Boolean): JsObject = - if (value) js + (key -> JsBoolean(true)) + if value then js + (key -> JsBoolean(true)) else js def add[A](key: String, value: A)(using sr: SameRuntime[A, Boolean]): JsObject = add(key, sr(value)) diff --git a/modules/common/src/main/base/LilaLibraryExtensions.scala b/modules/common/src/main/base/LilaLibraryExtensions.scala index c2833b2fa894a..b40004d5c7f54 100644 --- a/modules/common/src/main/base/LilaLibraryExtensions.scala +++ b/modules/common/src/main/base/LilaLibraryExtensions.scala @@ -25,8 +25,8 @@ trait LilaLibraryExtensions extends LilaTypes: def atMost(topValue: Long): Long = min(self, topValue) def squeeze(bottom: Long, top: Long): Long = max(min(self, top), bottom) def toSaturatedInt: Int = - if (self.toInt == self) self.toInt - else if (self > 0) Integer.MAX_VALUE + if self.toInt == self then self.toInt + else if self > 0 then Integer.MAX_VALUE else Integer.MIN_VALUE extension (self: Int) @@ -67,13 +67,13 @@ trait LilaLibraryExtensions extends LilaTypes: extension (s: String) def replaceIf(t: Char, r: Char): String = - if (s.indexOf(t.toInt) >= 0) s.replace(t, r) else s + if s.indexOf(t.toInt) >= 0 then s.replace(t, r) else s def replaceIf(t: Char, r: CharSequence): String = - if (s.indexOf(t.toInt) >= 0) s.replace(String.valueOf(t), r) else s + if s.indexOf(t.toInt) >= 0 then s.replace(String.valueOf(t), r) else s def replaceIf(t: CharSequence, r: CharSequence): String = - if (s.contains(t)) s.replace(t, r) else s + if s.contains(t) then s.replace(t, r) else s def replaceAllIn(regex: Regex, replacement: String) = regex.replaceAllIn(s, replacement) @@ -107,7 +107,7 @@ trait LilaLibraryExtensions extends LilaTypes: extension (d: FiniteDuration) def toCentis = chess.Centis(d) - def abs = if (d.length < 0) -d else d + def abs = if d.length < 0 then -d else d extension [E, A](v: Validated[E, A]) def toFuture: Fu[A] = v.fold(err => fufail(err.toString), fuccess) @@ -302,15 +302,15 @@ trait LilaLibraryExtensions extends LilaTypes: extension (fua: Fu[Boolean]) def >>&(fub: => Fu[Boolean]): Fu[Boolean] = - fua.flatMap { if (_) fub else fuFalse }(EC.parasitic) + fua.flatMap { if _ then fub else fuFalse }(EC.parasitic) def >>|(fub: => Fu[Boolean]): Fu[Boolean] = - fua.flatMap { if (_) fuTrue else fub }(EC.parasitic) + fua.flatMap { if _ then fuTrue else fub }(EC.parasitic) def flatMapz[B](fub: => Fu[B])(using zero: Zero[B]): Fu[B] = - fua.flatMap { if (_) fub else fuccess(zero.zero) }(EC.parasitic) + fua.flatMap { if _ then fub else fuccess(zero.zero) }(EC.parasitic) def mapz[B](fb: => B)(using zero: Zero[B]): Fu[B] = - fua.map { if (_) fb else zero.zero }(EC.parasitic) + fua.map { if _ then fb else zero.zero }(EC.parasitic) inline def unary_! = fua.map { !_ }(EC.parasitic) diff --git a/modules/common/src/main/base/RawHtml.scala b/modules/common/src/main/base/RawHtml.scala index 9494eb6d948c1..7cd2bbd11bcbb 100644 --- a/modules/common/src/main/base/RawHtml.scala +++ b/modules/common/src/main/base/RawHtml.scala @@ -14,12 +14,11 @@ object RawHtml: def nl2br(s: String): Html = val sb = jStringBuilder(s.length) var counter = 0 - for (char <- s) - if (char == '\n') + for char <- s do + if char == '\n' then counter += 1 - if (counter < 3) - sb.append("${content.trim}
" else "" + if m.toLowerCase == move.toLowerCase then s"${content.trim}
" else "" case html => html } mkString "\n" } diff --git a/modules/opening/src/test/OpeningSearchTest.scala b/modules/opening/src/test/OpeningSearchTest.scala index f364314e4c756..56dc68e931ab7 100644 --- a/modules/opening/src/test/OpeningSearchTest.scala +++ b/modules/opening/src/test/OpeningSearchTest.scala @@ -2,7 +2,7 @@ package lila.opening import chess.opening.OpeningName -class OpeningSearchTest extends munit.FunSuite { +class OpeningSearchTest extends munit.FunSuite: def search(q: String) = OpeningSearch(q, 10) @@ -25,4 +25,3 @@ class OpeningSearchTest extends munit.FunSuite { test("progressive") { assertEquals(search("Sicil").headOption.map(_.name), OpeningName("Sicilian Defense").some) } -} diff --git a/modules/opening/src/test/OpeningTest.scala b/modules/opening/src/test/OpeningTest.scala index e6a466194b852..6142f8206e5f3 100644 --- a/modules/opening/src/test/OpeningTest.scala +++ b/modules/opening/src/test/OpeningTest.scala @@ -2,7 +2,7 @@ package lila.opening import chess.opening.OpeningName -class OpeningTest extends munit.FunSuite { +class OpeningTest extends munit.FunSuite: import NameSection.variationName def vn(prev: String, next: String, expected: String) = @@ -59,4 +59,3 @@ class OpeningTest extends munit.FunSuite { "Semi-Slav Defense" ) } -} diff --git a/modules/perfStat/src/main/PerfStat.scala b/modules/perfStat/src/main/PerfStat.scala index fc5ddc74ce565..28f15c363a0ed 100644 --- a/modules/perfStat/src/main/PerfStat.scala +++ b/modules/perfStat/src/main/PerfStat.scala @@ -21,14 +21,14 @@ case class PerfStat( inline def id = _id def agg(pov: Pov) = - if (!pov.game.finished) this + if !pov.game.finished then this else val thisYear = pov.game.createdAt isAfter nowInstant.minusYears(1) copy( highest = RatingAt.agg(highest, pov, 1), - lowest = if (thisYear) RatingAt.agg(lowest, pov, -1) else lowest, - bestWins = if (~pov.win) bestWins.agg(pov, 1) else bestWins, - worstLosses = if (thisYear && ~pov.loss) worstLosses.agg(pov, -1) else worstLosses, + lowest = if thisYear then RatingAt.agg(lowest, pov, -1) else lowest, + bestWins = if ~pov.win then bestWins.agg(pov, 1) else bestWins, + worstLosses = if thisYear && ~pov.loss then worstLosses.agg(pov, -1) else worstLosses, count = count(pov), resultStreak = resultStreak agg pov, playStreak = playStreak agg pov @@ -74,7 +74,7 @@ case class PlayStreak(nb: Streaks, time: Streaks, lastDate: Option[Instant]): ) } def checkCurrent = - if (isContinued(nowInstant)) this + if isContinued(nowInstant) then this else copy(nb = nb.reset, time = time.reset) private def isContinued(at: Instant) = lastDate.fold(true) { ld => @@ -89,14 +89,14 @@ case class Streaks(cur: Streak, max: Streak): def continueOrStart(cont: Boolean, pov: Pov)(v: Int) = copy(cur = cur.continueOrStart(cont, pov)(v)).setMax def reset = copy(cur = Streak.init) - private def setMax = copy(max = if (cur.v >= max.v) cur else max) + private def setMax = copy(max = if cur.v >= max.v then cur else max) object Streaks: val init = Streaks(Streak.init, Streak.init) case class Streak(v: Int, from: Option[GameAt], to: Option[GameAt]): def continueOrReset(cont: Boolean, pov: Pov)(v: Int) = - if (cont) inc(pov, v) else Streak.init + if cont then inc(pov, v) else Streak.init def continueOrStart(cont: Boolean, pov: Pov)(v: Int) = - if (cont) inc(pov, v) + if cont then inc(pov, v) else val at = GameAt(pov.game.createdAt, pov.gameId).some val end = GameAt(pov.game.movedAt, pov.gameId).some @@ -124,19 +124,19 @@ case class Count( def apply(pov: Pov) = copy( all = all + 1, - rated = rated + (if (pov.game.rated) 1 else 0), - win = win + (if (pov.win.contains(true)) 1 else 0), - loss = loss + (if (pov.win.contains(false)) 1 else 0), - draw = draw + (if (pov.win.isEmpty) 1 else 0), - tour = tour + (if (pov.game.isTournament) 1 else 0), - berserk = berserk + (if (pov.player.berserk) 1 else 0), + rated = rated + (if pov.game.rated then 1 else 0), + win = win + (if pov.win.contains(true) then 1 else 0), + loss = loss + (if pov.win.contains(false) then 1 else 0), + draw = draw + (if pov.win.isEmpty then 1 else 0), + tour = tour + (if pov.game.isTournament then 1 else 0), + berserk = berserk + (if pov.player.berserk then 1 else 0), opAvg = pov.opponent.stableRating.fold(opAvg)(r => opAvg agg r.value), - seconds = seconds + (pov.game.durationSeconds match { + seconds = seconds + (pov.game.durationSeconds match case Some(s) if s <= 3 * 60 * 60 => s case _ => 0 - }), + ), disconnects = disconnects + { - if (~pov.loss && pov.game.status == chess.Status.Timeout) 1 else 0 + if ~pov.loss && pov.game.status == chess.Status.Timeout then 1 else 0 } ) def duration = Duration.ofSeconds(seconds) diff --git a/modules/plan/src/main/Charge.scala b/modules/plan/src/main/Charge.scala index d638f00157ac4..ee568423c0e19 100644 --- a/modules/plan/src/main/Charge.scala +++ b/modules/plan/src/main/Charge.scala @@ -22,9 +22,9 @@ case class Charge( def isStripe = stripe.nonEmpty def serviceName = - if (isStripe) "stripe" - else if (isPayPalLegacy) "paypal legacy" - else if (isPayPalCheckout) "paypal checkout" + if isStripe then "stripe" + else if isPayPalLegacy then "paypal legacy" + else if isPayPalCheckout then "paypal checkout" else "???" def toGift = (userId, giftTo) mapN { Charge.Gift(_, _, date) } diff --git a/modules/plan/src/main/Currency.scala b/modules/plan/src/main/Currency.scala index 363f5414d8e65..5106e7a3ce1c3 100644 --- a/modules/plan/src/main/Currency.scala +++ b/modules/plan/src/main/Currency.scala @@ -26,7 +26,7 @@ final class CurrencyApi( private val ratesCache = mongoCache.unit[Map[String, Double]]( "currency:rates", - if (mode == Mode.Prod) 120 minutes // i.e. 377/month, under the 1000/month limit of free OER plan + if mode == Mode.Prod then 120 minutes // i.e. 377/month, under the 1000/month limit of free OER plan else 1 day ) { loader => _.refreshAfterWrite(121 minutes) @@ -48,10 +48,10 @@ final class CurrencyApi( def convert(money: Money, currency: Currency): Fu[Option[Money]] = ratesCache.get {} map { rates => - for { + for fromRate <- rates get money.currencyCode toRate <- rates get currency.getCurrencyCode - } yield Money(money.amount / fromRate * toRate, currency) + yield Money(money.amount / fromRate * toRate, currency) } def toUsd(money: Money): Fu[Option[Usd]] = diff --git a/modules/plan/src/main/Patron.scala b/modules/plan/src/main/Patron.scala index b9275cc4c91ec..ced620d204832 100644 --- a/modules/plan/src/main/Patron.scala +++ b/modules/plan/src/main/Patron.scala @@ -27,7 +27,7 @@ case class Patron( ) def expireInOneMonth(cond: Boolean): Patron = - if (cond) expireInOneMonth + if cond then expireInOneMonth else copy(expiresAt = none) def removeStripe = diff --git a/modules/plan/src/main/PayPalClient.scala b/modules/plan/src/main/PayPalClient.scala index daad142b232c7..b5c385996cda7 100644 --- a/modules/plan/src/main/PayPalClient.scala +++ b/modules/plan/src/main/PayPalClient.scala @@ -134,7 +134,7 @@ final private class PayPalClient( )(using (__ \ "plans").read[List[PayPalPlan]]) current .flatMap { (plans: List[PayPalPlan]) => - if (plans.size == plansPerPage) getPlans(page + 1).map(plans ::: _) + if plans.size == plansPerPage then getPlans(page + 1).map(plans ::: _) else fuccess(plans) } .map(_.filter(_.active)) diff --git a/modules/plan/src/main/PlanApi.scala b/modules/plan/src/main/PlanApi.scala index b955a59189ba3..5776d807a1b39 100644 --- a/modules/plan/src/main/PlanApi.scala +++ b/modules/plan/src/main/PlanApi.scala @@ -66,7 +66,7 @@ final class PlanApi( def getEvent = stripeClient.getEvent - def onCharge(stripeCharge: StripeCharge): Funit = for { + def onCharge(stripeCharge: StripeCharge): Funit = for patronOption <- customerIdPatron(stripeCharge.customer) giftTo <- stripeCharge.giftTo so userRepo.byId money = stripeCharge.amount toMoney stripeCharge.currency @@ -93,7 +93,7 @@ final class PlanApi( case Some(to) => gift(user, to, money) case None => stripeClient.getCustomer(stripeCharge.customer) flatMap { customer => - val freq = if (customer.exists(_.renew)) Freq.Monthly else Freq.Onetime + val freq = if customer.exists(_.renew) then Freq.Monthly else Freq.Onetime val patron = prevPatron .copy(lastLevelUp = prevPatron.lastLevelUp orElse nowInstant.some) .levelUpIfPossible @@ -104,11 +104,11 @@ final class PlanApi( } } } - } yield () + yield () def onSubscriptionDeleted(sub: StripeSubscription): Funit = customerIdPatron(sub.customer) flatMapz { patron => - if (patron.isLifetime) funit + if patron.isLifetime then funit else userRepo byId patron.userId orFail s"Missing user for $patron" flatMap { user => setDbUserPlan(user.mapPlan(_.disable)) >> @@ -175,7 +175,7 @@ final class PlanApi( } def canUse(ip: IpAddress, freq: Freq)(using me: Me): Fu[StripeCanUse] = ip2proxy(ip) flatMap { proxy => - if (!proxy.is) fuccess(StripeCanUse.Yes) + if !proxy.is then fuccess(StripeCanUse.Yes) else val maxPerWeek = { val verifiedBonus = me.isVerified so 50 @@ -209,17 +209,17 @@ final class PlanApi( def getEvent = payPalClient.getEvent - def onLegacyCharge(ipn: PlanForm.Ipn, ip: IpAddress, key: String): Funit = for { + def onLegacyCharge(ipn: PlanForm.Ipn, ip: IpAddress, key: String): Funit = for money <- ipn.money.fold[Fu[Money]](fufail(s"Invalid paypal charge ${ipn.txnId}"))(fuccess) pricing <- pricingApi pricingFor money.currency orFail s"Invalid paypal currency $money" usd <- currencyApi toUsd money orFail s"Invalid paypal currency $money" isLifetime <- pricingApi isLifetime money giftTo <- ipn.giftTo so userRepo.byId _ <- - if (key != payPalIpnKey.value) + if key != payPalIpnKey.value then logger.error(s"Invalid PayPal IPN key $key from $ip ${ipn.userId} $money") funit - else if (!pricing.valid(money)) + else if !pricing.valid(money) then logger.info(s"Ignoring invalid paypal amount from $ip ${ipn.userId} $money ${ipn.txnId}") funit else @@ -273,7 +273,7 @@ final class PlanApi( isLifetime so setLifetime(user) } >>- logger.info(s"Charged ${user.username} with paypal: $money") } - } yield () + yield () def userSubscriptionId(user: User): Fu[Option[PayPalSubscriptionId]] = userPatron(user) map { @@ -284,15 +284,15 @@ final class PlanApi( userSubscriptionId(user) flatMapz payPalClient.getSubscription def createOrder(checkout: PlanCheckout, user: User, giftTo: Option[lila.user.User]) = - for { + for isLifetime <- pricingApi.isLifetime(checkout.money) order <- payPalClient.createOrder(CreatePayPalOrder(checkout, user, giftTo, isLifetime)) - } yield order + yield order def createSubscription(checkout: PlanCheckout, user: User) = payPalClient.createSubscription(checkout, user) - def captureOrder(orderId: PayPalOrderId, ip: IpAddress) = for { + def captureOrder(orderId: PayPalOrderId, ip: IpAddress) = for order <- payPalClient.captureOrder(orderId) money <- order.capturedMoney.fold[Fu[Money]](fufail(s"Invalid paypal capture $order"))(fuccess) pricing <- pricingApi pricingFor money.currency orFail s"Invalid paypal currency $money" @@ -300,7 +300,7 @@ final class PlanApi( isLifetime <- pricingApi isLifetime money giftTo <- order.giftTo so userRepo.byId _ <- - if (!pricing.valid(money)) + if !pricing.valid(money) then logger.info(s"Ignoring invalid paypal amount from $ip ${order.userId} $money ${orderId}") funit else @@ -341,7 +341,7 @@ final class PlanApi( isLifetime so setLifetime(user) } >>- logger.info(s"Charged ${user.username} with paypal: $money") } - } yield () + yield () def captureSubscription( orderId: PayPalOrderId, @@ -355,7 +355,7 @@ final class PlanApi( pricing <- pricingApi pricingFor money.currency orFail s"Invalid paypal currency $money" usd <- currencyApi toUsd money orFail s"Invalid paypal currency $money" _ <- - if (!pricing.valid(money)) + if !pricing.valid(money) then logger.info(s"Ignoring invalid paypal amount from $ip ${order.userId} $money $orderId") funit else @@ -425,7 +425,7 @@ final class PlanApi( end payPal private def setDbUserPlanOnCharge(from: User, levelUp: Boolean): Funit = - val user = from.mapPlan(p => if (levelUp) p.incMonths else p.enable) + val user = from.mapPlan(p => if levelUp then p.incMonths else p.enable) notifier.onCharge(user) setDbUserPlan(user) @@ -466,7 +466,7 @@ final class PlanApi( } case (_, _, Some(_)) => - if (!user.plan.active) + if !user.plan.active then logger.warn(s"${user.username} sync: enable plan of customer with paypal") setDbUserPlan(user.mapPlan(_.enable)) inject ReloadUser else fuccess(Synced(patron.some, none, none)) @@ -486,7 +486,7 @@ final class PlanApi( } def setLifetime(user: User): Funit = - if (user.plan.isEmpty) Bus.publish(lila.hub.actorApi.plan.MonthInc(user.id, 0), "plan") + if user.plan.isEmpty then Bus.publish(lila.hub.actorApi.plan.MonthInc(user.id, 0), "plan") userRepo.setPlan( user, user.plan.enable @@ -517,7 +517,7 @@ final class PlanApi( .void >> setDbUserPlanOnCharge(user, levelUp = false) def gift(from: User, to: User, money: Money): Funit = - for { + for toPatronOpt <- userPatron(to) isLifetime <- fuccess(toPatronOpt.exists(_.isLifetime)) >>| (pricingApi isLifetime money) _ <- mongo.patron.update @@ -531,9 +531,9 @@ final class PlanApi( ), upsert = true ) - newTo = to.mapPlan(p => if (toPatronOpt.exists(_.canLevelUp)) p.incMonths else p.enable) + newTo = to.mapPlan(p => if toPatronOpt.exists(_.canLevelUp) then p.incMonths else p.enable) _ <- setDbUserPlan(newTo) - } yield notifier.onGift(from, newTo, isLifetime) + yield notifier.onGift(from, newTo, isLifetime) def recentGiftFrom(from: User): Fu[Option[Patron]] = mongo.patron @@ -655,9 +655,9 @@ final class PlanApi( lila.mon.plan.goal.update(m.goal.cents) lila.mon.plan.current.update(m.current.cents) lila.mon.plan.percent.update(m.percent) - if (charge.isPayPalLegacy) lila.mon.plan.paypalLegacy.amount.record(charge.usd.cents) - else if (charge.isPayPalCheckout) lila.mon.plan.paypalCheckout.amount.record(charge.usd.cents) - else if (charge.isStripe) lila.mon.plan.stripe.record(charge.usd.cents) + if charge.isPayPalLegacy then lila.mon.plan.paypalLegacy.amount.record(charge.usd.cents) + else if charge.isPayPalCheckout then lila.mon.plan.paypalCheckout.amount.record(charge.usd.cents) + else if charge.isStripe then lila.mon.plan.stripe.record(charge.usd.cents) }.void private def setDbUserPlan(user: User): Funit = diff --git a/modules/plan/src/main/PlanCheckout.scala b/modules/plan/src/main/PlanCheckout.scala index 3f6a6cf4facd5..e4453a39814bd 100644 --- a/modules/plan/src/main/PlanCheckout.scala +++ b/modules/plan/src/main/PlanCheckout.scala @@ -12,7 +12,7 @@ case class PlanCheckout( giftTo: Option[UserStr] ): def fixFreq = copy( - freq = if (giftTo.isDefined) Freq.Onetime else freq + freq = if giftTo.isDefined then Freq.Onetime else freq ) private object PlanCheckout: @@ -29,7 +29,7 @@ final class PlanCheckoutForm(lightUserApi: lila.user.LightUserApi): PlanCheckout( email, Money(amount, currency), - if (freq == "monthly") Freq.Monthly else Freq.Onetime, + if freq == "monthly" then Freq.Monthly else Freq.Onetime, giftTo = giftTo ) diff --git a/modules/plan/src/main/PlanNotifier.scala b/modules/plan/src/main/PlanNotifier.scala index 5ebc0845a2bb8..a25a55a9b01df 100644 --- a/modules/plan/src/main/PlanNotifier.scala +++ b/modules/plan/src/main/PlanNotifier.scala @@ -16,7 +16,7 @@ final private[plan] class PlanNotifier( def onCharge(user: User) = Bus.publish(lila.hub.actorApi.plan.MonthInc(user.id, user.plan.months), "plan") - if (user.plan.months > 1) onRenew(user) else onStart(user) + if user.plan.months > 1 then onRenew(user) else onStart(user) private def onStart(user: User): Unit = system.scheduler.scheduleOnce(5 seconds) { diff --git a/modules/plan/src/main/PlanPricingApi.scala b/modules/plan/src/main/PlanPricingApi.scala index e2ea2568de564..370747fce57c0 100644 --- a/modules/plan/src/main/PlanPricingApi.scala +++ b/modules/plan/src/main/PlanPricingApi.scala @@ -32,16 +32,16 @@ final class PlanPricingApi(currencyApi: CurrencyApi)(using Executor): ) def pricingFor(currency: Currency): Fu[Option[PlanPricing]] = - if (currency == USD) fuccess(usdPricing.some) - else if (currency == EUR) fuccess(eurPricing.some) + if currency == USD then fuccess(usdPricing.some) + else if currency == EUR then fuccess(eurPricing.some) else - for { + for allSuggestions <- usdPricing.suggestions.map(convertAndRound(_, currency)).parallel.map(_.sequence) suggestions = allSuggestions.map(_.distinct) min <- convertAndRound(usdPricing.min, currency) max <- convertAndRound(usdPricing.max, currency) lifetime <- convertAndRound(usdPricing.lifetime, currency) - } yield (suggestions, min, max, lifetime).mapN(PlanPricing.apply) + yield (suggestions, min, max, lifetime).mapN(PlanPricing.apply) def pricingOrDefault(currency: Currency): Fu[PlanPricing] = pricingFor(currency).dmap(_ | usdPricing) @@ -60,7 +60,7 @@ object PlanPricingApi: def nicelyRound(amount: BigDecimal): BigDecimal = { val double = amount.toDouble val scale = math.floor(math.log10(double)); - val fraction = if (scale > 1) 2d else 1d + val fraction = if scale > 1 then 2d else 1d math.round(double * fraction * math.pow(10, -scale)) / fraction / math.pow(10, -scale) } atLeast 1 diff --git a/modules/plan/src/main/PlanWebhook.scala b/modules/plan/src/main/PlanWebhook.scala index 02cd54685f5c5..36b8d0447cd8f 100644 --- a/modules/plan/src/main/PlanWebhook.scala +++ b/modules/plan/src/main/PlanWebhook.scala @@ -51,10 +51,10 @@ final class PlanWebhook(api: PlanApi)(using Executor): Json .fromJson[PayPalCapture](event.resource) .fold( - _ => { + _ => log.error(s"Unreadable PayPalCapture ${Json stringify event.resource take 2000}") funit - }, + , capture => fuccess { api.payPal.onCaptureCompleted(capture) @@ -64,10 +64,10 @@ final class PlanWebhook(api: PlanApi)(using Executor): Json .fromJson[PayPalSale](event.resource) .fold( - _ => { + _ => log.error(s"Unreadable PayPalSale ${Json stringify event.resource take 2000}") funit - }, + , sale => fuccess { api.payPal.onCaptureCompleted(sale.toCapture) diff --git a/modules/plan/src/main/StripeClient.scala b/modules/plan/src/main/StripeClient.scala index 48f9d017225eb..3852b414fb557 100644 --- a/modules/plan/src/main/StripeClient.scala +++ b/modules/plan/src/main/StripeClient.scala @@ -35,7 +35,7 @@ final private class StripeClient(ws: StandaloneWSClient, config: StripeClient.Co val args = sessionArgs(StripeMode.payment, data, data.urls) ::: List( "line_items[0][price_data][product]" -> { - if (data.giftTo.isDefined) config.products.gift + if data.giftTo.isDefined then config.products.gift else config.products.onetime }, "line_items[0][price_data][currency]" -> data.checkout.money.currency, @@ -172,7 +172,7 @@ final private class StripeClient(ws: StandaloneWSClient, config: StripeClient.Co (summon[Reads[A]] reads res.body[JsValue]).fold( errs => fufail { - if (isDeleted(res.body[JsValue])) + if isDeleted(res.body[JsValue]) then new DeletedException(s"[stripe] Upstream resource was deleted: ${res.body}") else new Exception(s"[stripe] Can't parse ${res.body} --- $errs") }, diff --git a/modules/plan/src/main/model.scala b/modules/plan/src/main/model.scala index be8136967db7e..117d66d3856ec 100644 --- a/modules/plan/src/main/model.scala +++ b/modules/plan/src/main/model.scala @@ -53,12 +53,13 @@ object StripeAmount extends OpaqueInt[lila.plan.StripeAmount]: extension (e: StripeAmount) def toMoney(currency: Currency) = Money( - if (CurrencyApi zeroDecimalCurrencies currency) e + if CurrencyApi zeroDecimalCurrencies currency then e else BigDecimal(e) / 100, currency ) def apply(money: Money): StripeAmount = StripeAmount { - if (CurrencyApi.zeroDecimalCurrencies(money.currency)) money.amount.toInt else (money.amount * 100).toInt + if CurrencyApi.zeroDecimalCurrencies(money.currency) then money.amount.toInt + else (money.amount * 100).toInt } case class StripeSubscriptions(data: List[StripeSubscription]) @@ -148,7 +149,7 @@ case class StripeCompletedSession( amount_total: StripeAmount, currency: Currency ): - def freq = if (mode == "subscription") Freq.Monthly else Freq.Onetime + def freq = if mode == "subscription" then Freq.Monthly else Freq.Onetime def money = amount_total toMoney currency def giftTo: Option[UserId] = UserId.from(metadata get "giftTo") @@ -220,11 +221,11 @@ case class PayPalPlanId(value: String) extends AnyVal with StringValue case class PayPalPlan(id: PayPalPlanId, name: String, status: String, billing_cycles: JsArray): import JsonHandlers.payPal.given def active = status == "ACTIVE" - val currency = for { + val currency = for cycle <- billing_cycles.value.headOption pricing <- cycle obj "pricing_scheme" price <- pricing.get[PayPalAmount]("fixed_price") - } yield price.money.currency + yield price.money.currency case class PayPalTransactionId(value: String) extends AnyVal with StringValue case class PayPalCapture( id: PayPalTransactionId, diff --git a/modules/plan/src/test/PlanPricingTest.scala b/modules/plan/src/test/PlanPricingTest.scala index f040ce30fbc26..25d598ed17912 100644 --- a/modules/plan/src/test/PlanPricingTest.scala +++ b/modules/plan/src/test/PlanPricingTest.scala @@ -1,6 +1,6 @@ package lila.plan -class PlanPricingTest extends munit.FunSuite { +class PlanPricingTest extends munit.FunSuite: import PlanPricingApi.nicelyRound @@ -31,5 +31,3 @@ class PlanPricingTest extends munit.FunSuite { assertEquals(nicelyRound(77), BigDecimal(80)) assertEquals(nicelyRound(1009), BigDecimal(1000)) } - -} diff --git a/modules/playban/src/main/PlaybanApi.scala b/modules/playban/src/main/PlaybanApi.scala index 55377332696af..8086b472af63e 100644 --- a/modules/playban/src/main/PlaybanApi.scala +++ b/modules/playban/src/main/PlaybanApi.scala @@ -31,7 +31,7 @@ final class PlaybanApi( private def blameable(game: Game): Fu[Boolean] = (game.source.exists(blameableSources.contains) && game.hasClock) so { - if (game.rated) fuTrue + if game.rated then fuTrue else !userRepo.containsEngine(game.userIds) } @@ -71,11 +71,11 @@ final class PlaybanApi( // flagged after waiting a long time def sitting: Option[Funit] = - for { + for userId <- game.player(flaggerColor).userId seconds = nowSeconds - game.movedAt.toSeconds if unreasonableTime.exists(seconds >= _) - } yield save(Outcome.Sitting, userId, RageSit.imbalanceInc(game, flaggerColor), game.source) >>- + yield save(Outcome.Sitting, userId, RageSit.imbalanceInc(game, flaggerColor), game.source) >>- feedback.sitting(Pov(game, flaggerColor)) >> propagateSitting(game, userId) @@ -84,11 +84,11 @@ final class PlaybanApi( // assumes game was already checked for sitting def sitMoving: Option[Funit] = game.player(flaggerColor).userId.ifTrue { - ~(for { + ~(for movetimes <- game moveTimes flaggerColor lastMovetime <- movetimes.lastOption limit <- unreasonableTime - } yield lastMovetime.toSeconds >= limit) + yield lastMovetime.toSeconds >= limit) } map { userId => save(Outcome.SitMoving, userId, RageSit.imbalanceInc(game, flaggerColor), game.source) >>- feedback.sitting(Pov(game, flaggerColor)) >> @@ -103,17 +103,17 @@ final class PlaybanApi( private def propagateSitting(game: Game, userId: UserId): Funit = rageSitCache get userId map { rageSit => - if (rageSit.isBad) Bus.publish(SittingDetected(game, userId), "playban") + if rageSit.isBad then Bus.publish(SittingDetected(game, userId), "playban") } def other(game: Game, status: Status.type => Status, winner: Option[Color]): Funit = IfBlameable(game) { - ~(for { + ~(for w <- winner loser = game.player(!w) loserId <- loser.userId - } yield { - if (Status.NoStart is status) + yield + if Status.NoStart is status then save(Outcome.NoPlay, loserId, RageSit.Update.Reset, game.source) >>- feedback.noStart(Pov(game, !w)) else game.clock @@ -134,7 +134,7 @@ final class PlaybanApi( .getOrElse { good(game, !w) } - }) + ) } private def good(game: Game, loserColor: Color): Funit = @@ -198,31 +198,30 @@ final class PlaybanApi( source: Option[Source] ): Funit = { lila.mon.playban.outcome(outcome.key).increment() - for { + for withOutcome <- coll .findAndUpdateSimplified[UserRecord]( selector = $id(userId), update = $doc( $push("o" -> $doc("$each" -> List(outcome), "$slice" -> -30)) ++ { - rsUpdate match { + rsUpdate match case RageSit.Update.Reset => $min("c" -> 0) case RageSit.Update.Inc(v) if v != 0 => $inc("c" -> v) case _ => $empty - } } ), fetchNewObject = true, upsert = true ) orFail s"can't find newly created record for user $userId" withBan <- - if (outcome == Outcome.Good) fuccess(withOutcome) + if outcome == Outcome.Good then fuccess(withOutcome) else - for { + for createdAt <- userRepo.createdAtById(userId) orFail s"Missing user creation date $userId" withBan <- legiferate(withOutcome, createdAt, source) - } yield withBan + yield withBan _ <- registerRageSit(withBan, rsUpdate) - } yield () + yield () }.void logFailure lila.log("playban") private def legiferate(record: UserRecord, accCreatedAt: Instant, source: Option[Source]): Fu[UserRecord] = @@ -261,7 +260,7 @@ final class PlaybanApi( lila.hub.actorApi.mod.AutoWarning(record.userId, MsgPreset.sittingAuto.name), "autoWarning" ) - if (record.rageSit.isLethal && record.banMinutes.exists(_ > 12 * 60)) + if record.rageSit.isLethal && record.banMinutes.exists(_ > 12 * 60) then userRepo .byId(record.userId) .flatMapz { user => diff --git a/modules/playban/src/main/RageSit.scala b/modules/playban/src/main/RageSit.scala index a20d191db44e8..116c41b566b3e 100644 --- a/modules/playban/src/main/RageSit.scala +++ b/modules/playban/src/main/RageSit.scala @@ -17,7 +17,7 @@ object RageSit extends OpaqueInt[RageSit]: def isLethal = a.value <= -200 def goneWeight: Float = - if (!isBad) 1f + if !isBad then 1f else (1 - 0.7 * sqrt(log10(-(a.counter / 10) - 3))).toFloat max 0.1f def counterView = a.counter / 10 @@ -38,10 +38,10 @@ object RageSit extends OpaqueInt[RageSit]: case (a, _) if a <= -4 => -1 case _ => 0 } * { - if (loser.white) 1 else -1 + if loser.white then 1 else -1 } * { - if (game.speed <= Speed.Bullet) 5 - else if (game.speed == Speed.Blitz) 10 + if game.speed <= Speed.Bullet then 5 + else if game.speed == Speed.Blitz then 10 else 15 } } diff --git a/modules/playban/src/main/model.scala b/modules/playban/src/main/model.scala index 2d213b54e779a..079e65a30a37c 100644 --- a/modules/playban/src/main/model.scala +++ b/modules/playban/src/main/model.scala @@ -27,7 +27,7 @@ case class UserRecord( case o if o != Outcome.Good => 1 } sum - def badOutcomeRatio: Float = if (bans.sizeIs < 3) 0.4f else 0.3f + def badOutcomeRatio: Float = if bans.sizeIs < 3 then 0.4f else 0.3f def minBadOutcomes: Int = bans.size match @@ -93,11 +93,10 @@ object TempBan: def make(bans: Vector[TempBan], accountCreationDate: Instant): TempBan = make { (bans.lastOption so { prev => - prev.endsAt.toNow.toHours.toSaturatedInt match { + prev.endsAt.toNow.toHours.toSaturatedInt match case h if h < 72 => prev.mins * (132 - h) / 60 case h => (55.6 * prev.mins / (Math.pow(5.56 * prev.mins - 54.6, h / 720) + 54.6)).toInt - } - } atLeast baseMinutes) * (if (accountCreationDate.plusDays(3).isAfterNow) 2 else 1) + } atLeast baseMinutes) * (if accountCreationDate.plusDays(3).isAfterNow then 2 else 1) } enum Outcome(val id: Int, val name: String): diff --git a/modules/pool/src/main/GameStarter.scala b/modules/pool/src/main/GameStarter.scala index 983dda627af35..828d090f9abd6 100644 --- a/modules/pool/src/main/GameStarter.scala +++ b/modules/pool/src/main/GameStarter.scala @@ -38,10 +38,10 @@ final private class GameStarter( import couple.* import cats.syntax.all.* (perfs.get(p1.userId), perfs.get(p2.userId)).mapN((_, _)) so { (perf1, perf2) => - for { + for p1White <- userRepo.firstGetsWhite(p1.userId, p2.userId) - (whitePerf, blackPerf) = if (p1White) perf1 -> perf2 else perf2 -> perf1 - (whiteMember, blackMember) = if (p1White) p1 -> p2 else p2 -> p1 + (whitePerf, blackPerf) = if p1White then perf1 -> perf2 else perf2 -> perf1 + (whiteMember, blackMember) = if p1White then p1 -> p2 else p2 -> p1 game = makeGame( id, pool, @@ -49,7 +49,7 @@ final private class GameStarter( blackMember.userId -> blackPerf ).start _ <- gameRepo insertDenormalized game - } yield + yield onStart(game.id) Pairing( game, diff --git a/modules/pool/src/main/HookThieve.scala b/modules/pool/src/main/HookThieve.scala index 2811f001dcfc4..c4023db7e2c37 100644 --- a/modules/pool/src/main/HookThieve.scala +++ b/modules/pool/src/main/HookThieve.scala @@ -14,7 +14,7 @@ final private class HookThieve()(using Executor, Scheduler): def stolen(poolHooks: Vector[PoolHook], monId: String) = lila.mon.lobby.pool.thieve.stolen(monId).record(poolHooks.size) - if (poolHooks.nonEmpty) Bus.publish(StolenHookIds(poolHooks.map(_.hookId)), "lobbyActor") + if poolHooks.nonEmpty then Bus.publish(StolenHookIds(poolHooks.map(_.hookId)), "lobbyActor") object HookThieve: diff --git a/modules/pool/src/main/MatchMaking.scala b/modules/pool/src/main/MatchMaking.scala index d0f4579f9e13d..292fb8ea3a1b6 100644 --- a/modules/pool/src/main/MatchMaking.scala +++ b/modules/pool/src/main/MatchMaking.scala @@ -30,8 +30,8 @@ object MatchMaking: // 2500 ~> 166 // 3000 ~> 200 private def ratingToMaxScore(rating: IntRating) = - if (rating < 1000) 130 - else if (rating < 1500) 100 + if rating < 1000 then 130 + else if rating < 1500 then 100 else rating.value / 15 // quality of a potential pairing. Lower is better. @@ -61,7 +61,7 @@ object MatchMaking: // bonus if both players have rating ranges, and they're compatible private def rangeBonus(a: PoolMember, b: PoolMember) = - if (a.ratingRange.exists(_ contains b.rating) && b.ratingRange.exists(_ contains a.rating)) 200 + if a.ratingRange.exists(_ contains b.rating) && b.ratingRange.exists(_ contains a.rating) then 200 else 0 // if players block each other @@ -72,17 +72,17 @@ object MatchMaking: // bonus if the two players both have a bad sit counter // malus (so negative number as bonus) if neither of those are true, meaning that their sit counters are far away (e.g. 0 and -5) private def ragesitBonus(a: PoolMember, b: PoolMember) = - if (a.rageSitCounter >= -2 && b.rageSitCounter >= -2) 30 // good players - else if (a.rageSitCounter <= -12 && b.rageSitCounter <= -12) 60 // very bad players - else if (a.rageSitCounter <= -5 && b.rageSitCounter <= -5) 30 // bad players - else (abs(a.rageSitCounter - b.rageSitCounter) atMost 10) * -20 // match of good and bad player + if a.rageSitCounter >= -2 && b.rageSitCounter >= -2 then 30 // good players + else if a.rageSitCounter <= -12 && b.rageSitCounter <= -12 then 60 // very bad players + else if a.rageSitCounter <= -5 && b.rageSitCounter <= -5 then 30 // bad players + else (abs(a.rageSitCounter - b.rageSitCounter) atMost 10) * -20 // match of good and bad player def apply(members: Vector[PoolMember]): Option[Vector[Couple]] = WMMatching(members.toArray, pairScore).fold( - err => { + err => logger.error("WMMatching", err) none - }, + , pairs => Some { pairs.view.map { case (a, b) => Couple(a, b) } to Vector diff --git a/modules/pool/src/main/PoolActor.scala b/modules/pool/src/main/PoolActor.scala index 632fb35e35951..5529e272c0b85 100644 --- a/modules/pool/src/main/PoolActor.scala +++ b/modules/pool/src/main/PoolActor.scala @@ -41,7 +41,7 @@ final private class PoolActor( members.find(joiner.is) match case None => members = members :+ PoolMember(joiner, rageSit) - if (members.sizeIs >= config.wave.players.value) self ! FullWave + if members.sizeIs >= config.wave.players.value then self ! FullWave case Some(member) if member.ratingRange != joiner.ratingRange => members = members.map { case m if m == member => m withRange joiner.ratingRange @@ -84,7 +84,7 @@ final private class PoolActor( members = members.diff(pairedMembers).map(_.incMisses) - if (pairings.nonEmpty) gameStarter(config, pairings) + if pairings.nonEmpty then gameStarter(config, pairings) monitor.candidates(monId).record(candidates.size) monitor.paired(monId).record(pairedMembers.size) diff --git a/modules/pool/src/main/PoolMember.scala b/modules/pool/src/main/PoolMember.scala index ba46b5ad696c4..2e6a9430949d6 100644 --- a/modules/pool/src/main/PoolMember.scala +++ b/modules/pool/src/main/PoolMember.scala @@ -19,7 +19,7 @@ case class PoolMember( def ratingDiff(other: PoolMember) = IntRatingDiff(Math.abs(rating.value - other.rating.value)) def withRange(r: Option[RatingRange]) = - if (r == ratingRange) this + if r == ratingRange then this else copy(ratingRange = r, misses = 0) def hasRange = ratingRange.isDefined diff --git a/modules/practice/src/main/PracticeApi.scala b/modules/practice/src/main/PracticeApi.scala index 4ef67f82e55d6..549447fc9de8f 100644 --- a/modules/practice/src/main/PracticeApi.scala +++ b/modules/practice/src/main/PracticeApi.scala @@ -79,7 +79,7 @@ final class PracticeApi( def clear() = cache.invalidateUnit() def onSave(study: Study) = get foreach { structure => - if (structure.hasStudy(study.id)) clear() + if structure.hasStudy(study.id) then clear() } object progress: diff --git a/modules/practice/src/main/PracticeGoal.scala b/modules/practice/src/main/PracticeGoal.scala index bfd4bc53f4178..e745fd9bce7c4 100644 --- a/modules/practice/src/main/PracticeGoal.scala +++ b/modules/practice/src/main/PracticeGoal.scala @@ -27,10 +27,10 @@ object PracticeGoal: case DrawInR(movesStr) => movesStr.toIntOption map DrawIn.apply case EqualInR(movesStr) => movesStr.toIntOption map EqualIn.apply case EvalInR(cpStr, movesStr) => - for { + for cp <- cpStr.toIntOption moves <- movesStr.toIntOption - } yield EvalIn(cp, moves) + yield EvalIn(cp, moves) case PromotionR(cpStr) => cpStr.toIntOption map Promotion.apply case _ => none } | Mate // default to mate diff --git a/modules/practice/src/main/UserPractice.scala b/modules/practice/src/main/UserPractice.scala index 7c34c3f902302..7c314e0c599b2 100644 --- a/modules/practice/src/main/UserPractice.scala +++ b/modules/practice/src/main/UserPractice.scala @@ -30,6 +30,6 @@ case class UserStudy( case class Completion(done: Int, total: Int): - def percent = if (total == 0) 0 else done * 100 / total + def percent = if total == 0 then 0 else done * 100 / total def complete = done >= total diff --git a/modules/pref/src/main/Pref.scala b/modules/pref/src/main/Pref.scala index ced4706349cf7..93f6685300b0f 100644 --- a/modules/pref/src/main/Pref.scala +++ b/modules/pref/src/main/Pref.scala @@ -57,7 +57,7 @@ case class Pref( val themeColorLight = "#dbd7d1" val themeColorDark = "#2e2a24" - def themeColor = if (bg == Bg.LIGHT) themeColorLight else themeColorDark + def themeColor = if bg == Bg.LIGHT then themeColorLight else themeColorDark def realSoundSet = SoundSet(soundSet) @@ -90,9 +90,9 @@ case class Pref( SoundSet.allByKey get value map { s => copy(soundSet = s.key) } - case "zen" => copy(zen = if (value == "1") 1 else 0).some - case "voice" => copy(voice = if (value == "1") 1.some else 0.some).some - case "keyboardMove" => copy(keyboardMove = if (value == "1") 1 else 0).some + case "zen" => copy(zen = if value == "1" then 1 else 0).some + case "voice" => copy(voice = if value == "1" then 1.some else 0.some).some + case "keyboardMove" => copy(keyboardMove = if value == "1" then 1 else 0).some case _ => none def animationMillis: Int = @@ -450,7 +450,7 @@ object Pref: if user.createdAt.isAfter(systemByDefaultSince) then Bg.SYSTEM else if user.createdAt.isAfter(darkByDefaultSince) then Bg.DARK else Bg.LIGHT, - agreement = if (user.createdAt isAfter Agreement.changedAt) Agreement.current else 0 + agreement = if user.createdAt isAfter Agreement.changedAt then Agreement.current else 0 ) lazy val default = Pref( diff --git a/modules/pref/src/main/PrefForm.scala b/modules/pref/src/main/PrefForm.scala index ae9b21ff98b80..f9d2f529957f6 100644 --- a/modules/pref/src/main/PrefForm.scala +++ b/modules/pref/src/main/PrefForm.scala @@ -154,12 +154,12 @@ object PrefForm: def apply(pref: Pref): PrefData = PrefData( display = DisplayData( - highlight = if (pref.highlight) 1 else 0, - destination = if (pref.destination) 1 else 0, + highlight = if pref.highlight then 1 else 0, + destination = if pref.destination then 1 else 0, animation = pref.animation, coords = pref.coords, replay = pref.replay, - captured = if (pref.captured) 1 else 0, + captured = if pref.captured then 1 else 0, blindfold = pref.blindfold, zen = pref.zen.some, resizeHandle = pref.resizeHandle.some, @@ -167,7 +167,7 @@ object PrefForm: ), behavior = BehaviorData( moveEvent = pref.moveEvent.some, - premove = if (pref.premove) 1 else 0, + premove = if pref.premove then 1 else 0, takeback = pref.takeback, autoQueen = pref.autoQueen, autoThreefold = pref.autoThreefold, @@ -179,11 +179,11 @@ object PrefForm: ), clock = ClockData( tenths = pref.clockTenths, - bar = if (pref.clockBar) 1 else 0, - sound = if (pref.clockSound) 1 else 0, + bar = if pref.clockBar then 1 else 0, + sound = if pref.clockSound then 1 else 0, moretime = pref.moretime ), - follow = if (pref.follow) 1 else 0, + follow = if pref.follow then 1 else 0, challenge = pref.challenge, message = pref.message, studyInvite = pref.studyInvite.some, diff --git a/modules/push/src/main/Env.scala b/modules/push/src/main/Env.scala index 5aacfb7f7621f..4dd4f2aac057d 100644 --- a/modules/push/src/main/Env.scala +++ b/modules/push/src/main/Env.scala @@ -52,7 +52,7 @@ final class Env( case e: Exception => logger.warn("Failed to create google credentials", e) none - if (googleCredentials.isDefined) logger.info("Firebase push notifications are enabled.") + if googleCredentials.isDefined then logger.info("Firebase push notifications are enabled.") private lazy val firebasePush = wire[FirebasePush] diff --git a/modules/push/src/main/FirebasePush.scala b/modules/push/src/main/FirebasePush.scala index 41642f6d7772b..dc9cdf7dc2a9a 100644 --- a/modules/push/src/main/FirebasePush.scala +++ b/modules/push/src/main/FirebasePush.scala @@ -84,12 +84,12 @@ final private class FirebasePush( ) ) flatMap { res => lila.mon.push.firebaseStatus(res.status).increment() - if (res.status == 200) funit - else if (res.status == 404) + if res.status == 200 then funit + else if res.status == 404 then logger.info(s"Delete missing firebase device $device") deviceApi delete device else - if (errorCounter(res.status)) logger.warn(s"[push] firebase: ${res.status}") + if errorCounter(res.status) then logger.warn(s"[push] firebase: ${res.status}") funit } diff --git a/modules/push/src/main/PushApi.scala b/modules/push/src/main/PushApi.scala index d5d0b22067907..7423e36409e48 100644 --- a/modules/push/src/main/PushApi.scala +++ b/modules/push/src/main/PushApi.scala @@ -37,7 +37,7 @@ final private class PushApi( case _ => funit def finish(game: Game): Funit = - if (!game.isCorrespondence || game.hasAi) funit + if !game.isCorrespondence || game.hasAi then funit else game.userIds .map { userId => @@ -50,11 +50,11 @@ final private class PushApi( _.finish, NotificationPref.GameEvent, PushApi.Data( - title = pov.win match { + title = pov.win match case Some(true) => "You won!" case Some(false) => "You lost." case _ => "It's a draw." - }, + , body = s"Your game with $opponent is over.", stacking = Stacking.GameFinish, urgency = Urgency.VeryLow, @@ -317,7 +317,7 @@ final private class PushApi( "type" -> "tourSoon", "tourId" -> tour.tourId, "tourName" -> tour.tourName, - "path" -> s"/${if (tour.swiss) "swiss" else "tournament"}/${tour.tourId}" + "path" -> s"/${if tour.swiss then "swiss" else "tournament"}/${tour.tourId}" ) ) ) @@ -397,11 +397,11 @@ final private class PushApi( import lila.challenge.Challenge.TimeControl.* List( if c.mode.rated then "Rated" else "Casual", - c.timeControl match { + c.timeControl match case Unlimited => "Unlimited" case Correspondence(d) => s"$d days" case c: Clock => c.show - }, + , c.variant.name ) mkString " • " diff --git a/modules/push/src/main/WebSubscriptionApi.scala b/modules/push/src/main/WebSubscriptionApi.scala index 4d26bb0e5466c..1c38c5064c1a9 100644 --- a/modules/push/src/main/WebSubscriptionApi.scala +++ b/modules/push/src/main/WebSubscriptionApi.scala @@ -40,7 +40,7 @@ final class WebSubscriptionApi(coll: Coll)(using Executor): private[push] def getSubscriptions(userIds: Iterable[UserId], maxPerUser: Int): Fu[List[WebSubscription]] = coll .aggregateList(100_000, _.sec): framework => - import framework._ + import framework.* Match($doc("userId" $in userIds)) -> List( Sort(Descending("seenAt")), GroupField("userId")("subs" -> Push(BSONString("$$ROOT"))), diff --git a/modules/puzzle/src/main/BsonHandlers.scala b/modules/puzzle/src/main/BsonHandlers.scala index f85e9a6c49b92..d34fee30e3d0f 100644 --- a/modules/puzzle/src/main/BsonHandlers.scala +++ b/modules/puzzle/src/main/BsonHandlers.scala @@ -13,7 +13,7 @@ object BsonHandlers: import Puzzle.BSONFields.* private[puzzle] given puzzleReader: BSONDocumentReader[Puzzle] with - def readDocument(r: BSONDocument) = for { + def readDocument(r: BSONDocument) = for id <- r.getAsTry[PuzzleId](id) gameId <- r.getAsTry[GameId](gameId) fen <- r.getAsTry[Fen.Epd](fen) @@ -23,7 +23,7 @@ object BsonHandlers: plays <- r.getAsTry[Int](plays) vote <- r.getAsTry[Float](vote) themes <- r.getAsTry[Set[PuzzleTheme.Key]](themes) - } yield Puzzle( + yield Puzzle( id = id, gameId = gameId, fen = fen, @@ -36,10 +36,9 @@ object BsonHandlers: private[puzzle] given roundIdHandler: BSONHandler[PuzzleRound.Id] = tryHandler[PuzzleRound.Id]( { case BSONString(v) => - v split PuzzleRound.idSep match { + v split PuzzleRound.idSep match case Array(userId, puzzleId) => Success(PuzzleRound.Id(UserId(userId), PuzzleId(puzzleId))) case _ => handlerBadValue(s"Invalid puzzle round id $v") - } }, id => BSONString(id.toString) ) @@ -52,7 +51,7 @@ object BsonHandlers: Success(PuzzleRound.Theme(theme.key, v.head == '+')) } }, - rt => BSONString(s"${if (rt.vote) "+" else "-"}${rt.theme}") + rt => BSONString(s"${if rt.vote then "+" else "-"}${rt.theme}") ) private[puzzle] given roundHandler: BSON[PuzzleRound] with diff --git a/modules/puzzle/src/main/Env.scala b/modules/puzzle/src/main/Env.scala index ebfe67c0032f3..ee92514a6495d 100644 --- a/modules/puzzle/src/main/Env.scala +++ b/modules/puzzle/src/main/Env.scala @@ -88,10 +88,10 @@ final class Env( scheduler.scheduleAtFixedRate(10 minutes, 1 day): () => tagger.addAllMissing unit - if (mode == play.api.Mode.Prod) + if mode == play.api.Mode.Prod then scheduler.scheduleAtFixedRate(1 hour, 1 hour): () => pathApi.isStale.foreach: stale => - if (stale) logger.error("Puzzle paths appear to be stale! check that the regen cron is up") + if stale then logger.error("Puzzle paths appear to be stale! check that the regen cron is up") final class PuzzleColls( val puzzle: AsyncColl, diff --git a/modules/puzzle/src/main/GameJson.scala b/modules/puzzle/src/main/GameJson.scala index 2633d597d700c..cfac44ea51695 100644 --- a/modules/puzzle/src/main/GameJson.scala +++ b/modules/puzzle/src/main/GameJson.scala @@ -16,7 +16,7 @@ final private class GameJson( )(using Executor): def apply(gameId: GameId, plies: Ply, bc: Boolean): Fu[JsObject] = - (if (bc) bcCache else cache) get writeKey(gameId, plies) + (if bc then bcCache else cache) get writeKey(gameId, plies) def noCache(game: Game, plies: Ply): Fu[JsObject] = lightUserApi preloadMany game.userIds inject generate(game, plies) @@ -47,7 +47,7 @@ final private class GameJson( private def generate(gameId: GameId, plies: Ply, bc: Boolean): Fu[JsObject] = gameRepo gameFromSecondary gameId orFail s"Missing puzzle game $gameId!" flatMap { game => lightUserApi preloadMany game.userIds map { _ => - if (bc) generateBc(game, plies) + if bc then generateBc(game, plies) else generate(game, plies) } } diff --git a/modules/puzzle/src/main/Puzzle.scala b/modules/puzzle/src/main/Puzzle.scala index 0707f458e9fde..ebb6e36303b79 100644 --- a/modules/puzzle/src/main/Puzzle.scala +++ b/modules/puzzle/src/main/Puzzle.scala @@ -63,13 +63,13 @@ object Puzzle: private def charToInt(c: Char) = val i = c.toInt - if (i > 96) i - 71 - else if (i > 64) i - 65 + if i > 96 then i - 71 + else if i > 64 then i - 65 else i + 4 private def intToChar(i: Int): Char = { - if (i < 26) i + 65 - else if (i < 52) i + 71 + if i < 26 then i + 65 + else if i < 52 then i + 71 else i - 4 }.toChar diff --git a/modules/puzzle/src/main/PuzzleAnon.scala b/modules/puzzle/src/main/PuzzleAnon.scala index 581b26054abf7..45f701bdbb055 100644 --- a/modules/puzzle/src/main/PuzzleAnon.scala +++ b/modules/puzzle/src/main/PuzzleAnon.scala @@ -26,7 +26,7 @@ final class PuzzleAnon( private def selectWithColor(color: Color)(puzzles: Vector[Puzzle]): Option[Puzzle] = def nextTry(attempts: Int): Option[Puzzle] = - if (attempts < 10) + if attempts < 10 then ThreadLocalRandom oneOf puzzles filter (_.color == color) orElse nextTry(attempts + 1) else ThreadLocalRandom oneOf puzzles.filter(_.color == color) nextTry(1) diff --git a/modules/puzzle/src/main/PuzzleApi.scala b/modules/puzzle/src/main/PuzzleApi.scala index ea00bcfa2b608..d6ffb7ed1de96 100644 --- a/modules/puzzle/src/main/PuzzleApi.scala +++ b/modules/puzzle/src/main/PuzzleApi.scala @@ -68,7 +68,7 @@ final class PuzzleApi( .find(user, id) .flatMapz { prevRound => trustApi.vote(user, prevRound, vote) flatMapz { weight => - val voteValue = (if (vote) 1 else -1) * weight + val voteValue = (if vote then 1 else -1) * weight lila.mon.puzzle.vote.count(vote, prevRound.win.yes).increment() updatePuzzle(id, voteValue, prevRound.vote) zip colls.round { @@ -107,10 +107,10 @@ final class PuzzleApi( } } - def angles: Fu[PuzzleAngle.All] = for { + def angles: Fu[PuzzleAngle.All] = for themes <- theme.categorizedWithCount openings <- openingApi.collection - } yield PuzzleAngle.All(themes, openings) + yield PuzzleAngle.All(themes, openings) object theme: @@ -128,7 +128,7 @@ final class PuzzleApi( round.themeVote(theme, vote) so { newThemes => import PuzzleRound.{ BSONFields as F } val update = - if (newThemes.isEmpty || !PuzzleRound.themesLookSane(newThemes)) + if newThemes.isEmpty || !PuzzleRound.themesLookSane(newThemes) then fuccess($unset(F.themes, F.puzzle).some) else vote match diff --git a/modules/puzzle/src/main/PuzzleCount.scala b/modules/puzzle/src/main/PuzzleCount.scala index 95f2606767c5d..8f725c43efc4f 100644 --- a/modules/puzzle/src/main/PuzzleCount.scala +++ b/modules/puzzle/src/main/PuzzleCount.scala @@ -33,10 +33,10 @@ final private class PuzzleCountApi( ) }.map { _.flatMap { obj => - for { + for key <- obj string "_id" count <- obj int "nb" - } yield PuzzleTheme.Key(key) -> count + yield PuzzleTheme.Key(key) -> count }.toMap }.flatMap { themed => colls.puzzle(_.countAll) map { all => diff --git a/modules/puzzle/src/main/PuzzleFinisher.scala b/modules/puzzle/src/main/PuzzleFinisher.scala index 57ac9c0900210..a05226689506a 100644 --- a/modules/puzzle/src/main/PuzzleFinisher.scala +++ b/modules/puzzle/src/main/PuzzleFinisher.scala @@ -181,23 +181,21 @@ final private[puzzle] class PuzzleFinisher( private def weightOf(angle: PuzzleAngle, win: PuzzleWin) = angle.asTheme.fold(1f) { theme => - if (theme == PuzzleTheme.mix.key) 1 - else if (isObvious(theme)) - if (win.yes) 0.2f else 0.6f - else if (isHinting(theme)) - if (win.yes) 0.3f else 0.7f - else if (win.yes) 0.7f + if theme == PuzzleTheme.mix.key then 1 + else if isObvious(theme) then if win.yes then 0.2f else 0.6f + else if isHinting(theme) then if win.yes then 0.3f else 0.7f + else if win.yes then 0.7f else 0.8f } def player(angle: PuzzleAngle, win: PuzzleWin, glicko: (Glicko, Glicko), puzzle: Glicko) = val provisionalPuzzle = puzzle.provisional.yes so { - if (win.yes) -0.2f else -0.7f + if win.yes then -0.2f else -0.7f } glicko._1.average(glicko._2, (weightOf(angle, win) + provisionalPuzzle) atLeast 0.1f) def puzzle(angle: PuzzleAngle, win: PuzzleWin, glicko: (Glicko, Glicko), player: Glicko) = - if (player.clueless) glicko._1 + if player.clueless then glicko._1 else glicko._1.average(glicko._2, weightOf(angle, win)) private val VOLATILITY = Glicko.default.volatility diff --git a/modules/puzzle/src/main/PuzzleOpening.scala b/modules/puzzle/src/main/PuzzleOpening.scala index 3780149a4a9e9..ace25e157f0fd 100644 --- a/modules/puzzle/src/main/PuzzleOpening.scala +++ b/modules/puzzle/src/main/PuzzleOpening.scala @@ -28,7 +28,7 @@ case class PuzzleOpeningCollection( op.opening.ref.variation.isDefined so Set(op) ).some case Some((famCount, ops)) => - (famCount, if (op.opening.ref.variation.isDefined) ops incl op else ops).some + (famCount, if op.opening.ref.variation.isDefined then ops incl op else ops).some } } val treePopular: TreeList = treeMap.toList diff --git a/modules/puzzle/src/main/PuzzleReplay.scala b/modules/puzzle/src/main/PuzzleReplay.scala index b65b37f29ac55..154ba8489ccfd 100644 --- a/modules/puzzle/src/main/PuzzleReplay.scala +++ b/modules/puzzle/src/main/PuzzleReplay.scala @@ -38,7 +38,7 @@ final class PuzzleReplayApi( ): Fu[Option[(Puzzle, PuzzleReplay)]] = maybeDays map { days => replays.getFuture(user.id, _ => createReplayFor(user, days, theme)) flatMap { current => - if (current.days == days && current.theme == theme && current.remaining.nonEmpty) fuccess(current) + if current.days == days && current.theme == theme && current.remaining.nonEmpty then fuccess(current) else createReplayFor(user, days, theme) tap { replays.put(user.id, _) } } flatMap { replay => replay.remaining.headOption so { id => @@ -51,8 +51,7 @@ final class PuzzleReplayApi( angle.asTheme so { theme => replays.getIfPresent(round.userId) so { _ map { replay => - if (replay.days == days && replay.theme == theme) - replays.put(round.userId, fuccess(replay.step)) + if replay.days == days && replay.theme == theme then replays.put(round.userId, fuccess(replay.step)) } } } @@ -83,7 +82,7 @@ final class PuzzleReplayApi( $doc( "$match" -> $doc( $expr { - if (theme == PuzzleTheme.mix.key) $doc("$eq" -> $arr("$_id", "$$pid")) + if theme == PuzzleTheme.mix.key then $doc("$eq" -> $arr("$_id", "$$pid")) else $doc( $and( diff --git a/modules/puzzle/src/main/PuzzleSelector.scala b/modules/puzzle/src/main/PuzzleSelector.scala index 57931d48b71cc..c8fa839f974dc 100644 --- a/modules/puzzle/src/main/PuzzleSelector.scala +++ b/modules/puzzle/src/main/PuzzleSelector.scala @@ -122,8 +122,9 @@ final class PuzzleSelector( .getAsOpt[List[Puzzle]]("puzzle") .flatMap(_.headOption) .fold[NextPuzzleResult](PuzzleMissing(puzzleId)): puzzle => - if (session.settings.color.exists(puzzle.color !=)) WrongColor(puzzle) - else if (doc.getAsOpt[List[Bdoc]]("round").exists(_.nonEmpty)) PuzzleAlreadyPlayed(puzzle) + if session.settings.color.exists(puzzle.color !=) then WrongColor(puzzle) + else if doc.getAsOpt[List[Bdoc]]("round").exists(_.nonEmpty) then + PuzzleAlreadyPlayed(puzzle) else PuzzleFound(puzzle) .monValue: result => _.puzzle.selector.nextPuzzleResult( diff --git a/modules/puzzle/src/main/PuzzleSession.scala b/modules/puzzle/src/main/PuzzleSession.scala index aa55553f50003..5b31535c4b6fc 100644 --- a/modules/puzzle/src/main/PuzzleSession.scala +++ b/modules/puzzle/src/main/PuzzleSession.scala @@ -46,8 +46,7 @@ final class PuzzleSessionApi(pathApi: PuzzlePathApi, cacheApi: CacheApi)(using E _ map { session => // yes, even if the completed puzzle was not the current session puzzle // in that case we just skip a puzzle on the path, which doesn't matter - if (session.path.angle == angle) - sessions.put(round.userId, fuccess(session.next)) + if session.path.angle == angle then sessions.put(round.userId, fuccess(session.next)) } } diff --git a/modules/puzzle/src/main/PuzzleStreak.scala b/modules/puzzle/src/main/PuzzleStreak.scala index 8c92c2b5b2c01..d6b992d6473f8 100644 --- a/modules/puzzle/src/main/PuzzleStreak.scala +++ b/modules/puzzle/src/main/PuzzleStreak.scala @@ -44,7 +44,7 @@ final class PuzzleStreakApi(colls: PuzzleColls, cacheApi: CacheApi)(using Execut Facet( buckets.map { case (rating, nbPuzzles) => val (tier, samples, deviation) = - if (rating > 2300) (PuzzleTier.good, 5, 110) else (PuzzleTier.top, 1, 85) + if rating > 2300 then (PuzzleTier.good, 5, 110) else (PuzzleTier.top, 1, 85) rating.toString -> List( Match( $doc( @@ -95,9 +95,8 @@ final class PuzzleStreakApi(colls: PuzzleColls, cacheApi: CacheApi)(using Execut private def monitor(puzzles: List[Puzzle]): Unit = val nb = puzzles.size lila.mon.streak.selector.count.record(nb) - if (nb < poolSize * 0.9) - logger.warn(s"Streak selector wanted $poolSize puzzles, only got $nb") - if (nb > 1) + if nb < poolSize * 0.9 then logger.warn(s"Streak selector wanted $poolSize puzzles, only got $nb") + if nb > 1 then val rest = puzzles.toVector drop 1 lila.common.Maths.mean(rest.map(_.glicko.intRating.value)) foreach { r => lila.mon.streak.selector.rating.record(r.toInt).unit diff --git a/modules/puzzle/src/main/PuzzleTier.scala b/modules/puzzle/src/main/PuzzleTier.scala index 1b498cfd5daec..690436decc9d2 100644 --- a/modules/puzzle/src/main/PuzzleTier.scala +++ b/modules/puzzle/src/main/PuzzleTier.scala @@ -8,11 +8,11 @@ enum PuzzleTier: object PuzzleTier: def stepDown(tier: PuzzleTier): Option[PuzzleTier] = - if (tier == top) good.some - else if (tier == good) all.some + if tier == top then good.some + else if tier == good then all.some else none def from(tier: String) = - if (tier == top.toString) top - else if (tier == good.toString) good + if tier == top.toString then top + else if tier == good.toString then good else all diff --git a/modules/puzzle/src/main/PuzzleTrust.scala b/modules/puzzle/src/main/PuzzleTrust.scala index b6734eb2c8ddb..05f02eb357077 100644 --- a/modules/puzzle/src/main/PuzzleTrust.scala +++ b/modules/puzzle/src/main/PuzzleTrust.scala @@ -11,7 +11,7 @@ final private class PuzzleTrustApi(colls: PuzzleColls, perfsRepo: UserPerfsRepo) .flatMap: user => val w = base(user) + { // more trust when vote != win - if (vote == round.win.value) -2 else 2 + if vote == round.win.value then -2 else 2 } // distrust provisional ratings and distant ratings (w > 0) @@ -63,10 +63,10 @@ final private class PuzzleTrustApi(colls: PuzzleColls, perfsRepo: UserPerfsRepo) private def patronBonus(user: User) = (~user.planMonths * 5) atMost 15 private def modBonus(user: User) = - if (user.roles.exists(_ contains "ROLE_PUZZLE_CURATOR")) 100 - else if (user.isAdmin) 50 - else if (user.isVerified) 30 + if user.roles.exists(_ contains "ROLE_PUZZLE_CURATOR") then 100 + else if user.isAdmin then 50 + else if user.isVerified then 30 else 0 private def lameBonus(user: User) = - if (user.lameOrTroll) -30 else 0 + if user.lameOrTroll then -30 else 0 diff --git a/modules/racer/src/main/RacerApi.scala b/modules/racer/src/main/RacerApi.scala index c1373e58ff3c9..ab1f55019c782 100644 --- a/modules/racer/src/main/RacerApi.scala +++ b/modules/racer/src/main/RacerApi.scala @@ -72,14 +72,13 @@ final class RacerApi( def makePlayer(id: RacerPlayer.Id) = RacerPlayer.make(id, RacerPlayer.Id.userIdOf(id).map(lightUser)) - def join(id: RacerRace.Id, playerId: RacerPlayer.Id): Option[RacerRace] = { + def join(id: RacerRace.Id, playerId: RacerPlayer.Id): Option[RacerRace] = val player = makePlayer(playerId) get(id).flatMap(_ join player) map { r => val race = (r.isLobby so doStart(r)) | r saveAndPublish(race) race } - } private[racer] def manualStart(race: RacerRace): Unit = !race.isLobby so { doStart(race) foreach saveAndPublish @@ -107,7 +106,7 @@ final class RacerApi( } def registerPlayerScore(id: RacerRace.Id, player: RacerPlayer.Id, score: Int): Unit = - if (score > 160) logger.warn(s"$id $player score: $score") + if score > 160 then logger.warn(s"$id $player score: $score") else get(id).flatMap(_.registerScore(player, score)) foreach saveAndPublish private def save(race: RacerRace): Unit = @@ -121,4 +120,4 @@ final class RacerApi( // work around circular dependency private var socket: Option[RacerSocket] = None - private[racer] def registerSocket(s: RacerSocket) = { socket = s.some } + private[racer] def registerSocket(s: RacerSocket) = socket = s.some diff --git a/modules/racer/src/main/RacerBsonHandlers.scala b/modules/racer/src/main/RacerBsonHandlers.scala index 298a895a8657d..859056aea6b41 100644 --- a/modules/racer/src/main/RacerBsonHandlers.scala +++ b/modules/racer/src/main/RacerBsonHandlers.scala @@ -10,11 +10,11 @@ import lila.storm.StormPuzzle private object RacerBsonHandlers: given BSONDocumentReader[StormPuzzle] with - def readDocument(r: BSONDocument) = for { + def readDocument(r: BSONDocument) = for id <- r.getAsTry[PuzzleId]("_id") fen <- r.getAsTry[Fen.Epd]("fen") lineStr <- r.getAsTry[String]("line") line <- lineStr.split(' ').toList.flatMap(Uci.Move.apply).toNel.toTry("Empty move list?!") glicko <- r.getAsTry[Bdoc]("glicko") rating <- glicko.getAsTry[Double]("r") - } yield StormPuzzle(id, fen, line, IntRating(rating.toInt)) + yield StormPuzzle(id, fen, line, IntRating(rating.toInt)) diff --git a/modules/racer/src/main/RacerPlayer.scala b/modules/racer/src/main/RacerPlayer.scala index e8f2e841552f3..105f105abb86f 100644 --- a/modules/racer/src/main/RacerPlayer.scala +++ b/modules/racer/src/main/RacerPlayer.scala @@ -18,7 +18,7 @@ object RacerPlayer: case Anon(sessionId: String) object Id: def apply(str: String) = - if (str startsWith "@") Anon(str drop 1) + if str startsWith "@" then Anon(str drop 1) else User(UserId(str)) def userIdOf(id: Id) = id match case User(uid) => uid.some diff --git a/modules/racer/src/main/RacerRace.scala b/modules/racer/src/main/RacerRace.scala index b3ee851db442c..6fa1682ac504d 100644 --- a/modules/racer/src/main/RacerRace.scala +++ b/modules/racer/src/main/RacerRace.scala @@ -33,7 +33,7 @@ case class RacerRace( ) def startCountdown: Option[RacerRace] = - startsAt.isEmpty && players.size > (if (isLobby) 2 else 1) option + startsAt.isEmpty && players.size > (if isLobby then 2 else 1) option copy(startsAt = nowInstant.plusSeconds(countdownSeconds).some) def startsInMillis = startsAt.map(d => d.toMillis - nowMillis) diff --git a/modules/rating/src/main/Glicko.scala b/modules/rating/src/main/Glicko.scala index 1e7f090486de0..3064c670d8183 100644 --- a/modules/rating/src/main/Glicko.scala +++ b/modules/rating/src/main/Glicko.scala @@ -19,7 +19,7 @@ case class Glicko( def rankable(variant: chess.variant.Variant) = deviation <= { - if (variant.standard) Glicko.standardRankableDeviation + if variant.standard then Glicko.standardRankableDeviation else Glicko.variantRankableDeviation } def provisional = RatingProvisional(deviation >= Glicko.provisionalDeviation) @@ -46,8 +46,8 @@ case class Glicko( ) def average(other: Glicko, weight: Float = 0.5f) = - if (weight >= 1) other - else if (weight <= 0) this + if weight >= 1 then other + else if weight <= 0 then this else Glicko( rating = rating * (1 - weight) + other.rating * weight, diff --git a/modules/rating/src/main/Perf.scala b/modules/rating/src/main/Perf.scala index 7752b41e61c0f..f658e2f1e1a63 100644 --- a/modules/rating/src/main/Perf.scala +++ b/modules/rating/src/main/Perf.scala @@ -59,7 +59,7 @@ case class Perf( ) private def updateRecentWith(glicko: Glicko) = - if (nb < 10) recent + if nb < 10 then recent else (glicko.intRating :: recent) take Perf.recentMaxSize def clearRecent = copy(recent = Nil) diff --git a/modules/rating/src/main/RatingFactor.scala b/modules/rating/src/main/RatingFactor.scala index cddedf37dfeeb..087cc700703e9 100644 --- a/modules/rating/src/main/RatingFactor.scala +++ b/modules/rating/src/main/RatingFactor.scala @@ -20,10 +20,10 @@ object RatingFactor extends OpaqueDouble[RatingFactor]: private def read(s: String): RatingFactors = s.split(separator).toList.map(_.trim.split('=')) flatMap { case Array(ptk, fs) => - for { + for pt <- PerfType(Perf.Key(ptk)) f <- fs.toDoubleOption - } yield pt -> RatingFactor(f) + yield pt -> RatingFactor(f) case _ => None } toMap diff --git a/modules/rating/src/main/RatingRange.scala b/modules/rating/src/main/RatingRange.scala index 44ad596c17fc1..71793c07997de 100644 --- a/modules/rating/src/main/RatingRange.scala +++ b/modules/rating/src/main/RatingRange.scala @@ -29,16 +29,16 @@ object RatingRange: def readRating(str: String) = IntRating from str.toIntOption // ^\d{3,4}\-\d{3,4}$ - def apply(from: String): Option[RatingRange] = for { + def apply(from: String): Option[RatingRange] = for min <- readRating(from.takeWhile('-' !=)) if acceptable(min) max <- readRating(from.dropWhile('-' !=).tail) if acceptable(max) if min < max - } yield RatingRange(min, max) + yield RatingRange(min, max) def apply(rating: IntRating, deltaMin: Option[String], deltaMax: Option[String]): Option[RatingRange] = - for { + for dmin <- deltaMin.flatMap(_.toIntOption) min = rating + dmin if acceptable(min) @@ -46,14 +46,14 @@ object RatingRange: max = rating + dmax if acceptable(max) if min < max - } yield RatingRange(min, max) + yield RatingRange(min, max) def orDefault(from: String) = apply(from) | default def orDefault(rating: Option[IntRating], deltaMin: Option[String], deltaMax: Option[String]) = rating.flatMap(r => apply(r, deltaMin, deltaMax)) | default def noneIfDefault(from: String) = - if (from == default.toString) none + if from == default.toString then none else apply(from).filter(_ != default) def valid(from: String) = apply(from).isDefined diff --git a/modules/rating/src/main/RatingRegulator.scala b/modules/rating/src/main/RatingRegulator.scala index 58cdf7e324ffa..d1f53c97c550c 100644 --- a/modules/rating/src/main/RatingRegulator.scala +++ b/modules/rating/src/main/RatingRegulator.scala @@ -8,10 +8,10 @@ object RatingRegulator: } private def apply(factor: RatingFactor, perfType: PerfType, before: Perf, after: Perf): Perf = - if ({ + if { (after.nb == before.nb + 1) && // after playing one game (after.glicko.rating > before.glicko.rating) // and gaining rating - }) + } then val diff = after.glicko.rating - before.glicko.rating val extra = diff * (factor.value - 1) lila.mon.rating.regulator.micropoints(perfType.key.value).record((extra * 1000 * 1000).toLong) diff --git a/modules/rating/src/main/glicko2/RatingCalculator.scala b/modules/rating/src/main/glicko2/RatingCalculator.scala index e816d70b731b4..b6062ebc7587b 100644 --- a/modules/rating/src/main/glicko2/RatingCalculator.scala +++ b/modules/rating/src/main/glicko2/RatingCalculator.scala @@ -44,9 +44,9 @@ final class RatingCalculator( val players = results.getParticipants players foreach { player => val elapsedRatingPeriods = if skipDeviationIncrease then 0 else 1 - if (results.getResults(player).sizeIs > 0) { + if results.getResults(player).sizeIs > 0 then calculateNewRating(player, results.getResults(player), elapsedRatingPeriods) - } else { + else { // if a player does not compete during the rating period, then only Step 6 applies. // the player's rating and volatility parameters remain the same but deviation increases player.workingRating = player.getGlicko2Rating @@ -74,9 +74,7 @@ final class RatingCalculator( val interval = java.time.Duration.between(periodEnd, ratingPeriodEndDate) elapsedRatingPeriods = interval.toMillis * ratingPeriodsPerMilli } - if (reverse) { - elapsedRatingPeriods = -elapsedRatingPeriods - } + if reverse then elapsedRatingPeriods = -elapsedRatingPeriods val newRD = calculateNewRD(player.getGlicko2RatingDeviation, player.volatility, elapsedRatingPeriods) convertRatingDeviationToOriginalGlickoScale(newRD) @@ -96,16 +94,14 @@ final class RatingCalculator( // step 5.2 - set the initial values of the iterative algorithm to come in step 5.4 var A: Double = a var B: Double = 0 - if (Math.pow(delta, 2) > Math.pow(phi, 2) + v) { - B = Math.log(Math.pow(delta, 2) - Math.pow(phi, 2) - v) - } else { + if Math.pow(delta, 2) > Math.pow(phi, 2) + v then B = Math.log(Math.pow(delta, 2) - Math.pow(phi, 2) - v) + else { var k = 1d B = a - (k * Math.abs(tau)) - while (f(B, delta, phi, v, a, tau) < 0) { + while f(B, delta, phi, v, a, tau) < 0 do k = k + 1 B = a - (k * Math.abs(tau)) - } } // step 5.3 @@ -114,28 +110,24 @@ final class RatingCalculator( // step 5.4 var iterations = 0 - while (Math.abs(B - A) > CONVERGENCE_TOLERANCE && iterations < ITERATION_MAX) { + while Math.abs(B - A) > CONVERGENCE_TOLERANCE && iterations < ITERATION_MAX do iterations = iterations + 1 // println(String.format("%f - %f (%f) > %f", B, A, Math.abs(B - A), CONVERGENCE_TOLERANCE)) val C = A + (((A - B) * fA) / (fB - fA)) val fC = f(C, delta, phi, v, a, tau) - if (fC * fB <= 0) { + if fC * fB <= 0 then A = B fA = fB - } else { - fA = fA / 2.0 - } + else fA = fA / 2.0 B = C fB = fC - } - if (iterations == ITERATION_MAX) { + if iterations == ITERATION_MAX then println(String.format("Convergence fail at %d iterations", iterations)) println(player.toString()) results foreach println throw new RuntimeException("Convergence fail") - } val newSigma = Math.exp(A / 2.0) diff --git a/modules/rating/src/main/glicko2/Result.scala b/modules/rating/src/main/glicko2/Result.scala index 87cd674e3f0f4..d9c046187cd13 100644 --- a/modules/rating/src/main/glicko2/Result.scala +++ b/modules/rating/src/main/glicko2/Result.scala @@ -15,9 +15,9 @@ trait Result: // score from 0 (opponent wins) to 1 (player wins) class FloatingResult(player: Rating, opponent: Rating, score: Float) extends Result: - def getScore(p: Rating) = if (p == player) score else 1 - score + def getScore(p: Rating) = if p == player then score else 1 - score - def getOpponent(p: Rating) = if (p == player) opponent else player + def getOpponent(p: Rating) = if p == player then opponent else player def participated(p: Rating) = p == player || p == opponent diff --git a/modules/rating/src/main/package.scala b/modules/rating/src/main/package.scala index 83fd2c56429b6..d82793522c1b9 100644 --- a/modules/rating/src/main/package.scala +++ b/modules/rating/src/main/package.scala @@ -9,8 +9,7 @@ type RatingFactors = Map[lila.rating.PerfType, RatingFactor] given intZero: Zero[IntRating] = Zero(IntRating(0)) -val formMapping: play.api.data.Mapping[IntRating] = { +val formMapping: play.api.data.Mapping[IntRating] = import play.api.data.Forms.number import lila.common.Form.into number(min = Glicko.minRating.value, max = Glicko.maxRating.value).into[IntRating] -} diff --git a/modules/rating/src/test/RatingCalculatorTest.scala b/modules/rating/src/test/RatingCalculatorTest.scala index dfdcb1d3fee2e..3637b15664cda 100644 --- a/modules/rating/src/test/RatingCalculatorTest.scala +++ b/modules/rating/src/test/RatingCalculatorTest.scala @@ -3,7 +3,7 @@ package lila.rating import glicko2.* import chess.{ Color, White, Black } -class RatingCalculatorTest extends lila.common.LilaTest { +class RatingCalculatorTest extends lila.common.LilaTest: def updateRatings(wRating: Rating, bRating: Rating, winner: Option[Color]) = val result = winner match @@ -190,4 +190,3 @@ class RatingCalculatorTest extends lila.common.LilaTest { assertCloseTo(br.volatility, 0.062006, 0.000001d) } } -} diff --git a/modules/relation/src/main/SubscriptionRepo.scala b/modules/relation/src/main/SubscriptionRepo.scala index f72bbbacdcdc2..86259ada0d582 100644 --- a/modules/relation/src/main/SubscriptionRepo.scala +++ b/modules/relation/src/main/SubscriptionRepo.scala @@ -7,14 +7,14 @@ import lila.relation.RelationRepo.makeId final class SubscriptionRepo(colls: Colls, userRepo: lila.user.UserRepo)(using Executor -) { +): val coll = colls.subscription // for streaming, streamerId is the user UserId of the streamer being subscribed to def subscribersOnlineSince(streamerId: UserId, daysAgo: Int): Fu[List[UserId]] = coll .aggregateOne(_.sec): framework => - import framework._ + import framework.* Match($doc("s" -> streamerId)) -> List( PipelineOperator( $lookup.pipeline( @@ -55,4 +55,3 @@ final class SubscriptionRepo(colls: Colls, userRepo: lila.user.UserRepo)(using coll.distinctEasy[String, Set]("_id", $inIds(streamerIds.map(makeId(subscriber, _)))) map { ids => UserId from ids.flatMap(_.split('/').lift(1)) } -} diff --git a/modules/relay/src/main/BSONHandlers.scala b/modules/relay/src/main/BSONHandlers.scala index 2172bf214475e..9104f907f3747 100644 --- a/modules/relay/src/main/BSONHandlers.scala +++ b/modules/relay/src/main/BSONHandlers.scala @@ -35,7 +35,7 @@ object BSONHandlers: given BSONDocumentHandler[RelayTour] = Macros.handler - def readRoundWithTour(doc: Bdoc): Option[RelayRound.WithTour] = for { + def readRoundWithTour(doc: Bdoc): Option[RelayRound.WithTour] = for round <- doc.asOpt[RelayRound] tour <- doc.getAsOpt[RelayTour]("tour") - } yield RelayRound.WithTour(round, tour) + yield RelayRound.WithTour(round, tour) diff --git a/modules/relay/src/main/JsonView.scala b/modules/relay/src/main/JsonView.scala index c4d4074f87be6..0bde7b6c5c106 100644 --- a/modules/relay/src/main/JsonView.scala +++ b/modules/relay/src/main/JsonView.scala @@ -26,7 +26,7 @@ final class JsonView(baseUrl: BaseUrl, markup: RelayMarkup, leaderboardApi: Rela .add("markup" -> trs.tour.markup.map(markup(trs.tour))) .add("url" -> withUrls.option(s"$baseUrl/broadcast/${trs.tour.slug}/${trs.tour.id}")), "rounds" -> trs.rounds.map { round => - if (withUrls) withUrl(round withTour trs.tour) else apply(round) + if withUrls then withUrl(round withTour trs.tour) else apply(round) } ) diff --git a/modules/relay/src/main/RelayApi.scala b/modules/relay/src/main/RelayApi.scala index 0bee871f44375..c7ec4798ed4c2 100644 --- a/modules/relay/src/main/RelayApi.scala +++ b/modules/relay/src/main/RelayApi.scala @@ -160,7 +160,7 @@ final class RelayApi( def isOfficial(id: StudyId): Fu[Boolean] = roundRepo.coll .aggregateOne(): framework => - import framework._ + import framework.* Match($id(id)) -> List( PipelineOperator(tourRepo lookup "tourId"), UnwindField("tour"), diff --git a/modules/relay/src/main/RelayFetch.scala b/modules/relay/src/main/RelayFetch.scala index 93f99af75ac7c..e2ebb40e1bd08 100644 --- a/modules/relay/src/main/RelayFetch.scala +++ b/modules/relay/src/main/RelayFetch.scala @@ -80,10 +80,10 @@ final private class RelayFetch( case e: Exception => e.match { case SyncResult.Timeout => - if (rt.tour.official) logger.info(s"Sync timeout ${rt.round}") + if rt.tour.official then logger.info(s"Sync timeout ${rt.round}") SyncResult.Timeout case _ => - if (rt.tour.official) logger.info(s"Sync error ${rt.round} ${e.getMessage take 80}") + if rt.tour.official then logger.info(s"Sync error ${rt.round} ${e.getMessage take 80}") SyncResult.Error(e.getMessage) } -> rt.round.withSync(_ addLog SyncLog.event(0, e.some)) .map: (result, newRelay) => @@ -173,13 +173,12 @@ final private class RelayFetch( val number = i + 1 val gameDoc = makeGameDoc(number) gameDoc.format - .match { + .match case RelayFormat.DocFormat.Pgn => httpGetPgn(gameDoc.url) case RelayFormat.DocFormat.Json => httpGetJson[GameJson](gameDoc.url).recover { case _: Exception => GameJson(moves = Nil, result = none) } map { _.toPgn(pairing.tags) } - } .map(number -> _) .parallel .map { results => @@ -212,7 +211,7 @@ final private class RelayFetch( private[relay] object RelayFetch: def maxChapters(tour: RelayTour) = - lila.study.Study.maxChapters * (if (tour.official) 2 else 1) + lila.study.Study.maxChapters * (if tour.official then 2 else 1) private[relay] object DgtJson: case class PairingPlayer( @@ -267,7 +266,7 @@ private[relay] object RelayFetch: case (Success((acc, index)), pgn) => pgnCache.get(pgn) flatMap { f => val game = f(index) - if (game.isEmpty) Failure(LilaInvalid(s"Found an empty PGN at index $index")) + if game.isEmpty then Failure(LilaInvalid(s"Found an empty PGN at index $index")) else Success((acc :+ game, index + 1)) } case (acc, _) => acc diff --git a/modules/relay/src/main/RelayInputSanity.scala b/modules/relay/src/main/RelayInputSanity.scala index 04f1af1d32212..5258bc6d30d57 100644 --- a/modules/relay/src/main/RelayInputSanity.scala +++ b/modules/relay/src/main/RelayInputSanity.scala @@ -12,8 +12,8 @@ private object RelayInputSanity: extends Fail(s"Game ${gamePos + 1} matches with Chapter ${chapterPos + 1}") def apply(chapters: List[Chapter], games: RelayGames): Either[Fail, RelayGames] = { - if (chapters.isEmpty) Right(games) - else if (isValidTCEC(chapters, games)) Right(games) + if chapters.isEmpty then Right(games) + else if isValidTCEC(chapters, games) then Right(games) else val relayChapters: List[RelayChapter] = chapters.flatMap { chapter => chapter.relay map chapter.-> diff --git a/modules/relay/src/main/RelayPgnStream.scala b/modules/relay/src/main/RelayPgnStream.scala index 19854af7ea17f..5cab5b7f89dc4 100644 --- a/modules/relay/src/main/RelayPgnStream.scala +++ b/modules/relay/src/main/RelayPgnStream.scala @@ -38,7 +38,7 @@ final class RelayPgnStream( fileR.replaceAllIn(s"lichess_broadcast_${tour.slug}_${tour.id}_$date", "") def streamRoundGames(rt: RelayRound.WithTourAndStudy): Source[PgnStr, ?] = { - if (rt.relay.hasStarted) studyPgnDump.chaptersOf(rt.study, flags).throttle(16, 1 second) + if rt.relay.hasStarted then studyPgnDump.chaptersOf(rt.study, flags).throttle(16, 1 second) else Source.empty[PgnStr] } concat Source .queue[Set[StudyChapterId]](8, akka.stream.OverflowStrategy.dropHead) diff --git a/modules/relay/src/main/RelayPush.scala b/modules/relay/src/main/RelayPush.scala index 1d3b5d225e74e..897c993c39e06 100644 --- a/modules/relay/src/main/RelayPush.scala +++ b/modules/relay/src/main/RelayPush.scala @@ -13,11 +13,10 @@ final class RelayPush(sync: RelaySync, api: RelayApi)(using private val throttler = new lila.hub.EarlyMultiThrottler[RelayRoundId](logger) def apply(rt: RelayRound.WithTour, pgn: PgnStr): Fu[Option[String]] = - if (rt.round.sync.hasUpstream) - fuccess("The relay has an upstream URL, and cannot be pushed to.".some) + if rt.round.sync.hasUpstream then fuccess("The relay has an upstream URL, and cannot be pushed to.".some) else fuccess { - throttler(rt.round.id, if (rt.tour.official) 3.seconds else 7.seconds) { + throttler(rt.round.id, if rt.tour.official then 3.seconds else 7.seconds) { pushNow(rt, pgn) } none diff --git a/modules/relay/src/main/RelayRound.scala b/modules/relay/src/main/RelayRound.scala index 0b47948d1dc5f..2bb52fa2a6f4b 100644 --- a/modules/relay/src/main/RelayRound.scala +++ b/modules/relay/src/main/RelayRound.scala @@ -27,7 +27,7 @@ case class RelayRound( lazy val slug = val s = lila.common.String slugify name.value - if (s.isEmpty) "-" else s + if s.isEmpty then "-" else s def finish = copy( @@ -76,13 +76,13 @@ object RelayRound: def hasUpstream = upstream.isDefined def renew = - if (hasUpstream) copy(until = nowInstant.plusHours(1).some) + if hasUpstream then copy(until = nowInstant.plusHours(1).some) else pause def ongoing = until so nowInstant.isBefore def play = - if (hasUpstream) renew.copy(nextAt = nextAt orElse nowInstant.plusSeconds(3).some) + if hasUpstream then renew.copy(nextAt = nextAt orElse nowInstant.plusSeconds(3).some) else pause def pause = @@ -129,7 +129,7 @@ object RelayRound: def link: RelayRound def fullName = s"${tour.name} • ${display.name}" def path: String = - s"/broadcast/${tour.slug}/${if (link.slug == tour.slug) "-" else link.slug}/${link.id}" + s"/broadcast/${tour.slug}/${if link.slug == tour.slug then "-" else link.slug}/${link.id}" def path(chapterId: StudyChapterId): String = s"$path/$chapterId" case class WithTour(round: RelayRound, tour: RelayTour) extends AndTour: diff --git a/modules/relay/src/main/RelayRoundForm.scala b/modules/relay/src/main/RelayRoundForm.scala index dc0d472ea2298..9b3e036fc91be 100644 --- a/modules/relay/src/main/RelayRoundForm.scala +++ b/modules/relay/src/main/RelayRoundForm.scala @@ -114,7 +114,7 @@ object RelayRoundForm: name = name, caption = caption, sync = makeSync(me).pipe: sync => - if (relay.sync.playing) sync.play else sync, + if relay.sync.playing then sync.play else sync, startsAt = startsAt, finished = relay.finished && startsAt.fold(true)(_.isBeforeNow) ) diff --git a/modules/relay/src/main/RelaySync.scala b/modules/relay/src/main/RelaySync.scala index b6ce6402f73b2..c69f023cae1e8 100644 --- a/modules/relay/src/main/RelaySync.scala +++ b/modules/relay/src/main/RelaySync.scala @@ -62,7 +62,7 @@ final private class RelaySync( chapters: List[Chapter], nbGames: Int ): Option[Chapter] = - if (nbGames == 1 || game.looksLikeLichess) chapters find game.staticTagsMatch + if nbGames == 1 || game.looksLikeLichess then chapters find game.staticTagsMatch else chapters.find(_.relay.exists(_.index == game.index)) private def updateChapter( @@ -119,7 +119,7 @@ final private class RelaySync( .some )(who) inject position + n } inject { - if (chapter.root.children.nodes.isEmpty && node.mainline.nonEmpty) + if chapter.root.children.nodes.isEmpty && node.mainline.nonEmpty then studyApi.reloadChapters(study) node.mainline.size } @@ -132,7 +132,7 @@ final private class RelaySync( game: RelayGame ): Fu[Boolean] = val gameTags = game.tags.value.foldLeft(Tags(Nil)): (newTags, tag) => - if (!chapter.tags.value.has(tag)) newTags + tag + if !chapter.tags.value.has(tag) then newTags + tag else newTags val newEndTag = game.end .ifFalse(gameTags(_.Result).isDefined) @@ -142,7 +142,7 @@ final private class RelaySync( val chapterNewTags = tags.value.foldLeft(chapter.tags): (chapterTags, tag) => PgnTags(chapterTags + tag) (chapterNewTags != chapter.tags) so { - if (vs(chapterNewTags) != vs(chapter.tags)) + if vs(chapterNewTags) != vs(chapter.tags) then logger.info(s"Update ${showSC(study, chapter)} tags '${vs(chapter.tags)}' -> '${vs(chapterNewTags)}'") studyApi.setTags( studyId = study.id, diff --git a/modules/relay/src/main/RelayTour.scala b/modules/relay/src/main/RelayTour.scala index 91726667c11c8..1c896350eca97 100644 --- a/modules/relay/src/main/RelayTour.scala +++ b/modules/relay/src/main/RelayTour.scala @@ -21,13 +21,13 @@ case class RelayTour( lazy val slug = val s = lila.common.String slugify name - if (s.isEmpty) "-" else s + if s.isEmpty then "-" else s def withRounds(rounds: List[RelayRound]) = RelayTour.WithRounds(this, rounds) def official = tier.isDefined - def reAssignIfOfficial = if (official) copy(ownerId = User.broadcasterId) else this + def reAssignIfOfficial = if official then copy(ownerId = User.broadcasterId) else this object RelayTour: diff --git a/modules/relay/src/main/SyncLog.scala b/modules/relay/src/main/SyncLog.scala index 88016caa43d4e..9c7a472d42af0 100644 --- a/modules/relay/src/main/SyncLog.scala +++ b/modules/relay/src/main/SyncLog.scala @@ -13,7 +13,7 @@ case class SyncLog(events: Vector[SyncLog.Event]) extends AnyVal: def add(event: SyncLog.Event) = copy( events = { - if (events.sizeIs > SyncLog.historySize) events drop 1 + if events.sizeIs > SyncLog.historySize then events drop 1 else events } :+ event ) diff --git a/modules/report/src/main/AutoAnalysis.scala b/modules/report/src/main/AutoAnalysis.scala index eed8ca4293534..240fff332f79c 100644 --- a/modules/report/src/main/AutoAnalysis.scala +++ b/modules/report/src/main/AutoAnalysis.scala @@ -11,17 +11,18 @@ final class AutoAnalysis( ): def apply(candidate: Report.Candidate): Funit = - if (candidate.isCheat) doItNow(candidate) - else if (candidate.isPrint) fuccess { - List(30, 90) foreach { minutes => - scheduler.scheduleOnce(minutes minutes) { doItNow(candidate).unit } + if candidate.isCheat then doItNow(candidate) + else if candidate.isPrint then + fuccess { + List(30, 90) foreach { minutes => + scheduler.scheduleOnce(minutes minutes) { doItNow(candidate).unit } + } } - } else funit private def doItNow(candidate: Report.Candidate) = gamesToAnalyse(candidate) map { games => - if (games.nonEmpty) + if games.nonEmpty then logger.info(s"Auto-analyse ${games.size} games after report by ${candidate.reporter.user.id}") games foreach { game => lila.mon.cheat.autoAnalysis("Report").increment() diff --git a/modules/report/src/main/Report.scala b/modules/report/src/main/Report.scala index 5e1f5c2c139a2..8bb0b97d976e8 100644 --- a/modules/report/src/main/Report.scala +++ b/modules/report/src/main/Report.scala @@ -30,7 +30,7 @@ case class Report( def add(atom: Atom) = atomBy(atom.by) .fold(copy(atoms = atom :: atoms)): existing => - if (existing.text contains atom.text) this + if existing.text contains atom.text then this else copy( atoms = { @@ -89,9 +89,9 @@ object Report: extension (a: Score) def +(s: Score): Score = a + s def color = - if (a >= 150) "red" - else if (a >= 100) "orange" - else if (a >= 50) "yellow" + if a >= 150 then "red" + else if a >= 100 then "orange" + else if a >= 50 then "yellow" else "green" def atLeast(s: Score): Score = math.max(a, s) def withinBounds: Score = a atLeast 5 atMost 100 diff --git a/modules/report/src/main/ReportApi.scala b/modules/report/src/main/ReportApi.scala index 43cedafefbc9e..809ef9106d835 100644 --- a/modules/report/src/main/ReportApi.scala +++ b/modules/report/src/main/ReportApi.scala @@ -59,14 +59,13 @@ final class ReportApi( .flatMap { prev => val report = Report.make(scored, prev) lila.mon.mod.report.create(report.reason.key, scored.score.value.toInt).increment() - if ( - report.isRecentComm && + if report.isRecentComm && report.score.value >= thresholds.discord() && prev.exists(_.score.value < thresholds.discord()) - ) ircApi.commReportBurst(c.suspect.user) + then ircApi.commReportBurst(c.suspect.user) coll.update.one($id(report.id), report, upsert = true).void >> autoAnalysis(candidate) >>- { - if (report.isCheat) + if report.isCheat then Bus.publish(lila.hub.actorApi.report.CheatReportCreated(report.user), "cheatReport") } } >>- @@ -223,7 +222,7 @@ final class ReportApi( yield open def reopenReports(suspect: Suspect): Funit = - for { + for all <- recent(suspect, 10) closed = all .filter(_.done.map(_.by) has User.lichessId.into(ModId)) @@ -236,7 +235,7 @@ final class ReportApi( multi = true ) .void - } yield () + yield () // `seriousness` depends on the number of previous warnings, and number of games throwed away def autoBoostReport(winnerId: UserId, loserId: UserId, seriousness: Int): Funit = @@ -244,7 +243,7 @@ final class ReportApi( userRepo.pair(winnerId, loserId) zip getLichessReporter flatMap { case ((isSame, Some((winner, loser))), reporter) if !winner.lame && !loser.lame => val loginsText = - if (isSame) "Found matching IP/print" + if isSame then "Found matching IP/print" else "No IP/print match found" create( Candidate( @@ -281,7 +280,7 @@ final class ReportApi( maxScoreCache.invalidateUnit() >>- lila.mon.mod.report.close.increment().unit - def autoProcess(sus: Suspect, rooms: Set[Room])(using Me.Id): Funit = { + def autoProcess(sus: Suspect, rooms: Set[Room])(using Me.Id): Funit = val selector = $doc( "user" -> sus.user.id, "room" $in rooms, @@ -290,7 +289,6 @@ final class ReportApi( doProcessReport(selector, unsetInquiry = true).void >>- maxScoreCache.invalidateUnit() >>- lila.mon.mod.report.close.increment().unit - } private def doProcessReport(selector: Bdoc, unsetInquiry: Boolean)(using me: Me.Id): Funit = coll.update @@ -435,7 +433,7 @@ final class ReportApi( opens <- findBest(nb, selectOpenInRoom(room, snoozedIds)) nbClosed = nb - opens.size closed <- - if (room.has(Room.Xfiles) || nbClosed < 1) fuccess(Nil) + if room.has(Room.Xfiles) || nbClosed < 1 then fuccess(Nil) else findRecent(nbClosed, closedSelect ++ roomSelect(room)) withNotes <- addSuspectsAndNotes(opens ++ closed) yield withNotes @@ -477,7 +475,7 @@ final class ReportApi( .sort(sortLastAtomAt) .cursor[Report](ReadPref.sec) .list(20) flatMap { reports => - if (reports.sizeIs < 4) fuccess(none) // not enough data to know + if reports.sizeIs < 4 then fuccess(none) // not enough data to know else val userIds = reports.map(_.user).distinct userRepo countEngines userIds map { nbEngines => @@ -563,7 +561,7 @@ final class ReportApi( id: String | Either[Report.Id, UserId] )(using mod: Me): Fu[(Option[Report], Option[Report])] = def findByUser(userId: UserId) = coll.one[Report]($doc("user" -> userId, "inquiry.mod" $exists true)) - for { + for report <- id match case Left(reportId) => coll.byId[Report](reportId) case Right(userId) => findByUser(userId) @@ -579,7 +577,7 @@ final class ReportApi( Report.Inquiry(mod.userId, nowInstant) ) .void - } yield (current, report.filter(_.inquiry.isEmpty)) + yield (current, report.filter(_.inquiry.isEmpty)) def toggleNext(room: Room)(using Me): Fu[Option[Report]] = workQueue: diff --git a/modules/report/src/main/ReportScore.scala b/modules/report/src/main/ReportScore.scala index 80dc2bddaa3a6..d48dcbaa95795 100644 --- a/modules/report/src/main/ReportScore.scala +++ b/modules/report/src/main/ReportScore.scala @@ -48,7 +48,7 @@ final private class ReportScore( private val gameRegex = ReportForm gameLinkRegex domain def dropScoreIfCheatReportHasNoAnalyzedGames(c: Report.Candidate.Scored): Fu[Report.Candidate.Scored] = - if (c.candidate.isCheat & !c.candidate.isIrwinCheat & !c.candidate.isKaladinCheat) + if c.candidate.isCheat & !c.candidate.isIrwinCheat & !c.candidate.isKaladinCheat then val gameIds = gameRegex.findAllMatchIn(c.candidate.text).toList.take(20).map(m => GameId(m.group(1))) def isUsable(gameId: GameId) = gameRepo analysed gameId map { _.exists(_.ply > 30) } gameIds diff --git a/modules/round/src/main/CorresAlarm.scala b/modules/round/src/main/CorresAlarm.scala index b13e64f1bd4d0..64847747d568b 100644 --- a/modules/round/src/main/CorresAlarm.scala +++ b/modules/round/src/main/CorresAlarm.scala @@ -27,7 +27,7 @@ final private class CorresAlarm( private given BSONDocumentHandler[Alarm] = Macros.handler Bus.subscribeFun("finishGame") { case lila.game.actorApi.FinishGame(game, _, _) => - if (game.hasCorrespondenceClock && !game.hasAi) coll.delete.one($id(game.id)).unit + if game.hasCorrespondenceClock && !game.hasAi then coll.delete.one($id(game.id)).unit } Bus.subscribeFun("moveEventCorres") { case lila.hub.actorApi.round.CorresMoveEvent(move, _, _, true, _) => diff --git a/modules/round/src/main/CorrespondenceEmail.scala b/modules/round/src/main/CorrespondenceEmail.scala index 9a5d180ec9913..354ce53e1364d 100644 --- a/modules/round/src/main/CorrespondenceEmail.scala +++ b/modules/round/src/main/CorrespondenceEmail.scala @@ -22,7 +22,7 @@ final private class CorrespondenceEmail(gameRepo: GameRepo, userRepo: UserRepo, def tick(): Unit = { val now = LocalTime.now - if (now.isAfter(runAfter) && now.isBefore(runBefore)) run() + if now.isAfter(runAfter) && now.isBefore(runBefore) then run() }.unit private def run() = @@ -67,7 +67,7 @@ final private class CorrespondenceEmail(gameRepo: GameRepo, userRepo: UserRepo, .documentSource() .mapConcat { doc => import lila.game.BSONHandlers.given - (for { + (for userId <- doc.getAsOpt[UserId]("_id") games <- doc.getAsOpt[List[Game]]("games") povs = games @@ -82,5 +82,5 @@ final private class CorrespondenceEmail(gameRepo: GameRepo, userRepo: UserRepo, pov.game.id ) } - } yield CorrespondenceOpponents(userId, opponents)).toList + yield CorrespondenceOpponents(userId, opponents)).toList } diff --git a/modules/round/src/main/Drawer.scala b/modules/round/src/main/Drawer.scala index 8bf19819e7a66..c4efe06ecfeb8 100644 --- a/modules/round/src/main/Drawer.scala +++ b/modules/round/src/main/Drawer.scala @@ -20,7 +20,7 @@ final private[round] class Drawer( def autoThreefold(game: Game): Fu[Option[Pov]] = game.drawable.so: Pov(game) .map: pov => - if (game.playerHasOfferedDrawRecently(pov.color)) fuccess(pov.some) + if game.playerHasOfferedDrawRecently(pov.color) then fuccess(pov.some) else pov.player.userId so { uid => prefApi.get(uid, _.autoThreefold) } map { autoThreefold => autoThreefold == Pref.AutoThreefold.ALWAYS || { @@ -51,7 +51,7 @@ final private[round] class Drawer( case _ => fuccess(List(Event.ReloadOwner)) def no(pov: Pov)(using proxy: GameProxy): Fu[Events] = pov.game.drawable.so: - pov match { + pov match case Pov(g, color) if pov.player.isOfferingDraw => proxy.save { messenger.system(g, trans.drawOfferCanceled.txt()) @@ -67,7 +67,7 @@ final private[round] class Drawer( } } inject List(Event.DrawOffer(by = none)) case _ => fuccess(List(Event.ReloadOwner)) - }: Fu[Events] + : Fu[Events] def claim(pov: Pov)(using GameProxy): Fu[Events] = (pov.game.drawable && pov.game.history.threefoldRepetition) so @@ -75,13 +75,13 @@ final private[round] class Drawer( def force(game: Game)(using GameProxy): Fu[Events] = finisher.other(game, _.Draw, None, None) - private def publishDrawOffer(game: Game): Unit = if (game.nonAi) - if (game.isCorrespondence) + private def publishDrawOffer(game: Game): Unit = if game.nonAi then + if game.isCorrespondence then Bus.publish( lila.hub.actorApi.round.CorresDrawOfferEvent(game.id), "offerEventCorres" ) - if (lila.game.Game.isBoardOrBotCompatible(game)) + if lila.game.Game.isBoardOrBotCompatible(game) then Bus.publish( lila.game.actorApi.BoardDrawOffer(game), lila.game.actorApi.BoardDrawOffer makeChan game.id diff --git a/modules/round/src/main/Env.scala b/modules/round/src/main/Env.scala index dac5a21d51d57..57192a652db45 100644 --- a/modules/round/src/main/Env.scala +++ b/modules/round/src/main/Env.scala @@ -66,8 +66,7 @@ final class Env( private val defaultGoneWeight = fuccess(1f) private def goneWeight(userId: UserId): Fu[Float] = playban.getRageSit(userId).dmap(_.goneWeight) private val goneWeightsFor: Game => Fu[(Float, Float)] = (game: Game) => - if (!game.playable || !game.hasClock || game.hasAi || !Uptime.startedSinceMinutes(1)) - fuccess(1f -> 1f) + if !game.playable || !game.hasClock || game.hasAi || !Uptime.startedSinceMinutes(1) then fuccess(1f -> 1f) else game.whitePlayer.userId.fold(defaultGoneWeight)(goneWeight) zip game.blackPlayer.userId.fold(defaultGoneWeight)(goneWeight) @@ -198,8 +197,8 @@ final class Env( val apiMoveStream = wire[ApiMoveStream] def resign(pov: Pov): Unit = - if (pov.game.abortableByUser) tellRound(pov.gameId, Abort(pov.playerId)) - else if (pov.game.resignable) tellRound(pov.gameId, Resign(pov.playerId)) + if pov.game.abortableByUser then tellRound(pov.gameId, Abort(pov.playerId)) + else if pov.game.resignable then tellRound(pov.gameId, Resign(pov.playerId)) trait SelfReportEndGame trait SelfReportMarkUser diff --git a/modules/round/src/main/Finisher.scala b/modules/round/src/main/Finisher.scala index 6be2e0040210d..76c8a4d184606 100644 --- a/modules/round/src/main/Finisher.scala +++ b/modules/round/src/main/Finisher.scala @@ -42,10 +42,11 @@ final private class Finisher( } def outOfTime(game: Game)(using GameProxy): Fu[Events] = - if (!game.isCorrespondence && !Uptime.startedSinceSeconds(120) && game.movedAt.isBefore(Uptime.startedAt)) + if !game.isCorrespondence && !Uptime.startedSinceSeconds(120) && game.movedAt.isBefore(Uptime.startedAt) + then logger.info(s"Aborting game last played before JVM boot: ${game.id}") other(game, _.Aborted, none) - else if (game.player(!game.player.color).isOfferingDraw) + else if game.player(!game.player.color).isOfferingDraw then apply(game, _.Draw, None, Messenger.SystemMessage.Persistent(trans.drawOfferAccepted.txt()).some) else val winner = Some(!game.player.color) ifFalse game.situation.opponentHasInsufficientMaterial @@ -58,7 +59,8 @@ final private class Finisher( game.playerWhoDidNotMove.so: culprit => lila.mon.round.expiration.count.increment() playban.noStart(Pov(game, culprit)) - if (game.isMandatory || game.metadata.hasRule(_.NoAbort)) apply(game, _.NoStart, Some(!culprit.color)) + if game.isMandatory || game.metadata.hasRule(_.NoAbort) then + apply(game, _.NoStart, Some(!culprit.color)) else apply(game, _.Aborted, None, Messenger.SystemMessage.Persistent("Game aborted by server").some) def other( @@ -69,7 +71,7 @@ final private class Finisher( )(using GameProxy): Fu[Events] = apply(game, status, winner, message) >>- playban.other(game, status, winner).unit - private def recordLagStats(game: Game) = for { + private def recordLagStats(game: Game) = for clock <- game.clock player <- clock.players.all lt = player.lag @@ -82,7 +84,7 @@ final private class Finisher( compEstStdErr <- lt.compEstStdErr quotaStr = f"${lt.quotaGain.centis / 10}%02d" compEstOvers = lt.compEstOvers.centis - } { + do import lila.mon.round.move.{ lag as lRec } lRec.mean.record(Math.round(10 * mean)) lRec.stdDev.record(Math.round(10 * sd)) @@ -96,7 +98,6 @@ final private class Finisher( case h: DecayingStats => lRec.compDeviation.record(h.deviation.toInt) lRec.compEstStdErr.record(Math.round(1000 * compEstStdErr)) lRec.compEstOverErr.record(Math.round(10f * compEstOvers / moves)) - } private def apply( prev: Game, @@ -107,7 +108,7 @@ final private class Finisher( val status = makeStatus(Status) val prog = lila.game.Progress(prev, prev.finish(status, winnerC)) val game = prog.game - if (game.nonAi && game.isCorrespondence) Color.all foreach notifier.gameEnd(prog.game) + if game.nonAi && game.isCorrespondence then Color.all foreach notifier.gameEnd(prog.game) lila.mon.game .finish( variant = game.variant.key.value, @@ -154,8 +155,8 @@ final private class Finisher( val totalTime = (game.hasClock && user.playTime.isDefined) so game.durationSeconds val tvTime = totalTime ifTrue recentTvGames.get(game.id) val result = - if (game.winnerUserId has user.id) 1 - else if (game.loserUserId has user.id) -1 + if game.winnerUserId has user.id then 1 + else if game.loserUserId has user.id then -1 else 0 userRepo .incNbGames(user.id, game.rated, game.hasAi, result = result, totalTime = totalTime, tvTime = tvTime) diff --git a/modules/round/src/main/ForecastApi.scala b/modules/round/src/main/ForecastApi.scala index 39ccdce864f76..78b53dbe833cd 100644 --- a/modules/round/src/main/ForecastApi.scala +++ b/modules/round/src/main/ForecastApi.scala @@ -38,7 +38,7 @@ final class ForecastApi(coll: Coll, tellRound: TellRound)(using Executor): uciMove: String, steps: Forecast.Steps ): Funit = - if (!pov.isMyTurn) funit + if !pov.isMyTurn then funit else Uci.Move(uciMove).fold[Funit](fufail(lila.round.ClientError(s"Invalid move $uciMove on $pov"))) { uci => val promise = Promise[Unit]() @@ -58,7 +58,7 @@ final class ForecastApi(coll: Coll, tellRound: TellRound)(using Executor): pov.forecastable so coll.byId[Forecast](pov.fullId) flatMap { case None => fuccess(none) case Some(fc) => - if (firstStep(fc.steps).exists(_.ply != pov.game.ply + 1)) clearPov(pov) inject none + if firstStep(fc.steps).exists(_.ply != pov.game.ply + 1) then clearPov(pov) inject none else fuccess(fc.some) } @@ -66,7 +66,7 @@ final class ForecastApi(coll: Coll, tellRound: TellRound)(using Executor): pov.game.forecastable so coll.byId[Forecast](pov.fullId) flatMap { case None => fuccess(none) case Some(fc) => - if (firstStep(fc.steps).exists(_.ply != pov.game.ply)) clearPov(pov) inject none + if firstStep(fc.steps).exists(_.ply != pov.game.ply) then clearPov(pov) inject none else fuccess(fc.some) } diff --git a/modules/round/src/main/GameProxy.scala b/modules/round/src/main/GameProxy.scala index d4de4a8b6eb7a..dd8d944333bbc 100644 --- a/modules/round/src/main/GameProxy.scala +++ b/modules/round/src/main/GameProxy.scala @@ -21,7 +21,7 @@ final private class GameProxy( def save(progress: Progress): Funit = set(progress.game) dirtyProgress = dirtyProgress.fold(progress.dropEvents)(_ withGame progress.game).some - if (shouldFlushProgress(progress)) flushProgress() + if shouldFlushProgress(progress) then flushProgress() else fuccess(scheduleFlushProgress()) def update(f: Game => Game): Funit = diff --git a/modules/round/src/main/GameProxyRepo.scala b/modules/round/src/main/GameProxyRepo.scala index 79988d0c4ebaf..e5b85597f6982 100644 --- a/modules/round/src/main/GameProxyRepo.scala +++ b/modules/round/src/main/GameProxyRepo.scala @@ -24,7 +24,7 @@ final class GameProxyRepo( // get the proxied version of the game def upgradeIfPresent(game: Game): Fu[Game] = - if (game.finishedOrAborted) fuccess(game) + if game.finishedOrAborted then fuccess(game) else roundSocket upgradeIfPresent game def upgradeIfPresent(pov: Pov): Fu[Pov] = diff --git a/modules/round/src/main/JsonView.scala b/modules/round/src/main/JsonView.scala index 2908682f84929..5024dbb65f744 100644 --- a/modules/round/src/main/JsonView.scala +++ b/modules/round/src/main/JsonView.scala @@ -97,7 +97,7 @@ final class JsonView( "coords" -> pref.coords, "resizeHandle" -> pref.resizeHandle, "replay" -> pref.replay, - "autoQueen" -> (if (pov.game.variant == chess.variant.Antichess) Pref.AutoQueen.NEVER + "autoQueen" -> (if pov.game.variant == chess.variant.Antichess then Pref.AutoQueen.NEVER else pref.autoQueen), "clockTenths" -> pref.clockTenths, "moveEvent" -> pref.moveEvent @@ -321,7 +321,7 @@ final class JsonView( private def animationMillis(pov: Pov, pref: Pref) = pref.animationMillis * { - if (pov.game.finished) 1 + if pov.game.finished then 1 else math.max(0, math.min(1.2, ((pov.game.estimateTotalTime - 60) / 60) * 0.2)) } diff --git a/modules/round/src/main/Messenger.scala b/modules/round/src/main/Messenger.scala index d10cb168aa2b1..e4aeb938fa0b9 100644 --- a/modules/round/src/main/Messenger.scala +++ b/modules/round/src/main/Messenger.scala @@ -17,11 +17,12 @@ final class Messenger(api: ChatApi): case Messenger.SystemMessage.Persistent(msg) => system(persistent = true)(game, msg) case Messenger.SystemMessage.Volatile(msg) => system(persistent = false)(game, msg) - def system(persistent: Boolean)(game: Game, message: String): Unit = if (game.nonAi) { - api.userChat.volatile(chatWatcherId(game.id into ChatId), message, _.Round) - if (persistent) api.userChat.system(game.id into ChatId, message, _.Round) - else api.userChat.volatile(game.id into ChatId, message, _.Round) - }.unit + def system(persistent: Boolean)(game: Game, message: String): Unit = if game.nonAi then + { + api.userChat.volatile(chatWatcherId(game.id into ChatId), message, _.Round) + if persistent then api.userChat.system(game.id into ChatId, message, _.Round) + else api.userChat.volatile(game.id into ChatId, message, _.Round) + }.unit def watcher(gameId: GameId, userId: UserId, text: String) = api.userChat.write(gameWatcherId(gameId), userId, text, PublicSource.Watcher(gameId).some, _.Round) diff --git a/modules/round/src/main/Moretimer.scala b/modules/round/src/main/Moretimer.scala index 0fef17df54480..ae37d73c4b18e 100644 --- a/modules/round/src/main/Moretimer.scala +++ b/modules/round/src/main/Moretimer.scala @@ -52,8 +52,8 @@ final class Moretimer( p == Pref.Moretime.ALWAYS || (p == Pref.Moretime.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.canTakebackOrAddTime || game.metadata.hasRule(_.NoGiveTime)) + if !game.playable then fufail(ClientError("[moretimer] game is over " + game.id)) + else if !game.canTakebackOrAddTime || game.metadata.hasRule(_.NoGiveTime) then fufail(ClientError("[moretimer] game disallows it " + game.id)) else isAllowedByPrefs(game) flatMap { diff --git a/modules/round/src/main/NoteApi.scala b/modules/round/src/main/NoteApi.scala index 079e36df471e5..7e0b247e01375 100644 --- a/modules/round/src/main/NoteApi.scala +++ b/modules/round/src/main/NoteApi.scala @@ -14,7 +14,7 @@ final class NoteApi(coll: Coll)(using Executor): coll.primitiveOne[String]($id(makeId(gameId, userId)), noteField) dmap (~_) def set(gameId: GameId, userId: UserId, text: String) = { - if (text.isEmpty) coll.delete.one($id(makeId(gameId, userId))) + if text.isEmpty then coll.delete.one($id(makeId(gameId, userId))) else coll.update.one( $id(makeId(gameId, userId)), diff --git a/modules/round/src/main/PerfsUpdater.scala b/modules/round/src/main/PerfsUpdater.scala index a2f03b0715401..34fba5ed555dc 100644 --- a/modules/round/src/main/PerfsUpdater.scala +++ b/modules/round/src/main/PerfsUpdater.scala @@ -171,4 +171,4 @@ final class PerfsUpdater( classical = r(PT.Classical, perfs.classical, perfs1.classical), correspondence = r(PT.Correspondence, perfs.correspondence, perfs1.correspondence) ) - if (isStd) perfs2.updateStandard else perfs2 + if isStd then perfs2.updateStandard else perfs2 diff --git a/modules/round/src/main/Player.scala b/modules/round/src/main/Player.scala index 7746207807f0d..a5d3078e6a2fc 100644 --- a/modules/round/src/main/Player.scala +++ b/modules/round/src/main/Player.scala @@ -74,24 +74,25 @@ final private class Player( progress: Progress, moveOrDrop: MoveOrDrop )(using GameProxy): Fu[Events] = - if (pov.game.hasAi) uciMemo.add(pov.game, moveOrDrop) + if pov.game.hasAi then uciMemo.add(pov.game, moveOrDrop) notifyMove(moveOrDrop, progress.game) - if (progress.game.finished) moveFinish(progress.game) dmap { progress.events ::: _ } + if progress.game.finished then moveFinish(progress.game) dmap { progress.events ::: _ } else { - if (progress.game.playableByAi) requestFishnet(progress.game, round) - if (pov.opponent.isOfferingDraw) round ! DrawNo(pov.player.id) - if (pov.player.isProposingTakeback) round ! TakebackNo(pov.player.id) - if (progress.game.forecastable) moveOrDrop.move.foreach { move => - round ! ForecastPlay(move) - } + if progress.game.playableByAi then requestFishnet(progress.game, round) + if pov.opponent.isOfferingDraw then round ! DrawNo(pov.player.id) + if pov.player.isProposingTakeback then round ! TakebackNo(pov.player.id) + if progress.game.forecastable then + moveOrDrop.move.foreach { move => + round ! ForecastPlay(move) + } scheduleExpiration(progress.game) fuccess(progress.events) } private[round] def fishnet(game: Game, sign: String, uci: Uci)(using proxy: GameProxy): Fu[Events] = - if (game.playable && game.player.isAi) + if game.playable && game.player.isAi then uciMemo sign game flatMap { expectedSign => - if (expectedSign == sign) + if expectedSign == sign then applyUci(game, uci, blur = false, metrics = fishnetLag) .fold(errs => fufail(ClientError(ErrorStr raw errs)), fuccess) .flatMap { @@ -101,9 +102,8 @@ final private class Player( uciMemo.add(progress.game, moveOrDrop) >>- lila.mon.fishnet.move(~game.aiLevel).increment().unit >>- notifyMove(moveOrDrop, progress.game) >> { - if (progress.game.finished) moveFinish(progress.game) dmap { progress.events ::: _ } - else - fuccess(progress.events) + if progress.game.finished then moveFinish(progress.game) dmap { progress.events ::: _ } + else fuccess(progress.events) } } else @@ -122,7 +122,7 @@ final private class Player( private[round] def requestFishnet(game: Game, round: RoundAsyncActor): Funit = game.playableByAi.so: - if (game.ply <= fishnetPlayer.maxPlies) fishnetPlayer(game) + if game.ply <= fishnetPlayer.maxPlies then fishnetPlayer(game) else fuccess(round ! actorApi.round.ResignAi) private val fishnetLag = MoveMetrics(clientLag = Centis(5).some) @@ -168,7 +168,7 @@ final private class Player( Bus.publish(MoveGameEvent(game, moveEvent.fen, moveEvent.move), MoveGameEvent makeChan game.id) // publish correspondence moves - if (game.isCorrespondence && game.nonAi) + if game.isCorrespondence && game.nonAi then Bus.publish( CorresMoveEvent( move = moveEvent, diff --git a/modules/round/src/main/RecentTvGames.scala b/modules/round/src/main/RecentTvGames.scala index a50ba5f7929ac..6902cd39058dc 100644 --- a/modules/round/src/main/RecentTvGames.scala +++ b/modules/round/src/main/RecentTvGames.scala @@ -11,4 +11,4 @@ final class RecentTvGames(gameRepo: GameRepo): def put(game: Game) = gameRepo.setTv(game.id) - (if (game.speed <= chess.Speed.Bullet) fast else slow) put game.id + (if game.speed <= chess.Speed.Bullet then fast else slow) put game.id diff --git a/modules/round/src/main/Rematcher.scala b/modules/round/src/main/Rematcher.scala index b42a6c64dc3dc..92d2ed774f460 100644 --- a/modules/round/src/main/Rematcher.scala +++ b/modules/round/src/main/Rematcher.scala @@ -37,10 +37,9 @@ final private class Rematcher( def yes(pov: Pov): Fu[Events] = pov match case Pov(game, color) if game.playerCouldRematch => - if (isOffering(!pov) || game.opponent(color).isAi) + if isOffering(!pov) || game.opponent(color).isAi then rematches.getAcceptedId(game.id).fold(rematchJoin(pov))(rematchExists(pov)) - else if (!declined.get(pov.flip.fullId) && rateLimit.zero(pov.fullId)(true)) - rematchCreate(pov) + else if !declined.get(pov.flip.fullId) && rateLimit.zero(pov.fullId)(true) then rematchCreate(pov) else fuccess(List(Event.RematchOffer(by = none))) case _ => fuccess(List(Event.ReloadOwner)) @@ -72,12 +71,12 @@ final private class Rematcher( private def rematchJoin(pov: Pov): Fu[Events] = - def createGame(withId: Option[GameId]) = for { + def createGame(withId: Option[GameId]) = for nextGame <- returnGame(pov, withId).map(_.start) _ = rematches.accept(pov.gameId, nextGame.id) - _ = if (pov.game.variant == Chess960 && !chess960.get(pov.gameId)) chess960.put(nextGame.id) + _ = if pov.game.variant == Chess960 && !chess960.get(pov.gameId) then chess960.put(nextGame.id) _ <- gameRepo insertDenormalized nextGame - } yield + yield messenger.volatile(pov.game, trans.rematchOfferAccepted.txt()) onStart(nextGame.id) redirectEvents(nextGame) @@ -88,12 +87,12 @@ final private class Rematcher( case Some(Rematches.NextGame.Offered(_, id)) => createGame(id.some) private def returnGame(pov: Pov, withId: Option[GameId]): Fu[Game] = - for { + for initialFen <- gameRepo initialFen pov.game situation = initialFen.flatMap(Fen.readWithMoveNumber(pov.game.variant, _)) pieces = pov.game.variant match case Chess960 => - if (chess960 get pov.gameId) Chess960.pieces + if chess960 get pov.gameId then Chess960.pieces else situation.fold(Chess960.pieces)(_.situation.board.pieces) case FromPosition => situation.fold(Standard.pieces)(_.situation.board.pieces) case variant => variant.pieces @@ -126,7 +125,7 @@ final private class Rematcher( pgnImport = None ) game <- withId.fold(sloppy.withUniqueId) { id => fuccess(sloppy withId id) } - } yield game + yield game private def returnPlayer(game: Game, color: ChessColor, users: List[User.WithPerf]): lila.game.Player = game.opponent(color).aiLevel match diff --git a/modules/round/src/main/RoundAsyncActor.scala b/modules/round/src/main/RoundAsyncActor.scala index 1054351a93194..93b972777d8cb 100644 --- a/modules/round/src/main/RoundAsyncActor.scala +++ b/modules/round/src/main/RoundAsyncActor.scala @@ -53,7 +53,7 @@ final private[round] class RoundAsyncActor( def setOnline(on: Boolean): Unit = isLongGone foreach { _ so notifyGone(color, gone = false) } - offlineSince = if (on) None else offlineSince orElse nowMillis.some + offlineSince = if on then None else offlineSince orElse nowMillis.some bye = bye && !on def setBye(): Unit = bye = true @@ -62,7 +62,7 @@ final private[round] class RoundAsyncActor( private def timeoutMillis: Long = { val base = { - if (bye) RoundSocket.ragequitTimeout + if bye then RoundSocket.ragequitTimeout else proxy.withGameOptionSync { g => RoundSocket.povDisconnectTimeout(g pov color) @@ -76,7 +76,7 @@ final private[round] class RoundAsyncActor( } so !isHostingSimul def showMillisToGone: Fu[Option[Long]] = - if (botConnected) fuccess(none) + if botConnected then fuccess(none) else val now = nowMillis offlineSince @@ -87,13 +87,13 @@ final private[round] class RoundAsyncActor( !_ option (timeoutMillis + since - now) def setBotConnected(v: Boolean) = - botConnections = Math.max(0, botConnections + (if (v) 1 else -1)) + botConnections = Math.max(0, botConnections + (if v then 1 else -1)) end Player private val whitePlayer = Player(White) private val blackPlayer = Player(Black) - export proxy.{ game => getGame, update => updateGame } + export proxy.{ game as getGame, update as updateGame } val process: AsyncActor.ReceiveAsync = @@ -104,7 +104,7 @@ final private[round] class RoundAsyncActor( mightBeSimul = game.isSimul whitePlayer.goneWeight = whiteGoneWeight blackPlayer.goneWeight = blackGoneWeight - if (game.playableByAi) player.requestFishnet(game, this) + if game.playableByAi then player.requestFishnet(game, this) // socket stuff @@ -185,8 +185,8 @@ final private[round] class RoundAsyncActor( case p: HumanPlay => handle(p.playerId): pov => - if (pov.player.isAi) fufail(s"player $pov can't play AI") - else if (pov.game.outoftime(withGrace = true)) finisher.outOfTime(pov.game) + if pov.player.isAi then fufail(s"player $pov can't play AI") + else if pov.game.outoftime(withGrace = true) then finisher.outOfTime(pov.game) else recordLag(pov) player.human(p, this)(pov) @@ -204,7 +204,7 @@ final private[round] class RoundAsyncActor( case p: BotPlay => val res = proxy.withPov(p.playerId) { _.so: pov => - if (pov.game.outoftime(withGrace = true)) finisher.outOfTime(pov.game) + if pov.game.outoftime(withGrace = true) then finisher.outOfTime(pov.game) else player.bot(p.uci, this)(pov) } dmap publish p.promise.foreach(_ completeWith res) @@ -275,7 +275,7 @@ final private[round] class RoundAsyncActor( case Abandon => proxy.withGame: game => game.abandoned.so: - if (game.abortable) finisher.other(game, _.Aborted, None) + if game.abortable then finisher.other(game, _.Aborted, None) else finisher.other(game, _.Resign, Some(!game.player.color)) case DrawYes(playerId) => handle(playerId)(drawer.yes) @@ -350,8 +350,9 @@ final private[round] class RoundAsyncActor( case NoStart => handle: game => game.timeBeforeExpiration.exists(_.centis == 0) so { - if (game.isSwiss) game.startClock.so: g => - proxy save g inject List(Event.Reload) + if game.isSwiss then + game.startClock.so: g => + proxy save g inject List(Event.Reload) else finisher.noStart(game) } @@ -368,10 +369,10 @@ final private[round] class RoundAsyncActor( proxy.withGameOptionSync { g => (g.forceResignable && g.bothPlayersHaveMoved) so fuccess: Color.all.foreach: c => - if (!getPlayer(c).isOnline && getPlayer(!c).isOnline) + if !getPlayer(c).isOnline && getPlayer(!c).isOnline then getPlayer(c).showMillisToGone foreach { _.so: millis => - if (millis <= 0) notifyGone(c, gone = true) + if millis <= 0 then notifyGone(c, gone = true) else g.clock.exists(_.remainingTime(c).millis > millis + 3000) so notifyGoneIn(c, millis) } } | funit @@ -392,7 +393,7 @@ final private[round] class RoundAsyncActor( } private def recordLag(pov: Pov): Unit = - if ((pov.game.playedTurns.value & 30) == 10) + if (pov.game.playedTurns.value & 30) == 10 then // Triggers every 32 moves starting on ply 10. // i.e. 10, 11, 42, 43, 74, 75, ... for @@ -414,7 +415,7 @@ final private[round] class RoundAsyncActor( publishBoardBotGone(pov, millis.some) private def publishBoardBotGone(pov: Pov, millis: Option[Long]) = - if (lila.game.Game.isBoardOrBotCompatible(pov.game)) + if lila.game.Game.isBoardOrBotCompatible(pov.game) then lila.common.Bus.publish( lila.game.actorApi.BoardGone(pov, millis.map(m => (m.atLeast(0) / 1000).toInt)), lila.game.actorApi.BoardGone makeChan gameId diff --git a/modules/round/src/main/RoundSocket.scala b/modules/round/src/main/RoundSocket.scala index ea8f63e132048..3c99a30e6850e 100644 --- a/modules/round/src/main/RoundSocket.scala +++ b/modules/round/src/main/RoundSocket.scala @@ -245,7 +245,7 @@ final class RoundSocket( .andThen: case scala.util.Success(loadedIds) => val missingIds = gamePromises.keySet -- loadedIds - if (missingIds.nonEmpty) + if missingIds.nonEmpty then bootLog.warn: s"RoundSocket ${missingIds.size} round games could not be loaded: ${missingIds.take(20) mkString " "}" missingIds.foreach: id => @@ -367,12 +367,12 @@ object RoundSocket: case _ => RP.In.reader(raw) private def centis(s: String): Option[Centis] = - if (s == "-") none + if s == "-" then none else Centis from s.toIntOption private def readColor(s: String) = - if (s == "w") Some(White) - else if (s == "b") Some(Black) + if s == "w" then Some(White) + else if s == "b" then Some(Black) else None object Out: @@ -385,14 +385,14 @@ object RoundSocket: def tellVersion(roomId: RoomId, version: SocketVersion, e: Event) = val flags = StringBuilder(2) - if (e.watcher) flags += 's' - else if (e.owner) flags += 'p' + if e.watcher then flags += 's' + else if e.owner then flags += 'p' else e.only.map(_.fold('w', 'b')).orElse { e.moveBy.map(_.fold('W', 'B')) } foreach flags.+= - if (e.troll) flags += 't' - if (flags.isEmpty) flags += '-' + if e.troll then flags += 't' + if flags.isEmpty then flags += '-' s"r/ver $roomId $version $flags ${e.typ} ${e.data}" def tvSelect(gameId: GameId, speed: chess.Speed, data: JsObject) = diff --git a/modules/round/src/main/SelfReport.scala b/modules/round/src/main/SelfReport.scala index 7bff797cc6754..9b1758dce5ece 100644 --- a/modules/round/src/main/SelfReport.scala +++ b/modules/round/src/main/SelfReport.scala @@ -31,28 +31,27 @@ final class SelfReport( // Env.report.api.autoBotReport(u.id, referer, name) // } def doLog(): Unit = - if (name != "ceval") + if name != "ceval" then if logOnceEvery(ip.str) then lila.log("cheat").branch("jslog").info { s"$ip https://lichess.org/$fullId ${user.fold("anon")(_.id)} $name" } lila.mon.cheat.selfReport(name, userId.isDefined).increment() - if (fullId.value == "____________") doLog() + if fullId.value == "____________" then doLog() else proxyRepo .pov(fullId) .foreach: _.so: pov => - if (!known) doLog() + if !known then doLog() user.foreach: u => - if ( - endGameSetting.get().matches(name) || + if endGameSetting.get().matches(name) || (name.startsWith("soc") && ( name.contains("stockfish") || name.contains("userscript") || name.contains("__puppeteer_evaluation_script__") )) - ) tellRound(pov.gameId, lila.round.actorApi.round.Cheat(pov.color)) - if (markUserSetting.get().matches(name)) + then tellRound(pov.gameId, lila.round.actorApi.round.Cheat(pov.color)) + if markUserSetting.get().matches(name) then val rating = u.perfs.bestRating val hours = if rating > 2500 then 0 diff --git a/modules/round/src/main/StepBuilder.scala b/modules/round/src/main/StepBuilder.scala index 665c772a2c321..01e4e7115b0c9 100644 --- a/modules/round/src/main/StepBuilder.scala +++ b/modules/round/src/main/StepBuilder.scala @@ -45,7 +45,6 @@ object StepBuilder: } private val logChessError = (id: String) => - (err: chess.ErrorStr) => { - val path = if (id == "synthetic") "analysis" else id + (err: chess.ErrorStr) => + val path = if id == "synthetic" then "analysis" else id logger.info(s"https://lichess.org/$path ${err.value.linesIterator.toList.headOption | "?"}") - } diff --git a/modules/round/src/main/Takebacker.scala b/modules/round/src/main/Takebacker.scala index fffbeeb07406c..c157f5da12ebd 100644 --- a/modules/round/src/main/Takebacker.scala +++ b/modules/round/src/main/Takebacker.scala @@ -23,10 +23,9 @@ final private class Takebacker( pov match case Pov(game, color) if pov.opponent.isProposingTakeback => { - if ( - pov.opponent.proposeTakebackAt == pov.game.ply && + if pov.opponent.proposeTakebackAt == pov.game.ply && color == pov.opponent.proposeTakebackAt.turn - ) single(game) + then single(game) else double(game) } >>- publishTakeback(pov) dmap (_ -> situation.reset) case Pov(game, _) if pov.game.playableByAi => @@ -70,7 +69,7 @@ final private class Takebacker( game.canTakebackOrAddTime so isAllowedByPrefs(game) private def isAllowedByPrefs(game: Game): Fu[Boolean] = - if (game.hasAi) fuTrue + if game.hasAi then fuTrue else game.userIds.map { prefApi.get(_, (p: Pref) => p.takeback) @@ -81,8 +80,8 @@ final private 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.canTakebackOrAddTime) fufail(ClientError("[takebacker] game disallows it " + game.id)) + if !game.playable then fufail(ClientError("[takebacker] game is over " + game.id)) + else if !game.canTakebackOrAddTime then fufail(ClientError("[takebacker] game disallows it " + game.id)) else isAllowedByPrefs(game) flatMap { if _ then f @@ -90,15 +89,15 @@ final private class Takebacker( } private def single(game: Game)(using GameProxy): Fu[Events] = - for { + for fen <- gameRepo initialFen game progress <- Rewind(game, fen).toFuture _ <- fuccess { uciMemo.drop(game, 1) } events <- saveAndNotify(progress) - } yield events + yield events private def double(game: Game)(using GameProxy): Fu[Events] = - for { + for fen <- gameRepo initialFen game prog1 <- Rewind(game, fen).toFuture prog2 <- Rewind(prog1.game, fen).toFuture dmap { progress => @@ -106,7 +105,7 @@ final private class Takebacker( } _ <- fuccess { uciMemo.drop(game, 2) } events <- saveAndNotify(prog2) - } yield events + yield events private def saveAndNotify(p1: Progress)(using proxy: GameProxy): Fu[Events] = val p2 = p1 + Event.Reload @@ -114,14 +113,14 @@ final private class Takebacker( proxy.save(p2) inject p2.events private def publishTakebackOffer(game: Game): Unit = - if (lila.game.Game.isBoardOrBotCompatible(game)) + if lila.game.Game.isBoardOrBotCompatible(game) then Bus.publish( lila.game.actorApi.BoardTakebackOffer(game), lila.game.actorApi.BoardTakebackOffer makeChan game.id ) private def publishTakeback(prevPov: Pov)(using proxy: GameProxy): Unit = - if (lila.game.Game.isBoardOrBotCompatible(prevPov.game)) + if lila.game.Game.isBoardOrBotCompatible(prevPov.game) then proxy .withPov(prevPov.color) { p => fuccess( diff --git a/modules/round/src/main/TreeBuilder.scala b/modules/round/src/main/TreeBuilder.scala index 7f875c973eb3e..42ecd927b58dd 100644 --- a/modules/round/src/main/TreeBuilder.scala +++ b/modules/round/src/main/TreeBuilder.scala @@ -27,7 +27,8 @@ object TreeBuilder: case (init, games, error) => error foreach logChessError(game.id) val openingOf: OpeningOf = - if (withFlags.opening && Variant.list.openingSensibleVariants(game.variant)) OpeningDb.findByEpdFen + if withFlags.opening && Variant.list.openingSensibleVariants(game.variant) then + OpeningDb.findByEpdFen else _ => None val fen = Fen write init val infos: Vector[Info] = analysis.so(_.infos.toVector) diff --git a/modules/round/src/main/TvBroadcast.scala b/modules/round/src/main/TvBroadcast.scala index beab1d33fadf6..1af2477ca6988 100644 --- a/modules/round/src/main/TvBroadcast.scala +++ b/modules/round/src/main/TvBroadcast.scala @@ -69,7 +69,7 @@ final private class TvBroadcast( ) clients.foreach { client => client.queue offer { - if (client.fromLichess) msg + if client.fromLichess then msg else feat.socketMsg } } diff --git a/modules/round/src/main/actorApi.scala b/modules/round/src/main/actorApi.scala index 491ff1ddc022f..2f697c19e9309 100644 --- a/modules/round/src/main/actorApi.scala +++ b/modules/round/src/main/actorApi.scala @@ -46,7 +46,8 @@ package round: case class DrawNo(playerId: GamePlayerId) case class TakebackYes(playerId: GamePlayerId) case class TakebackNo(playerId: GamePlayerId) - object Moretime { val defaultDuration = 15.seconds } + object Moretime: + val defaultDuration = 15.seconds case class Moretime(playerId: GamePlayerId, seconds: FiniteDuration = Moretime.defaultDuration) case object QuietFlag case class ClientFlag(color: Color, fromPlayerId: Option[GamePlayerId]) diff --git a/modules/search/src/main/Env.scala b/modules/search/src/main/Env.scala index a1881f49a2138..68bbbf5a0302c 100644 --- a/modules/search/src/main/Env.scala +++ b/modules/search/src/main/Env.scala @@ -23,5 +23,5 @@ final class Env( private def makeHttp(index: Index): ESClientHttp = wire[ESClientHttp] val makeClient = (index: Index) => - if (config.enabled) makeHttp(index) + if config.enabled then makeHttp(index) else wire[ESClientStub] diff --git a/modules/search/src/main/Range.scala b/modules/search/src/main/Range.scala index d460ec91d813b..acb35e9ee4d39 100644 --- a/modules/search/src/main/Range.scala +++ b/modules/search/src/main/Range.scala @@ -17,7 +17,7 @@ object Range: def apply[A](a: Option[A], b: Option[A])(using o: Ordering[A]): Range[A] = (a, b) match case (Some(aa), Some(bb)) => - if (o.lt(aa, bb)) new Range(a, b) + if o.lt(aa, bb) then new Range(a, b) else new Range(b, a) case (x, y) => new Range(x, y) diff --git a/modules/security/src/main/DisposableEmailAttempt.scala b/modules/security/src/main/DisposableEmailAttempt.scala index fd7accd84cc17..fa6dc362dcd47 100644 --- a/modules/security/src/main/DisposableEmailAttempt.scala +++ b/modules/security/src/main/DisposableEmailAttempt.scala @@ -25,12 +25,12 @@ final class DisposableEmailAttempt( _.expireAfterWrite(1 day).build() } - def onFail(form: Form[?], ip: IpAddress): Unit = for { + def onFail(form: Form[?], ip: IpAddress): Unit = for email <- form("email").value flatMap EmailAddress.from if email.domain.exists(disposableApi.apply) str <- form("username").value u <- UserStr read str - } yield + yield val attempt = Attempt(u.id, email, ip) byIp.underlying.asMap.compute(ip, (_, attempts) => ~Option(attempts) + attempt).unit byId.underlying.asMap.compute(u.id, (_, attempts) => ~Option(attempts) + attempt).unit diff --git a/modules/security/src/main/DnsApi.scala b/modules/security/src/main/DnsApi.scala index d3d427bf9ccc2..82a330e245df5 100644 --- a/modules/security/src/main/DnsApi.scala +++ b/modules/security/src/main/DnsApi.scala @@ -32,7 +32,7 @@ final private class DnsApi( .map(_ split ' ') .collect { case Array(_, domain) => Domain.from { - if (domain endsWith ".") domain.init + if domain endsWith "." then domain.init else domain } } diff --git a/modules/security/src/main/EmailAddressValidator.scala b/modules/security/src/main/EmailAddressValidator.scala index 71f1cfb15e63d..bd7a4ef5faa35 100644 --- a/modules/security/src/main/EmailAddressValidator.scala +++ b/modules/security/src/main/EmailAddressValidator.scala @@ -17,7 +17,7 @@ final class EmailAddressValidator( import EmailAddressValidator.* val sendableConstraint = Constraint[EmailAddress]("constraint.email_acceptable") { email => - if (email.isSendable) Valid + if email.isSendable then Valid else Invalid(ValidationError("error.email_acceptable")) } @@ -25,13 +25,13 @@ final class EmailAddressValidator( Constraint[EmailAddress]("constraint.email_unique") { email => val (taken, reused) = (isTakenBySomeoneElse(email, forUser) zip wasUsedTwiceRecently(email)).await(2 seconds, "emailUnique") - if (taken || reused) Invalid(ValidationError("error.email_unique")) + if taken || reused then Invalid(ValidationError("error.email_unique")) else Valid } def differentConstraint(than: Option[EmailAddress]) = Constraint[EmailAddress]("constraint.email_different") { email => - if (than has email) Invalid(ValidationError("error.email_different")) + if than has email then Invalid(ValidationError("error.email_different")) else Valid } diff --git a/modules/security/src/main/EmailConfirm.scala b/modules/security/src/main/EmailConfirm.scala index e459549bec6df..12f042aaadda4 100644 --- a/modules/security/src/main/EmailConfirm.scala +++ b/modules/security/src/main/EmailConfirm.scala @@ -163,7 +163,7 @@ object EmailConfirm: userRepo withEmails u flatMap { case None => fuccess(NoSuchUser(u into UserName)) case Some(User.WithEmails(user, emails)) => - if (user.enabled.no) fuccess(Closed(user.username)) + if user.enabled.no then fuccess(Closed(user.username)) else userRepo mustConfirmEmail user.id dmap { if _ then diff --git a/modules/security/src/main/Env.scala b/modules/security/src/main/Env.scala index 88dc1d03a5e98..f6f80bd072f14 100644 --- a/modules/security/src/main/Env.scala +++ b/modules/security/src/main/Env.scala @@ -45,7 +45,7 @@ final class Env( lazy val flood = wire[Flood] lazy val hcaptcha: Hcaptcha = - if (config.hcaptcha.enabled) wire[HcaptchaReal] + if config.hcaptcha.enabled then wire[HcaptchaReal] else wire[HcaptchaSkip] lazy val forms = wire[SecurityForm] @@ -57,7 +57,7 @@ final class Env( lazy val store = Store(db(config.collection.security), cacheApi) lazy val ip2proxy: Ip2Proxy = - if (config.ip2Proxy.enabled && config.ip2Proxy.url.nonEmpty) + if config.ip2Proxy.enabled && config.ip2Proxy.url.nonEmpty then def mk = (url: String) => wire[Ip2ProxyServer] mk(config.ip2Proxy.url) else wire[Ip2ProxySkip] @@ -75,7 +75,7 @@ final class Env( mk((() => ugcArmedSetting.get())) lazy val emailConfirm: EmailConfirm = - if (config.emailConfirm.enabled) + if config.emailConfirm.enabled then EmailConfirmMailer( userRepo = userRepo, mailer = mailer, @@ -128,7 +128,7 @@ final class Env( lazy val promotion = wire[PromotionApi] - if (config.disposableEmail.enabled) + if config.disposableEmail.enabled then scheduler.scheduleOnce(33 seconds)(disposableEmailDomain.refresh()) scheduler.scheduleWithFixedDelay( config.disposableEmail.refreshDelay, @@ -139,7 +139,7 @@ final class Env( lazy val tor: Tor = wire[Tor] - if (config.tor.enabled) + if config.tor.enabled then scheduler.scheduleOnce(44 seconds)(tor.refresh.unit) scheduler.scheduleWithFixedDelay(config.tor.refreshDelay, config.tor.refreshDelay) { () => tor.refresh flatMap firewall.unblockIps diff --git a/modules/security/src/main/FingerPrint.scala b/modules/security/src/main/FingerPrint.scala index a99c720af6a12..9b34dba41d9ab 100644 --- a/modules/security/src/main/FingerPrint.scala +++ b/modules/security/src/main/FingerPrint.scala @@ -22,4 +22,4 @@ object FingerHash extends OpaqueString[FingerHash]: private def normalize(fp: FingerPrint): String = val str = fp.value.replace("-", "") - if (str.length % 2 != 0) s"${str}0" else str + if str.length % 2 != 0 then s"${str}0" else str diff --git a/modules/security/src/main/Firewall.scala b/modules/security/src/main/Firewall.scala index e2698e53e6cb7..4cb95574f08de 100644 --- a/modules/security/src/main/Firewall.scala +++ b/modules/security/src/main/Firewall.scala @@ -20,7 +20,7 @@ final class Firewall( val v = blocksIp { lila.common.HTTPRequest ipAddress req } - if (v) lila.mon.security.firewall.block.increment() + if v then lila.mon.security.firewall.block.increment() v def accepts(req: RequestHeader): Boolean = !blocks(req) diff --git a/modules/security/src/main/Hcaptcha.scala b/modules/security/src/main/Hcaptcha.scala index b58f8bd6b82b5..d5bbd78a24154 100644 --- a/modules/security/src/main/Hcaptcha.scala +++ b/modules/security/src/main/Hcaptcha.scala @@ -79,7 +79,7 @@ final class HcaptchaReal( def form[A](form: Form[A])(using req: RequestHeader): Fu[HcaptchaForm[A]] = skip.getFu map { skip => - lila.mon.security.hCaptcha.form(HTTPRequest clientName req, if (skip) "skip" else "show").increment() + lila.mon.security.hCaptcha.form(HTTPRequest clientName req, if skip then "skip" else "show").increment() HcaptchaForm(form, config.public, skip) } @@ -98,15 +98,15 @@ final class HcaptchaReal( res.body[JsValue].validate[GoodResponse] match case JsSuccess(res, _) => lila.mon.security.hCaptcha.hit(client, "success").increment() - if (res.success && res.hostname == netDomain.value) Result.Valid + if res.success && res.hostname == netDomain.value then Result.Valid else Result.Fail case JsError(err) => res.body[JsValue].validate[BadResponse].asOpt match case Some(err) if err.missingInput => - if (HTTPRequest.apiVersion(req).isDefined) + if HTTPRequest.apiVersion(req).isDefined then lila.mon.security.hCaptcha.hit(client, "api").increment() Result.Pass - else if (skip.get) + else if skip.get then lila.mon.security.hCaptcha.hit(client, "skip").increment() skip.record Result.Skip diff --git a/modules/security/src/main/Ip2Proxy.scala b/modules/security/src/main/Ip2Proxy.scala index f272033bec7b7..b6415967dcf16 100644 --- a/modules/security/src/main/Ip2Proxy.scala +++ b/modules/security/src/main/Ip2Proxy.scala @@ -56,7 +56,7 @@ final class Ip2ProxyServer( case Seq(ip) => apply(ip).dmap(Seq(_)) case ips => ips.flatMap(cache.getIfPresent).parallel flatMap { cached => - if (cached.sizeIs == ips.size) fuccess(cached) + if cached.sizeIs == ips.size then fuccess(cached) else ws.url(s"$checkUrl/batch") .addQueryStringParameters("ips" -> ips.mkString(",")) @@ -68,7 +68,7 @@ final class Ip2ProxyServer( } } .flatMap { res => - if (res.sizeIs == ips.size) fuccess(res) + if res.sizeIs == ips.size then fuccess(res) else fufail(s"Ip2Proxy missing results for $ips -> $res") } .addEffect { diff --git a/modules/security/src/main/IpTrust.scala b/modules/security/src/main/IpTrust.scala index 1b71e53be1c39..6d6dbaef3a347 100644 --- a/modules/security/src/main/IpTrust.scala +++ b/modules/security/src/main/IpTrust.scala @@ -5,18 +5,18 @@ import lila.common.IpAddress final class IpTrust(proxyApi: Ip2Proxy, geoApi: GeoIP, torApi: Tor, firewallApi: Firewall): def isSuspicious(ip: IpAddress): Fu[Boolean] = - if (firewallApi blocksIp ip) fuTrue - else if (torApi isExitNode ip) fuTrue + if firewallApi blocksIp ip then fuTrue + else if torApi isExitNode ip then fuTrue else val location = geoApi orUnknown ip - if (location == Location.unknown || location == Location.tor) fuTrue - else if (isUndetectedProxy(location)) fuTrue + if location == Location.unknown || location == Location.tor then fuTrue + else if isUndetectedProxy(location) then fuTrue else proxyApi(ip).dmap(_.is) def isSuspicious(ipData: UserLogins.IPData): Fu[Boolean] = isSuspicious(ipData.ip.value) - final class rateLimit(credits: Int, duration: FiniteDuration, key: String, factor: Int = 3) { + final class rateLimit(credits: Int, duration: FiniteDuration, key: String, factor: Int = 3): import lila.memo.{ RateLimit as RL } private val limiter = RL[IpAddress](credits, duration, key) def apply[A](ip: IpAddress, default: => Fu[A], cost: RL.Cost = 1, msg: => String = "")(op: => Fu[A])(using @@ -25,16 +25,15 @@ final class IpTrust(proxyApi: Ip2Proxy, geoApi: GeoIP, torApi: Tor, firewallApi: isSuspicious(ip).flatMap: susp => val realCost = cost * (if susp then factor else 1) limiter[Fu[A]](ip, default, realCost, msg)(op) - } /* lichess blacklist of proxies that ip2proxy doesn't know about */ private def isUndetectedProxy(location: Location): Boolean = location.shortCountry == "Iran" || - location.shortCountry == "United Arab Emirates" || (location match { + location.shortCountry == "United Arab Emirates" || (location match case Location("Poland", _, Some("Subcarpathian Voivodeship"), Some("Stalowa Wola")) => true case Location("Poland", _, Some("Lesser Poland Voivodeship"), Some("Krakow")) => true case Location("Russia", _, Some(region), Some("Ufa" | "Sterlitamak")) if region contains "Bashkortostan" => true case _ => false - }) + ) diff --git a/modules/security/src/main/Levenshtein.scala b/modules/security/src/main/Levenshtein.scala index 42cacf627e89e..9db55c9237a51 100644 --- a/modules/security/src/main/Levenshtein.scala +++ b/modules/security/src/main/Levenshtein.scala @@ -14,20 +14,20 @@ private object Levenshtein: ((i - (threshold - 1)) max 0) until (1 + ((i + t) min a.length)) @scala.annotation.tailrec def loop(j: Int, prev: Array[Int], prevr: Range, next: Array[Int]): Int = - if (j > b.length) prev.last + if j > b.length then prev.last else val c = b(j - 1) val q = rowRange(j) - for (i <- q) + for i <- q do next(i) = - if (i == 0) j + if i == 0 then j else - val t0 = if (i < prevr.end) prev(i) else inf - val t1 = 1 + (if (i > q.start) t0 min next(i - 1) else t0) - if (prevr.start < i) + val t0 = if i < prevr.end then prev(i) else inf + val t1 = 1 + (if i > q.start then t0 min next(i - 1) else t0) + if prevr.start < i then val t = prev(i - 1) - t1 min (if (c != a(i - 1)) 1 + t else t) + t1 min (if c != a(i - 1) then 1 + t else t) else t1 loop(j + 1, next, q, prev) loop(1, Array.range(0, a.length + 1), rowRange(0), Array.ofDim[Int](a.length + 1)) < threshold - if (a.lengthIs < b.length) f(b, a) else f(a, b) + if a.lengthIs < b.length then f(b, a) else f(a, b) diff --git a/modules/security/src/main/PrintBan.scala b/modules/security/src/main/PrintBan.scala index 637e046668b59..b740cc1015266 100644 --- a/modules/security/src/main/PrintBan.scala +++ b/modules/security/src/main/PrintBan.scala @@ -11,8 +11,8 @@ final class PrintBan(coll: Coll)(using Executor): def blocks(hash: FingerHash): Boolean = current contains hash.value def toggle(hash: FingerHash, block: Boolean): Funit = - current = if (block) current + hash.value else current - hash.value - if (block) + current = if block then current + hash.value else current - hash.value + if block then coll.update .one( $id(hash.value), diff --git a/modules/security/src/main/Promotion.scala b/modules/security/src/main/Promotion.scala index 93f9014d119f9..08b3465d8002c 100644 --- a/modules/security/src/main/Promotion.scala +++ b/modules/security/src/main/Promotion.scala @@ -13,7 +13,7 @@ final class PromotionApi(domain: NetDomain): val prevTextPromotion = prevText so extract val prev = ~cache.getIfPresent(me) -- prevTextPromotion val accept = prev.sizeIs < 3 && !prev.exists(promotions.contains) - if (!accept) logger.info(s"Promotion @${me.username} ${identify(text) mkString ", "}") + if !accept then logger.info(s"Promotion @${me.username} ${identify(text) mkString ", "}") accept } } diff --git a/modules/security/src/main/SecurityApi.scala b/modules/security/src/main/SecurityApi.scala index 2983867440af3..08a7784869844 100644 --- a/modules/security/src/main/SecurityApi.scala +++ b/modules/security/src/main/SecurityApi.scala @@ -97,7 +97,7 @@ final class SecurityApi( if _ then fufail(SecurityApi MustConfirmEmail userId) else val sessionId = SecureRandom nextString 22 - if (tor isExitNode HTTPRequest.ipAddress(req)) logger.info(s"Tor login $userId") + if tor isExitNode HTTPRequest.ipAddress(req) then logger.info(s"Tor login $userId") store.save(sessionId, userId, req, apiVersion, up = true, fp = none) inject sessionId } @@ -110,7 +110,7 @@ final class SecurityApi( private type AppealOrUser = Either[AppealUser, FingerPrintedUser] def restoreUser(req: RequestHeader): Fu[Option[AppealOrUser]] = firewall.accepts(req) so reqSessionId(req) so { sessionId => - appeal.authenticate(sessionId) match { + appeal.authenticate(sessionId) match case Some(userId) => userRepo byId userId map2 { u => Left(AppealUser(Me(u))) } case None => store.authInfo(sessionId) flatMapz { d => @@ -118,7 +118,7 @@ final class SecurityApi( _ map { me => Right(FingerPrintedUser(stripRolesOfCookieUser(me), d.hasFp)) } } } - }: Fu[Option[AppealOrUser]] + : Fu[Option[AppealOrUser]] } def oauthScoped( diff --git a/modules/security/src/main/Signup.scala b/modules/security/src/main/Signup.scala index 2e85954afab58..c0a678ca6d8b2 100644 --- a/modules/security/src/main/Signup.scala +++ b/modules/security/src/main/Signup.scala @@ -39,8 +39,8 @@ final class Signup( ): Fu[MustConfirmEmail] = val ip = HTTPRequest ipAddress req store.recentByIpExists(ip, 7.days) flatMap { ipExists => - if (ipExists) fuccess(YesBecauseIpExists) - else if (HTTPRequest weirdUA req) fuccess(YesBecauseUA) + if ipExists then fuccess(YesBecauseIpExists) + else if HTTPRequest weirdUA req then fuccess(YesBecauseUA) else print.fold[Fu[MustConfirmEmail]](fuccess(YesBecausePrintMissing)) { fp => store.recentByPrintExists(fp) map { printFound => @@ -109,9 +109,9 @@ final class Signup( apiVersion: Option[ApiVersion] )(user: User)(using RequestHeader, Lang): Fu[Signup.Result] = store.deletePreviousSessions(user) >> { - if (mustConfirm.value) + if mustConfirm.value then emailConfirm.send(user, email) >> { - if (emailConfirm.effective) + if emailConfirm.effective then api.saveSignup(user.id, apiVersion, fingerPrint) inject Signup.Result.ConfirmEmail(user, email) else fuccess(Signup.Result.AllSet(user, email)) diff --git a/modules/security/src/main/Store.scala b/modules/security/src/main/Store.scala index 4929720901a64..2187ecfeb832a 100644 --- a/modules/security/src/main/Store.scala +++ b/modules/security/src/main/Store.scala @@ -24,7 +24,7 @@ final class Store(val coll: Coll, cacheApi: lila.memo.CacheApi)(using .one[Bdoc] .map { _.flatMap { doc => - if (doc.getAsOpt[Instant]("date").fold(true)(_ isBefore nowInstant.minusHours(12))) + if doc.getAsOpt[Instant]("date").fold(true)(_ isBefore nowInstant.minusHours(12)) then coll.updateFieldUnchecked($id(id), "date", nowInstant) doc.getAsOpt[UserId]("user") map { AuthInfo(_, doc.contains("fp")) } } diff --git a/modules/security/src/main/UserLogins.scala b/modules/security/src/main/UserLogins.scala index 6c4485426615f..270fc33cb45e3 100644 --- a/modules/security/src/main/UserLogins.scala +++ b/modules/security/src/main/UserLogins.scala @@ -219,11 +219,10 @@ object UserLogins: case class WithMeSortedWithEmails[U: UserIdOf]( others: List[OtherUser[U]], emails: Map[UserId, EmailAddress] - ) { + ): def withUsers[V: UserIdOf](newUsers: List[V]) = copy(others = others.flatMap { o => newUsers.find(_ is o.user).map { u => o.copy(user = u) } }) - } def withMeSortedWithEmails( userRepo: UserRepo, @@ -243,8 +242,7 @@ object UserLogins: notes: List[lila.user.Note], bans: Map[UserId, Int], max: Int - ) { + ): def withUsers[V: UserIdOf](users: List[V]) = copy( othersWithEmail = othersWithEmail.withUsers(users) ) - } diff --git a/modules/security/src/main/model.scala b/modules/security/src/main/model.scala index 7575dc21e65d3..2b00da77593df 100644 --- a/modules/security/src/main/model.scala +++ b/modules/security/src/main/model.scala @@ -54,6 +54,6 @@ enum UserClient: case PC, Mob, App object UserClient: def apply(ua: UserAgent): UserClient = - if (ua.value contains "Lichobile") UserClient.App - else if (ua.value contains "Mobile") UserClient.Mob + if ua.value contains "Lichobile" then UserClient.App + else if ua.value contains "Mobile" then UserClient.Mob else UserClient.PC diff --git a/modules/security/src/test/Fixtures.scala b/modules/security/src/test/Fixtures.scala index 985999d99d23c..8755955092cf1 100644 --- a/modules/security/src/test/Fixtures.scala +++ b/modules/security/src/test/Fixtures.scala @@ -1,6 +1,6 @@ package lila.security -case object Fixtures { +case object Fixtures: def text = """ leeching.net @@ -1212,4 +1212,3 @@ zxcv.com zxcvbnm.com zzz.com """ -} diff --git a/modules/security/src/test/FloodTest.scala b/modules/security/src/test/FloodTest.scala index f74fa0e7bb85d..5aaf32ec91c80 100644 --- a/modules/security/src/test/FloodTest.scala +++ b/modules/security/src/test/FloodTest.scala @@ -2,9 +2,9 @@ package lila.security import java.time.Instant -class FloodTest extends munit.FunSuite { +class FloodTest extends munit.FunSuite: - import Flood._ + import Flood.* private def isDup = duplicateMessage _ @@ -33,4 +33,3 @@ class FloodTest extends munit.FunSuite { assert(isDup(m("hey"), List(m(s"hey!")))) assert(!isDup(m("hey"), List(m(s"hey!!")))) } -} diff --git a/modules/security/src/test/LevenshteinTest.scala b/modules/security/src/test/LevenshteinTest.scala index d8e3b9e4cdad4..8f8ce605c5a84 100644 --- a/modules/security/src/test/LevenshteinTest.scala +++ b/modules/security/src/test/LevenshteinTest.scala @@ -2,32 +2,25 @@ package lila.security import scala.util.Random import lila.common.base.StringUtils -object LevenshteinTest { - def check0(a: String, b: String): Boolean = { +object LevenshteinTest: + def check0(a: String, b: String): Boolean = val d = StringUtils.levenshtein(a, b) !Levenshtein.isDistanceLessThan(a, b, d) && Levenshtein.isDistanceLessThan(a, b, d + 1) - } def check(a: String, b: String) = check0(a, b) && check0(b, a) - def rndStr(r: Random, l: Int, sigma: Int): String = { + def rndStr(r: Random, l: Int, sigma: Int): String = val sb = new StringBuilder(l) - for (_ <- 0 until l) sb.append((48 + r.nextInt(sigma)).toChar) + for _ <- 0 until l do sb.append((48 + r.nextInt(sigma)).toChar) sb.result() - } - def rt(r: Random, l1: Int, l2: Int, sigma: Int) = { + def rt(r: Random, l1: Int, l2: Int, sigma: Int) = val s1 = rndStr(r, l1, sigma) val s2 = rndStr(r, l2, sigma) check(s1, s2) - } - def mt(seed: Int, nt: Int, l: Int, sigma: Int) = { + def mt(seed: Int, nt: Int, l: Int, sigma: Int) = val r = new Random(seed) - (0 until nt).forall(_ => { - rt(r, r.nextInt(l + 1), l, sigma) - }) - } -} + (0 until nt).forall(_ => rt(r, r.nextInt(l + 1), l, sigma)) -class LevenshteinTest extends munit.FunSuite { +class LevenshteinTest extends munit.FunSuite: import LevenshteinTest.{ check, mt } test("Levenshtein random") { assertEquals(mt(1, 1000, 10, 2), true) @@ -69,4 +62,3 @@ class LevenshteinTest extends munit.FunSuite { false ) } -} diff --git a/modules/security/src/test/SpamTest.scala b/modules/security/src/test/SpamTest.scala index 102ed8d3aea6a..9ccd3f88fc1c7 100644 --- a/modules/security/src/test/SpamTest.scala +++ b/modules/security/src/test/SpamTest.scala @@ -2,7 +2,7 @@ package lila.security import lila.common.Strings -class SpamTest extends munit.FunSuite { +class SpamTest extends munit.FunSuite: val spam = new Spam(() => Strings(Nil)) val foobar = """foo bar""" @@ -16,4 +16,3 @@ class SpamTest extends munit.FunSuite { assertEquals(spam.replace(foobar), foobar) assertEquals(spam.replace(_c2), """https://chess24.com""") } -} diff --git a/modules/setup/src/main/ApiAiConfig.scala b/modules/setup/src/main/ApiAiConfig.scala index 5717a076a6cfc..b78c73ea42c34 100644 --- a/modules/setup/src/main/ApiAiConfig.scala +++ b/modules/setup/src/main/ApiAiConfig.scala @@ -45,7 +45,7 @@ final case class ApiAiConfig( Player.make(chess.Black, user.map(_ only pt)) ), mode = chess.Mode.Casual, - source = if (chessGame.board.variant.fromPosition) Source.Position else Source.Ai, + source = if chessGame.board.variant.fromPosition then Source.Position else Source.Ai, daysPerTurn = makeDaysPerTurn, pgnImport = None ) diff --git a/modules/setup/src/main/Config.scala b/modules/setup/src/main/Config.scala index 6c467726c9c9c..e23c30f636b17 100644 --- a/modules/setup/src/main/Config.scala +++ b/modules/setup/src/main/Config.scala @@ -51,12 +51,13 @@ private[setup] trait Config: protected def justMakeClock = Clock.Config( Clock.LimitSeconds((time * 60).toInt), - if (clockHasTime) increment else Clock.IncrementSeconds(1) + if clockHasTime then increment else Clock.IncrementSeconds(1) ) def makeDaysPerTurn: Option[Days] = (timeMode == TimeMode.Correspondence) option days -trait Positional { self: Config => +trait Positional: + self: Config => def fen: Option[Fen.Epd] @@ -80,8 +81,8 @@ trait Positional { self: Config => startedAtPly = sit.ply, clock = makeClock.map(_.toClock) ) - if (Fen.write(game).isInitial) makeGame(chess.variant.Standard) -> none - else game -> baseState + if Fen.write(game).isInitial then makeGame(chess.variant.Standard) -> none + else game -> baseState } builder(chessGame) dmap { game => state.fold(game) { case sit @ Situation.AndFullMoveNumber(Situation(board, _), _) => @@ -98,7 +99,6 @@ trait Positional { self: Config => ) } } -} object Config extends BaseConfig diff --git a/modules/setup/src/main/SetupBulk.scala b/modules/setup/src/main/SetupBulk.scala index 63547ab7dd3b2..5b1f606b79917 100644 --- a/modules/setup/src/main/SetupBulk.scala +++ b/modules/setup/src/main/SetupBulk.scala @@ -39,7 +39,7 @@ object SetupBulk: def validFen = ApiConfig.validFen(variant, fen) def autoVariant = - if (variant.standard && fen.exists(!_.isInitial)) copy(variant = FromPosition) + if variant.standard && fen.exists(!_.isInitial) then copy(variant = FromPosition) else this private def timestampInNearFuture = longNumber( diff --git a/modules/setup/src/main/TimeMode.scala b/modules/setup/src/main/TimeMode.scala index 85cd207332c2f..cbecb549da3d3 100644 --- a/modules/setup/src/main/TimeMode.scala +++ b/modules/setup/src/main/TimeMode.scala @@ -17,6 +17,6 @@ object TimeMode: def orDefault(id: Int) = apply(id) | default def ofGame(game: lila.game.Game) = - if (game.hasClock) RealTime - else if (game.hasCorrespondenceClock) Correspondence + if game.hasClock then RealTime + else if game.hasCorrespondenceClock then Correspondence else Unlimited diff --git a/modules/setup/src/main/ValidFen.scala b/modules/setup/src/main/ValidFen.scala index 659964a1517e3..534fb4bfe572e 100644 --- a/modules/setup/src/main/ValidFen.scala +++ b/modules/setup/src/main/ValidFen.scala @@ -8,8 +8,8 @@ case class ValidFen(fen: Fen.Epd, situation: chess.Situation): object ValidFen: def apply(strict: Boolean)(fen: Fen.Epd): Option[ValidFen] = - for { + for parsed <- chess.format.Fen readWithMoveNumber fen if parsed.situation playable strict validated = chess.format.Fen write parsed - } yield ValidFen(validated, parsed.situation) + yield ValidFen(validated, parsed.situation) diff --git a/modules/shutup/src/main/PublicLine.scala b/modules/shutup/src/main/PublicLine.scala index 9433022826379..b195fba110f31 100644 --- a/modules/shutup/src/main/PublicLine.scala +++ b/modules/shutup/src/main/PublicLine.scala @@ -20,7 +20,7 @@ object PublicLine: import lila.db.dsl.* private given BSONHandler[Source] = lila.db.dsl.tryHandler[Source]( { case BSONString(v) => - v split ':' match { + v split ':' match case Array("t", id) => Success(Source.Tournament(TourId(id))) case Array("s", id) => Success(Source.Simul(SimulId(id))) case Array("w", id) => Success(Source.Watcher(GameId(id))) @@ -28,17 +28,16 @@ object PublicLine: case Array("e", id) => Success(Source.Team(TeamId(id))) case Array("i", id) => Success(Source.Swiss(SwissId(id))) case _ => lila.db.BSON.handlerBadValue(s"Invalid PublicLine source $v") - } }, x => - BSONString(x match { + BSONString(x match case Source.Tournament(id) => s"t:$id" case Source.Simul(id) => s"s:$id" case Source.Study(id) => s"u:$id" case Source.Watcher(gameId) => s"w:$gameId" case Source.Team(id) => s"e:$id" case Source.Swiss(id) => s"i:$id" - }) + ) ) private val objectHandler = Macros.handler[PublicLine] @@ -49,5 +48,5 @@ object PublicLine: case BSONString(text) => Success(PublicLine(text, none, none)) case a => lila.db.BSON.handlerBadValue(s"Invalid PublicLine $a") }, - x => if (x.from.isDefined) objectHandler.writeTry(x).get else BSONString(x.text) + x => if x.from.isDefined then objectHandler.writeTry(x).get else BSONString(x.text) ) diff --git a/modules/shutup/src/main/model.scala b/modules/shutup/src/main/model.scala index ed99fcdadf85b..daefc2bb9dfb5 100644 --- a/modules/shutup/src/main/model.scala +++ b/modules/shutup/src/main/model.scala @@ -29,9 +29,9 @@ case class TextAnalysis( lazy val nbWords = text.split("""\s+""").length def ratio: Double = { - if (nbWords == 0) 0 else badWords.size.toDouble / nbWords + if nbWords == 0 then 0 else badWords.size.toDouble / nbWords } * { - if (critical) 3 else 1 + if critical then 3 else 1 } def dirty = ratio > 0 diff --git a/modules/shutup/src/test/AnalyserTest.scala b/modules/shutup/src/test/AnalyserTest.scala index 15665b6ad9762..472373798f0db 100644 --- a/modules/shutup/src/test/AnalyserTest.scala +++ b/modules/shutup/src/test/AnalyserTest.scala @@ -4,7 +4,7 @@ package lila.shutup * We reject and condemn them. They are here so we can verify * that Lichess detects them, to help moderators keeping the site nice. */ -class AnalyserTest extends munit.FunSuite { +class AnalyserTest extends munit.FunSuite: private def find(t: String) = Analyser(t).badWords private def dirty(t: String) = Analyser(t).dirty @@ -85,4 +85,3 @@ class AnalyserTest extends munit.FunSuite { ) ) } -} diff --git a/modules/simul/src/main/JsonView.scala b/modules/simul/src/main/JsonView.scala index 374fc76a4db2b..9b87f7a4fa149 100644 --- a/modules/simul/src/main/JsonView.scala +++ b/modules/simul/src/main/JsonView.scala @@ -17,7 +17,7 @@ final class JsonView( )(using Executor): private def fetchGames(simul: Simul): Fu[List[Game]] = - if (simul.isFinished) gameRepo gamesFromSecondary simul.gameIds + if simul.isFinished then gameRepo gamesFromSecondary simul.gameIds else simul.gameIds.map(proxyRepo.game).parallel.dmap(_.flatten) def apply(simul: Simul, verdicts: WithVerdicts): Fu[JsObject] = for @@ -59,12 +59,12 @@ final class JsonView( started: List[Simul], finished: List[Simul] ): Fu[JsObject] = - for { + for pendingJson <- api(pending) createdJson <- api(created) startedJson <- api(started) finishedJson <- api(finished) - } yield Json.obj( + yield Json.obj( "pending" -> pendingJson, "created" -> createdJson, "started" -> startedJson, diff --git a/modules/simul/src/main/Simul.scala b/modules/simul/src/main/Simul.scala index 69017ae0d7d5d..a8ce7d07a817a 100644 --- a/modules/simul/src/main/Simul.scala +++ b/modules/simul/src/main/Simul.scala @@ -97,7 +97,7 @@ case class Simul( hasUser(userId) option removeApplicant(userId).removePairing(userId) private def finishIfDone = - if (isStarted && pairings.forall(_.finished)) + if isStarted && pairings.forall(_.finished) then copy( status = SimulStatus.Finished, finishedAt = nowInstant.some, @@ -128,7 +128,7 @@ case class Simul( def setPairingHostColor(gameId: GameId, hostColor: chess.Color) = updatePairing(gameId, _.copy(hostColor = hostColor)) - private def Created(s: => Simul): Simul = if (isCreated) s else this + private def Created(s: => Simul): Simul = if isCreated then s else this def wins = pairings.count(p => p.finished && p.wins.has(false)) def draws = pairings.count(p => p.finished && p.wins.isEmpty) diff --git a/modules/simul/src/main/SimulApi.scala b/modules/simul/src/main/SimulApi.scala index a64e37bf85f8d..b57a665e007df 100644 --- a/modules/simul/src/main/SimulApi.scala +++ b/modules/simul/src/main/SimulApi.scala @@ -139,7 +139,7 @@ final class SimulApi( } def onPlayerConnection(game: Game, user: Option[User])(simul: Simul): Unit = - if (user.exists(simul.isHost) && simul.isRunning) + if user.exists(simul.isHost) && simul.isRunning then repo.setHostGameId(simul, game.id) socket.hostIsOn(simul.id, game.id) diff --git a/modules/simul/src/main/SimulPairing.scala b/modules/simul/src/main/SimulPairing.scala index 917d0808cde8b..8e81233797098 100644 --- a/modules/simul/src/main/SimulPairing.scala +++ b/modules/simul/src/main/SimulPairing.scala @@ -24,7 +24,7 @@ final case class SimulPairing( def winnerColor = wins.map { w => - if (w) !hostColor else hostColor + if w then !hostColor else hostColor } private[simul] object SimulPairing: diff --git a/modules/socket/src/main/AnaDests.scala b/modules/socket/src/main/AnaDests.scala index 667dbaf384bf9..c82fede20e0ea 100644 --- a/modules/socket/src/main/AnaDests.scala +++ b/modules/socket/src/main/AnaDests.scala @@ -18,7 +18,7 @@ case class AnaDests( def isInitial = variant.standard && fen.isInitial && path == "" val dests: String = - if (isInitial) AnaDests.initialDests + if isInitial then AnaDests.initialDests else val sit = chess.Game(variant.some, fen.some).situation sit.playable(false) so destString(sit.destinations) diff --git a/modules/socket/src/main/AnaDrop.scala b/modules/socket/src/main/AnaDrop.scala index 748ff43c4d1e5..00a963051be99 100644 --- a/modules/socket/src/main/AnaDrop.scala +++ b/modules/socket/src/main/AnaDrop.scala @@ -37,7 +37,7 @@ case class AnaDrop( check = game.situation.check, dests = Some(movable so game.situation.destinations), opening = OpeningDb findByEpdFen fen, - drops = if (movable) game.situation.drops else Some(Nil), + drops = if movable then game.situation.drops else Some(Nil), crazyData = game.situation.board.crazyData ) diff --git a/modules/socket/src/main/AnaMove.scala b/modules/socket/src/main/AnaMove.scala index a4b3be6a57ee4..b3f0a9bc53218 100644 --- a/modules/socket/src/main/AnaMove.scala +++ b/modules/socket/src/main/AnaMove.scala @@ -44,7 +44,7 @@ case class AnaMove( dests = Some(movable so game.situation.destinations), opening = (game.ply <= 30 && Variant.list.openingSensibleVariants(variant)) so OpeningDb.findByEpdFen(fen), - drops = if (movable) game.situation.drops else Some(Nil), + drops = if movable then game.situation.drops else Some(Nil), crazyData = game.situation.board.crazyData ) diff --git a/modules/socket/src/main/RemoteSocket.scala b/modules/socket/src/main/RemoteSocket.scala index c6c5da4bb86e8..7286ced3a0c6d 100644 --- a/modules/socket/src/main/RemoteSocket.scala +++ b/modules/socket/src/main/RemoteSocket.scala @@ -65,13 +65,14 @@ final class RemoteSocket(redisClient: RedisClient, shutdown: CoordinatedShutdown ) { case SendTos(userIds, payload) => val connectedUsers = userIds intersect onlineUserIds.get - if (connectedUsers.nonEmpty) send(Out.tellUsers(connectedUsers, payload)) + if connectedUsers.nonEmpty then send(Out.tellUsers(connectedUsers, payload)) case SendTo(userId, payload) => - if (onlineUserIds.get.contains(userId)) send(Out.tellUser(userId, payload)) + if onlineUserIds.get.contains(userId) then send(Out.tellUser(userId, payload)) case SendToOnlineUser(userId, makePayload) => - if (onlineUserIds.get.contains(userId)) makePayload() foreach { payload => - send(Out.tellUser(userId, payload)) - } + if onlineUserIds.get.contains(userId) then + makePayload() foreach { payload => + send(Out.tellUser(userId, payload)) + } case Announce(_, _, json) => send(Out.tellAll(Json.obj("t" -> "announce", "d" -> json))) case Mlat(millis) => @@ -90,13 +91,13 @@ final class RemoteSocket(redisClient: RedisClient, shutdown: CoordinatedShutdown send(Out.impersonate(userId, modId)) case ApiUserIsOnline(userId, value) => send(Out.apiUserOnline(userId, value)) - if (value) onlineUserIds.getAndUpdate(_ + userId).unit + if value then onlineUserIds.getAndUpdate(_ + userId).unit case Follow(u1, u2) => send(Out.follow(u1, u2)) case UnFollow(u1, u2) => send(Out.unfollow(u1, u2)) } final class StoppableSender(val conn: PubSub[String, String], channel: Channel) extends Sender: - def apply(msg: String) = if (!stopping) super.send(channel, msg).unit + def apply(msg: String) = if !stopping then super.send(channel, msg).unit def sticky(_id: String, msg: String) = apply(msg) final class RoundRobinSender(val conn: PubSub[String, String], channel: Channel, parallelism: Int) @@ -106,7 +107,7 @@ final class RemoteSocket(redisClient: RedisClient, shutdown: CoordinatedShutdown def sticky(id: String, msg: String): Unit = publish(id.hashCode.abs % parallelism, msg) private def publish(subChannel: Int, msg: String) = - if (!stopping) conn.async.publish(s"$channel:$subChannel", msg).unit + if !stopping then conn.async.publish(s"$channel:$subChannel", msg).unit def makeSender(channel: Channel, parallelism: Int = 1): Sender = if parallelism > 1 then RoundRobinSender(redisClient.connectPubSub(), channel, parallelism) @@ -138,9 +139,10 @@ final class RemoteSocket(redisClient: RedisClient, shutdown: CoordinatedShutdown private def connectAndSubscribe(channel: Channel)(f: String => Unit): Funit = val conn = redisClient.connectPubSub() - conn.addListener(new pubsub.RedisPubSubAdapter[String, String] { - override def message(_channel: String, message: String): Unit = f(message) - }) + conn.addListener( + new pubsub.RedisPubSubAdapter[String, String]: + override def message(_channel: String, message: String): Unit = f(message) + ) val subPromise = Promise[Unit]() conn.async .subscribe(channel) @@ -222,21 +224,20 @@ object RemoteSocket: } case "lags" => Lags(commas(raw.args).flatMap { - _ split ':' match { + _ split ':' match case Array(user, l) => l.toIntOption map { lag => UserId(user) -> Centis(lag) } case _ => None - } }.toMap).some case "tell/sri" => raw.get(3)(tellSriMapper) case "tell/user" => raw.get(2) { case Array(user, payload) => - for { + for obj <- Json.parse(payload).asOpt[JsObject] typ <- obj str "t" - } yield TellUser(UserId(user), typ, obj) + yield TellUser(UserId(user), typ, obj) } case "req/response" => raw.get(2) { case Array(reqId, response) => @@ -247,15 +248,15 @@ object RemoteSocket: case _ => none def tellSriMapper: PartialFunction[Array[String], Option[TellSri]] = { case Array(sri, user, payload) => - for { + for obj <- Json.parse(payload).asOpt[JsObject] typ <- obj str "t" - } yield TellSri(Sri(sri), UserId from optional(user), typ, obj) + yield TellSri(Sri(sri), UserId from optional(user), typ, obj) } - def commas(str: String): Array[String] = if (str == "-") Array.empty else str split ',' + def commas(str: String): Array[String] = if str == "-" then Array.empty else str split ',' def boolean(str: String): Boolean = str == "+" - def optional(str: String): Option[String] = if (str == "-") None else Some(str) + def optional(str: String): Option[String] = if str == "-" then None else Some(str) object Out: def tellUser(userId: UserId, payload: JsObject) = @@ -286,8 +287,8 @@ object RemoteSocket: def pong(id: String) = s"pong $id" def stop(reqId: Int) = s"lila/stop $reqId" - def commas(strs: Iterable[Any]): String = if (strs.isEmpty) "-" else strs mkString "," - def boolean(v: Boolean): String = if (v) "+" else "-" + def commas(strs: Iterable[Any]): String = if strs.isEmpty then "-" else strs mkString "," + def boolean(v: Boolean): String = if v then "+" else "-" def optional(str: Option[String]) = str getOrElse "-" def color(c: Color): String = c.fold("w", "b") def color(c: Option[Color]): String = optional(c.map(_.fold("w", "b"))) diff --git a/modules/storm/src/main/StormBsonHandlers.scala b/modules/storm/src/main/StormBsonHandlers.scala index 2d6711bf4cbce..b63b80f7c613a 100644 --- a/modules/storm/src/main/StormBsonHandlers.scala +++ b/modules/storm/src/main/StormBsonHandlers.scala @@ -10,23 +10,22 @@ import lila.common.LichessDay object StormBsonHandlers: given puzzleReader: BSONDocumentReader[StormPuzzle] with - def readDocument(r: BSONDocument) = for { + def readDocument(r: BSONDocument) = for id <- r.getAsTry[PuzzleId]("_id") fen <- r.getAsTry[Fen.Epd]("fen") lineStr <- r.getAsTry[String]("line") line <- lineStr.split(' ').toList.flatMap(Uci.Move.apply).toNel.toTry("Empty move list?!") rating <- r.getAsTry[IntRating]("rating") - } yield StormPuzzle(id, fen, line, rating) + yield StormPuzzle(id, fen, line, rating) given BSONHandler[StormDay.Id] = val sep = ':' tryHandler[StormDay.Id]( { case BSONString(v) => - v split sep match { + v split sep match case Array(userId, dayStr) => Success(StormDay.Id(UserId(userId), LichessDay(Integer.parseInt(dayStr)))) case _ => handlerBadValue(s"Invalid storm day id $v") - } }, id => BSONString(s"${id.userId}$sep${id.day.value}") ) diff --git a/modules/storm/src/main/StormDay.scala b/modules/storm/src/main/StormDay.scala index df6571c7fb0f7..e9d4308054b40 100644 --- a/modules/storm/src/main/StormDay.scala +++ b/modules/storm/src/main/StormDay.scala @@ -21,7 +21,7 @@ case class StormDay( ): def add(run: StormForm.RunData) = { - if (run.score > score) + if run.score > score then copy( score = run.score, moves = run.moves, @@ -60,7 +60,7 @@ final class StormDayApi(coll: Coll, highApi: StormHighApi, perfsRepo: UserPerfsR ): Fu[Option[StormHigh.NewHigh]] = lila.mon.storm.run.score(user.isDefined).record(data.score).unit user so { u => - if (mobile || sign.check(u, ~data.signed)) + if mobile || sign.check(u, ~data.signed) then Bus.publish(lila.hub.actorApi.puzzle.StormRun(u.id, data.score), "stormRun") highApi get u.id flatMap { prevHigh => val todayId = Id today u.id @@ -78,15 +78,15 @@ final class StormDayApi(coll: Coll, highApi: StormHighApi, perfsRepo: UserPerfsR } } else - if (data.time > 40) - if (data.score > 99) logger.warn(s"badly signed run from ${u.username} $data") + if data.time > 40 then + if data.score > 99 then logger.warn(s"badly signed run from ${u.username} $data") lila.mon.storm.run - .sign(data.signed match { + .sign(data.signed match case None => "missing" case Some("") => "empty" case Some("undefined") => "undefined" case _ => "wrong" - }) + ) .increment() fuccess(none) } diff --git a/modules/storm/src/main/StormSelector.scala b/modules/storm/src/main/StormSelector.scala index 85cc836f2c683..8d0b162db3660 100644 --- a/modules/storm/src/main/StormSelector.scala +++ b/modules/storm/src/main/StormSelector.scala @@ -51,7 +51,7 @@ final class StormSelector(colls: PuzzleColls, cacheApi: CacheApi)(using Executor val fenColorRegex = $doc( "$regexMatch" -> $doc( "input" -> "$fen", - "regex" -> { if (scala.util.Random.nextBoolean()) " w " else " b " } + "regex" -> { if scala.util.Random.nextBoolean() then " w " else " b " } ) ) Facet( @@ -119,9 +119,8 @@ final class StormSelector(colls: PuzzleColls, cacheApi: CacheApi)(using Executor private def monitor(puzzles: Vector[StormPuzzle], poolSize: Int): Unit = val nb = puzzles.size lila.mon.storm.selector.count.record(nb) - if (nb < poolSize * 0.9) - logger.warn(s"Selector wanted $poolSize puzzles, only got $nb") - if (nb > 1) + if nb < poolSize * 0.9 then logger.warn(s"Selector wanted $poolSize puzzles, only got $nb") + if nb > 1 then val rest = puzzles.toVector drop 1 lila.common.Maths.mean(IntRating raw rest.map(_.rating)) foreach { r => lila.mon.storm.selector.rating.record(r.toInt).unit diff --git a/modules/storm/src/main/StormSign.scala b/modules/storm/src/main/StormSign.scala index 5bab9ecac9829..8aadc639d3d95 100644 --- a/modules/storm/src/main/StormSign.scala +++ b/modules/storm/src/main/StormSign.scala @@ -25,6 +25,6 @@ final class StormSign(secret: Secret, cacheApi: CacheApi): !Uptime.startedSinceMinutes(5) || { signer.sha1(store.get(user.id)) hash_= signed } - if (correct) store.put(user.id, signed) + if correct then store.put(user.id, signed) correct } diff --git a/modules/streamer/src/main/StreamerApi.scala b/modules/streamer/src/main/StreamerApi.scala index 69fa61c44490b..ab1622eb09efb 100644 --- a/modules/streamer/src/main/StreamerApi.scala +++ b/modules/streamer/src/main/StreamerApi.scala @@ -73,7 +73,7 @@ final class StreamerApi( }.parallel _ <- elements.nonEmpty so update.many(elements).void candidateIds <- cache.candidateIds.getUnit - yield if (streams.map(_.streamer.id).exists(candidateIds.contains)) cache.candidateIds.invalidateUnit() + yield if streams.map(_.streamer.id).exists(candidateIds.contains) then cache.candidateIds.invalidateUnit() def update(prev: Streamer, data: StreamerForm.UserData, asMod: Boolean): Fu[Streamer.ModChange] = val streamer = data(prev, asMod) diff --git a/modules/streamer/src/main/StreamerForm.scala b/modules/streamer/src/main/StreamerForm.scala index 82aa0f2e179c4..4723f83d3a2eb 100644 --- a/modules/streamer/src/main/StreamerForm.scala +++ b/modules/streamer/src/main/StreamerForm.scala @@ -86,13 +86,13 @@ object StreamerForm: updatedAt = nowInstant ) newStreamer.copy( - approval = approval.map(_.resolve) match { + approval = approval.map(_.resolve) match case Some(m) if asMod => streamer.approval.copy( granted = m.granted, tier = m.tier | streamer.approval.tier, requested = !m.granted && { - if (streamer.approval.requested != m.requested) m.requested + if streamer.approval.requested != m.requested then m.requested else streamer.approval.requested || m.requested }, ignored = m.ignored && !m.granted, @@ -105,7 +105,6 @@ object StreamerForm: newStreamer.twitch.fold(true)(streamer.twitch.has) && newStreamer.youTube.fold(true)(streamer.youTube.has) ) - } ) case class ApprovalData( diff --git a/modules/streamer/src/main/StreamerPager.scala b/modules/streamer/src/main/StreamerPager.scala index beca9e33a8c03..756ce3acac6fb 100644 --- a/modules/streamer/src/main/StreamerPager.scala +++ b/modules/streamer/src/main/StreamerPager.scala @@ -39,7 +39,7 @@ final class StreamerPager( def slice(offset: Int, length: Int): Fu[Seq[Streamer.WithContext]] = coll .aggregateList(length, _.sec): framework => - import framework._ + import framework.* Match( $doc( "approval.granted" -> true, @@ -74,7 +74,7 @@ final class StreamerPager( def slice(offset: Int, length: Int): Fu[Seq[Streamer.WithContext]] = coll .aggregateList(length, _.sec): framework => - import framework._ + import framework.* Match(selector) -> List( Sort(Ascending("updatedAt")), Skip(offset), diff --git a/modules/streamer/src/main/Streaming.scala b/modules/streamer/src/main/Streaming.scala index 049ac80d93e2f..9e9a52066c2e5 100644 --- a/modules/streamer/src/main/Streaming.scala +++ b/modules/streamer/src/main/Streaming.scala @@ -21,7 +21,7 @@ final private class Streaming( def getLiveStreams: LiveStreams = liveStreams LilaScheduler("Streaming", _.Every(15 seconds), _.AtMost(10 seconds), _.Delay(20 seconds)) { - for { + for streamerIds <- api.allListedIds activeIds = streamerIds.filter { id => liveStreams.has(id) || isOnline(id.userId) @@ -44,18 +44,18 @@ final private class Streaming( } } _ <- api.setLangLiveNow(streams.streams) - } yield publishStreams(streamers, streams) + yield publishStreams(streamers, streams) } private val streamStartOnceEvery = lila.memo.OnceEvery[UserId](2 hour) private def publishStreams(streamers: List[Streamer], newStreams: LiveStreams) = - if (newStreams != liveStreams) + if newStreams != liveStreams then newStreams.streams filterNot { s => liveStreams has s.streamer } foreach { s => import s.streamer.userId - if (streamStartOnceEvery(userId)) + if streamStartOnceEvery(userId) then Bus.publish( lila.hub.actorApi.streamer.StreamStart(userId, s.streamer.name.value), "streamStart" @@ -64,11 +64,11 @@ final private class Streaming( liveStreams = newStreams streamers foreach { streamer => streamer.twitch.foreach { t => - if (liveStreams.streams.exists(s => s.serviceName == "twitch" && s.is(streamer))) + if liveStreams.streams.exists(s => s.serviceName == "twitch" && s.is(streamer)) then lila.mon.tv.streamer.present(s"${t.userId}@twitch").increment() } streamer.youTube.foreach { t => - if (liveStreams.streams.exists(s => s.serviceName == "youTube" && s.is(streamer))) + if liveStreams.streams.exists(s => s.serviceName == "youTube" && s.is(streamer)) then lila.mon.tv.streamer.present(s"${t.channelId}@youtube").increment() } } diff --git a/modules/streamer/src/main/TwitchApi.scala b/modules/streamer/src/main/TwitchApi.scala index 76a98e650cbcb..297c7d5ee821a 100644 --- a/modules/streamer/src/main/TwitchApi.scala +++ b/modules/streamer/src/main/TwitchApi.scala @@ -49,7 +49,7 @@ final private class TwitchApi(ws: StandaloneWSClient, config: TwitchConfig)(usin } .monSuccess(_.tv.streamer.twitch) .flatMap { result => - if (result.data.exists(_.nonEmpty)) + if result.data.exists(_.nonEmpty) then fetchStreams(streamers, page + 1, result.pagination) map (result.liveStreams ::: _) else fuccess(Nil) } diff --git a/modules/study/src/main/BSONHandlers.scala b/modules/study/src/main/BSONHandlers.scala index 804ef82da734f..a6ad27987cec0 100644 --- a/modules/study/src/main/BSONHandlers.scala +++ b/modules/study/src/main/BSONHandlers.scala @@ -312,10 +312,9 @@ object BSONHandlers: given BSONHandler[Tag] = tryHandler[Tag]( { case BSONString(v) => - v.split(":", 2) match { + v.split(":", 2) match case Array(name, value) => Success(Tag(name, value)) case _ => handlerBadValue(s"Invalid pgn tag $v") - } }, t => BSONString(s"${t.name}:${t.value}") ) @@ -353,22 +352,21 @@ object BSONHandlers: import Study.From private[study] given BSONHandler[From] = tryHandler[From]( { case BSONString(v) => - v.split(' ') match { + v.split(' ') match case Array("scratch") => Success(From.Scratch) case Array("game", id) => Success(From.Game(GameId(id))) case Array("study", id) => Success(From.Study(StudyId(id))) case Array("relay") => Success(From.Relay(none)) case Array("relay", id) => Success(From.Relay(StudyId(id).some)) case _ => handlerBadValue(s"Invalid from $v") - } }, x => - BSONString(x match { + BSONString(x match case From.Scratch => "scratch" case From.Game(id) => s"game $id" case From.Study(id) => s"study $id" case From.Relay(id) => s"relay${id.fold("")(" " + _)}" - }) + ) ) import Settings.UserSelection private[study] given BSONHandler[UserSelection] = tryHandler[UserSelection]( @@ -401,7 +399,7 @@ object BSONHandlers: ) given BSONDocumentReader[Chapter.Metadata] with - def readDocument(doc: Bdoc) = for { + def readDocument(doc: Bdoc) = for id <- doc.getAsTry[StudyChapterId]("_id") name <- doc.getAsTry[StudyChapterName]("name") setup <- doc.getAsTry[Chapter.Setup]("setup") @@ -413,4 +411,4 @@ object BSONHandlers: .map(Outcome.fromResult) } hasRelayPath = doc.getAsOpt[Bdoc]("relay").flatMap(_ string "path").exists(_.nonEmpty) - } yield Chapter.Metadata(id, name, setup, outcome, hasRelayPath) + yield Chapter.Metadata(id, name, setup, outcome, hasRelayPath) diff --git a/modules/study/src/main/Chapter.scala b/modules/study/src/main/Chapter.scala index 515fa2934c97a..0015237cb390d 100644 --- a/modules/study/src/main/Chapter.scala +++ b/modules/study/src/main/Chapter.scala @@ -87,7 +87,7 @@ case class Chapter( def withoutChildren = copy(root = root.withoutChildren) - def withoutChildrenIfPractice = if (isPractice) copy(root = root.withoutChildren) else this + def withoutChildrenIfPractice = if isPractice then copy(root = root.withoutChildren) else this def relayAndTags = relay map { Chapter.RelayAndTags(id, _, tags) } diff --git a/modules/study/src/main/ChapterMaker.scala b/modules/study/src/main/ChapterMaker.scala index 6017a1cbead3f..92c6820ec5bb3 100644 --- a/modules/study/src/main/ChapterMaker.scala +++ b/modules/study/src/main/ChapterMaker.scala @@ -28,7 +28,7 @@ final private class ChapterMaker( } case Some(game) => fromGame(study, game, data, order, userId, withRatings) } map { (c: Chapter) => - if (c.name.value.isEmpty) c.copy(name = Chapter defaultName order) else c + if c.name.value.isEmpty then c.copy(name = Chapter defaultName order) else c } def fromFenOrPgnOrBlank(study: Study, data: Data, order: Int, userId: UserId): Fu[Chapter] = @@ -37,12 +37,12 @@ final private class ChapterMaker( case None => fuccess(fromFenOrBlank(study, data, order, userId)) private def fromPgn(study: Study, pgn: PgnStr, data: Data, order: Int, userId: UserId): Fu[Chapter] = - for { + for contributors <- lightUser.asyncMany(study.members.contributorIds.toList) parsed <- PgnImport(pgn, contributors.flatten).toFuture recoverWith { case e: Exception => fufail(ValidationException(e.getMessage)) } - } yield Chapter.make( + yield Chapter.make( studyId = study.id, name = getChapterNameFromPgn(data, parsed), setup = Chapter.Setup( @@ -133,10 +133,9 @@ final private class ChapterMaker( setup = Chapter.Setup( !game.synthetic option game.id, game.variant, - data.orientation match { + data.orientation match case Orientation.Auto => Color.white case Orientation.Fixed(color) => color - } ), root = root, tags = PgnTags(tags), @@ -148,7 +147,7 @@ final private class ChapterMaker( ) def notifyChat(study: Study, game: Game, userId: UserId) = - if (study.isPublic) + if study.isPublic then List(game hasUserId userId option game.id.value, s"${game.id}/w".some).flatten foreach { chatId => chatApi.userChat.write( chatId = ChatId(chatId), diff --git a/modules/study/src/main/ChapterRepo.scala b/modules/study/src/main/ChapterRepo.scala index a5d42e9aab1a6..265df1c7f9d39 100644 --- a/modules/study/src/main/ChapterRepo.scala +++ b/modules/study/src/main/ChapterRepo.scala @@ -11,7 +11,7 @@ import lila.db.AsyncColl import lila.db.dsl.{ *, given } import lila.tree.{ Branch, Branches } -import Node.{ BsonFields => F } +import Node.{ BsonFields as F } final class ChapterRepo(val coll: AsyncColl)(using Executor, akka.stream.Materializer): diff --git a/modules/study/src/main/CommentParser.scala b/modules/study/src/main/CommentParser.scala index 96cb7e18242dd..bacbd82435897 100644 --- a/modules/study/src/main/CommentParser.scala +++ b/modules/study/src/main/CommentParser.scala @@ -32,13 +32,13 @@ private[study] object CommentParser: private type ClockAndComment = (Option[Centis], String) private def readCentis(hours: String, minutes: String, seconds: String): Option[Centis] = - for { + for h <- hours.toIntOption m <- minutes.toIntOption cs <- seconds.toDoubleOption match case Some(s) => Some(Maths.roundAt(s * 100, 0).toInt) case _ => none - } yield Centis(h * 360000 + m * 6000 + cs) + yield Centis(h * 360000 + m * 6000 + cs) private val clockHourMinuteRegex = """^(\d++):(\d+)$""".r private val clockHourMinuteSecondRegex = """^(\d++):(\d++)[:\.](\d+)$""".r @@ -70,10 +70,10 @@ private[study] object CommentParser: comment match case circlesRegex(str) => val circles = str.split(',').toList.map(_.trim).flatMap { c => - for { + for color <- c.headOption pos <- Square fromKey c.drop(1) - } yield Shape.Circle(toBrush(color), pos) + yield Shape.Circle(toBrush(color), pos) } Shapes(circles) -> circlesRemoveRegex.replaceAllIn(comment, "").trim case _ => Shapes(Nil) -> comment @@ -82,11 +82,11 @@ private[study] object CommentParser: comment match case arrowsRegex(str) => val arrows = str.split(',').toList.flatMap { c => - for { + for color <- c.headOption orig <- Square fromKey c.slice(1, 3) dest <- Square fromKey c.slice(3, 5) - } yield Shape.Arrow(toBrush(color), orig, dest) + yield Shape.Arrow(toBrush(color), orig, dest) } Shapes(arrows) -> arrowsRemoveRegex.replaceAllIn(comment, "").trim case _ => Shapes(Nil) -> comment diff --git a/modules/study/src/main/ExplorerGame.scala b/modules/study/src/main/ExplorerGame.scala index b6a9bbb68d757..c95a945722420 100644 --- a/modules/study/src/main/ExplorerGame.scala +++ b/modules/study/src/main/ExplorerGame.scala @@ -20,7 +20,7 @@ final private class ExplorerGame( } def insert(study: Study, position: Position, gameId: GameId): Fu[Option[(Chapter, UciPath)]] = - if (position.chapter.isOverweight) + if position.chapter.isOverweight then logger.info(s"Overweight chapter ${study.id}/${position.chapter.id}") fuccess(none) else @@ -46,7 +46,7 @@ final private class ExplorerGame( val (path, foundGameNode) = gameNodes.foldLeft((UciPath.root, none[Branch])) { case ((path, None), gameNode) => val nextPath = path + gameNode.id - if (fromNode.children.nodeAt(nextPath).isDefined) (nextPath, none) + if fromNode.children.nodeAt(nextPath).isDefined then (nextPath, none) else (path, gameNode.some) case (found, _) => found } diff --git a/modules/study/src/main/PgnImport.scala b/modules/study/src/main/PgnImport.scala index 461825fc59edd..26b90a73f721c 100644 --- a/modules/study/src/main/PgnImport.scala +++ b/modules/study/src/main/PgnImport.scala @@ -90,11 +90,11 @@ object PgnImport: ( (shapes ++ s), c orElse clock, - (str.trim match { + (str.trim match case "" => comments case com => comments + Comment(Comment.Id.make, Comment.Text(com), annotator | Comment.Author.Lichess) - }) + ) ) } @@ -122,7 +122,7 @@ object PgnImport: val game = moveOrDrop.applyGame(prev) val uci = moveOrDrop.toUci val sanStr = moveOrDrop.toSanStr - parseComments(node.value.metas.comments, annotator) match { + parseComments(node.value.metas.comments, annotator) match case (shapes, clock, comments) => Branch( id = UciCharPair(uci), @@ -137,7 +137,6 @@ object PgnImport: crazyData = game.situation.board.crazyData, children = node.child.fold(Branches.empty)(makeBranches(game, _, annotator)) ).some - } ) catch case _: StackOverflowError => @@ -155,7 +154,7 @@ object PgnImport: case Some(main) if children.variations.exists(_.id == main.id) => Branches { main +: children.variations.flatMap { node => - if (node.id == main.id) node.children.nodes + if node.id == main.id then node.children.nodes else List(node) } } diff --git a/modules/study/src/main/PgnTags.scala b/modules/study/src/main/PgnTags.scala index 338037c725210..f0e1f7ba3053c 100644 --- a/modules/study/src/main/PgnTags.scala +++ b/modules/study/src/main/PgnTags.scala @@ -19,7 +19,7 @@ object PgnTags: }) private def removeContradictingTermination(tags: Tags) = - if (tags.outcome.isDefined) + if tags.outcome.isDefined then Tags(tags.value.filterNot { t => t.name == Tag.Termination && t.value.toLowerCase == "unterminated" }) diff --git a/modules/study/src/main/Study.scala b/modules/study/src/main/Study.scala index 7e5f3a2949227..5f730e9075357 100644 --- a/modules/study/src/main/Study.scala +++ b/modules/study/src/main/Study.scala @@ -40,7 +40,7 @@ case class Study( def isCurrent(c: Chapter.Like) = c.id == position.chapterId - def withChapter(c: Chapter.Like): Study = if (isCurrent(c)) this else rewindTo(c) + def withChapter(c: Chapter.Like): Study = if isCurrent(c) then this else rewindTo(c) def rewindTo(c: Chapter.Like): Study = copy(position = Position.Ref(chapterId = c.id, path = UciPath.root)) @@ -108,7 +108,7 @@ object Study: def compute(likes: Likes, createdAt: Instant) = Rank(createdAt plusHours likesToHours(likes)) private def likesToHours(likes: Likes): Int = - if (likes < 1) 0 + if likes < 1 then 0 else (5 * math.log(likes) + 1).toInt.min(likes) * 24 enum From: diff --git a/modules/study/src/main/StudyApi.scala b/modules/study/src/main/StudyApi.scala index 7e582dcb027ba..4f1ce3937b756 100644 --- a/modules/study/src/main/StudyApi.scala +++ b/modules/study/src/main/StudyApi.scala @@ -261,7 +261,7 @@ final class StudyApi( private def updateConceal(study: Study, chapter: Chapter, position: Position.Ref) = chapter.conceal so { conceal => chapter.root.lastMainlinePlyOf(position.path).some.filter(_ > conceal) so { newConceal => - if (newConceal >= chapter.root.lastMainlinePly) + if newConceal >= chapter.root.lastMainlinePly then chapterRepo.removeConceal(chapter.id) >>- sendTo(study.id)(_.setConceal(position, none)) else @@ -307,7 +307,7 @@ final class StudyApi( chapter .updateRoot: _.withChildren: children => - if (toMainline) children.promoteToMainlineAt(position.path) + if toMainline then children.promoteToMainlineAt(position.path) else children.promoteUpAt(position.path).map(_._1) .match case Some(newChapter) => @@ -520,7 +520,7 @@ final class StudyApi( sequenceStudyWithChapter(studyId, data.position.chapterId): case Study.WithChapter(study, chapter) => Contribute(who.u, study): - if (data.insert) + if data.insert then explorerGameHandler.insert(study, Position(chapter, data.position.path), data.gameId) flatMap { case None => fufail(s"Invalid explorerGame insert $studyId $data") >>- @@ -606,25 +606,24 @@ final class StudyApi( name = name, practice = data.isPractice option true, gamebook = data.isGamebook option true, - conceal = (chapter.conceal, data.isConceal) match { + conceal = (chapter.conceal, data.isConceal) match case (None, true) => chapter.root.ply.some case (Some(_), false) => None case _ => chapter.conceal - }, + , setup = chapter.setup.copy( - orientation = data.orientation match { + orientation = data.orientation match case ChapterMaker.Orientation.Fixed(color) => color case _ => chapter.setup.orientation - } ), description = data.hasDescription option { chapter.description | "-" } ) - if (chapter == newChapter) funit + if chapter == newChapter then funit else chapterRepo.update(newChapter) >> { - if (chapter.conceal != newChapter.conceal) + if chapter.conceal != newChapter.conceal then (newChapter.conceal.isDefined && study.position.chapterId == chapter.id).so { val newPosition = study.position.withPath(UciPath.root) studyRepo.setPosition(study.id, newPosition) @@ -637,7 +636,7 @@ final class StudyApi( (newChapter.practice != chapter.practice) || (newChapter.gamebook != chapter.gamebook) || (newChapter.description != chapter.description) - if (shouldReload) sendTo(study.id)(_.updateChapter(chapter.id, who)) + if shouldReload then sendTo(study.id)(_.updateChapter(chapter.id, who)) else reloadChapters(study) } } @@ -663,7 +662,7 @@ final class StudyApi( chapterRepo.byIdAndStudy(chapterId, studyId) flatMapz { chapter => chapterRepo.orderedMetadataByStudy(studyId).flatMap { chaps => // deleting the only chapter? Automatically create an empty one - if (chaps.sizeIs < 2) + if chaps.sizeIs < 2 then chapterMaker( study, ChapterMaker.Data(StudyChapterName("Chapter 1")), @@ -748,11 +747,12 @@ final class StudyApi( def like(studyId: StudyId, v: Boolean)(who: Who): Funit = studyRepo.like(studyId, who.u, v) map { likes => sendTo(studyId)(_.setLiking(Study.Liking(likes, v), who)) - if (v) studyRepo byId studyId foreach { - _.filter(_.isPublic) foreach { study => - timeline ! (Propagate(StudyLike(who.u, study.id, study.name)) toFollowersOf who.u) + if v then + studyRepo byId studyId foreach { + _.filter(_.isPublic) foreach { study => + timeline ! (Propagate(StudyLike(who.u, study.id, study.name)) toFollowersOf who.u) + } } - } } def chapterIdNames(studyIds: List[StudyId]): Fu[Map[StudyId, Vector[Chapter.IdName]]] = @@ -804,7 +804,7 @@ final class StudyApi( // work around circular dependency private var socket: Option[StudySocket] = None - private[study] def registerSocket(s: StudySocket) = { socket = s.some } + private[study] def registerSocket(s: StudySocket) = socket = s.some private def sendTo(studyId: StudyId)(f: StudySocket => StudyId => Unit): Unit = socket.foreach: s => f(s)(studyId) diff --git a/modules/study/src/main/StudyInvite.scala b/modules/study/src/main/StudyInvite.scala index 727f801d4f302..81a12b9cd8cd8 100644 --- a/modules/study/src/main/StudyInvite.scala +++ b/modules/study/src/main/StudyInvite.scala @@ -45,13 +45,13 @@ final private class StudyInvite( _ <- relation.has(Block) so fufail[Unit]("This user does not want to join") isPresent <- getIsPresent(invited.id) _ <- - if (isPresent || Granter(_.StudyAdmin)) funit + if isPresent || Granter(_.StudyAdmin) then funit else prefApi.get(invited).map(_.studyInvite).flatMap { case Pref.StudyInvite.ALWAYS => funit case Pref.StudyInvite.NEVER => fufail("This user doesn't accept study invitations") case Pref.StudyInvite.FRIEND => - if (relation.has(Follow)) funit + if relation.has(Follow) then funit else fufail("This user only accept study invitations from friends") } _ <- studyRepo.addMember(study, StudyMember make invited) diff --git a/modules/study/src/main/StudyMaker.scala b/modules/study/src/main/StudyMaker.scala index 4549de8f90f6c..5c14a0edef4d0 100644 --- a/modules/study/src/main/StudyMaker.scala +++ b/modules/study/src/main/StudyMaker.scala @@ -55,7 +55,7 @@ final private class StudyMaker( user: User, withRatings: Boolean ): Fu[Study.WithChapter] = { - for { + for root <- chapterMaker.makeRoot(pov.game, data.form.pgnStr, initialFen) tags <- pgnDump.tags(pov.game, initialFen, none, withOpening = true, withRatings) name <- StudyChapterName from Namer.gameVsText(pov.game, withRatings)(using lightUserApi.async) @@ -76,7 +76,7 @@ final private class StudyMaker( gamebook = false, conceal = None ) - } yield Study.WithChapter(study withChapter chapter, chapter) + yield Study.WithChapter(study withChapter chapter, chapter) } addEffect { swc => chapterMaker.notifyChat(swc.study, pov.game, user.id) } diff --git a/modules/study/src/main/StudyMember.scala b/modules/study/src/main/StudyMember.scala index 1ce29ee158dd6..4825bb5e1be88 100644 --- a/modules/study/src/main/StudyMember.scala +++ b/modules/study/src/main/StudyMember.scala @@ -25,7 +25,7 @@ case class StudyMembers(members: StudyMember.MemberMap): def update(id: UserId, f: StudyMember => StudyMember) = copy( members = members.view.mapValues { m => - if (m.id == id) f(m) else m + if m.id == id then f(m) else m }.toMap ) diff --git a/modules/study/src/main/StudyMultiBoard.scala b/modules/study/src/main/StudyMultiBoard.scala index 8045e50f90103..a4848712c1f71 100644 --- a/modules/study/src/main/StudyMultiBoard.scala +++ b/modules/study/src/main/StudyMultiBoard.scala @@ -23,7 +23,7 @@ final class StudyMultiBoard( import StudyMultiBoard.* def json(studyId: StudyId, page: Int, playing: Boolean): Fu[JsObject] = { - if (page == 1 && !playing) firstPageCache.get(studyId) + if page == 1 && !playing then firstPageCache.get(studyId) else fetch(studyId, page, playing) } map { PaginatorJson(_) } diff --git a/modules/study/src/main/StudyRepo.scala b/modules/study/src/main/StudyRepo.scala index db644c3147d59..266690f02480a 100644 --- a/modules/study/src/main/StudyRepo.scala +++ b/modules/study/src/main/StudyRepo.scala @@ -244,7 +244,7 @@ final class StudyRepo(private[study] val coll: AsyncColl)(using def like(studyId: StudyId, userId: UserId, v: Boolean): Fu[Study.Likes] = coll: c => - c.update.one($id(studyId), if (v) $addToSet(F.likers -> userId) else $pull(F.likers -> userId)) >> { + c.update.one($id(studyId), if v then $addToSet(F.likers -> userId) else $pull(F.likers -> userId)) >> { countLikes(studyId).flatMap: case None => fuccess(Study.Likes(0)) case Some((likes, createdAt)) => @@ -273,11 +273,11 @@ final class StudyRepo(private[study] val coll: AsyncColl)(using ) .cursor[Bdoc]() .foldWhileM(0) { (count, doc) => - ~(for { + ~(for id <- doc.getAsOpt[StudyId]("_id") likes <- doc.getAsOpt[Study.Likes](F.likes) createdAt <- doc.getAsOpt[Instant](F.createdAt) - } yield coll: + yield coll: _.update .one( $id(id), diff --git a/modules/study/src/main/StudyTopic.scala b/modules/study/src/main/StudyTopic.scala index ecc99b3ec68f9..532a91c010c9f 100644 --- a/modules/study/src/main/StudyTopic.scala +++ b/modules/study/src/main/StudyTopic.scala @@ -77,7 +77,7 @@ final class StudyTopicApi(topicRepo: StudyTopicRepo, userTopicRepo: StudyUserTop def userTopics(user: User, json: String): Funit = val topics = - if (json.trim.isEmpty) StudyTopics.empty + if json.trim.isEmpty then StudyTopics.empty else Json.parse(json).validate[List[TagifyTopic]] match case JsSuccess(topics, _) => StudyTopics.fromStrs(topics.map(_.value), StudyTopics.userMax) diff --git a/modules/study/src/main/TreeBuilder.scala b/modules/study/src/main/TreeBuilder.scala index 9116bf49c9e5f..a2169d6a16b81 100644 --- a/modules/study/src/main/TreeBuilder.scala +++ b/modules/study/src/main/TreeBuilder.scala @@ -11,7 +11,7 @@ object TreeBuilder: // DEBUG should be done in BSONHandler def apply(root: Root, variant: Variant): Root = val dests = - if (variant.standard && root.fen.isInitial) initialStandardDests + if variant.standard && root.fen.isInitial then initialStandardDests else val sit = chess.Game(variant.some, root.fen.some).situation sit.playable(false) so sit.destinations diff --git a/modules/study/src/test/CommentParserTest.scala b/modules/study/src/test/CommentParserTest.scala index f6a247a8c43cd..4fd7dc3af4dca 100644 --- a/modules/study/src/test/CommentParserTest.scala +++ b/modules/study/src/test/CommentParserTest.scala @@ -3,7 +3,7 @@ package lila.study import chess.Centis import lila.tree.Node.Shapes -class CommentParserTest extends lila.common.LilaTest { +class CommentParserTest extends lila.common.LilaTest: import chess.format.pgn.Comment import scala.language.implicitConversions @@ -121,4 +121,3 @@ class CommentParserTest extends lila.common.LilaTest { shapes.value.size == 6 && clock == Some(Centis(3843300)) } -} diff --git a/modules/studySearch/src/main/Env.scala b/modules/studySearch/src/main/Env.scala index e39a7772f3118..9dcb3bd2d0ac6 100644 --- a/modules/studySearch/src/main/Env.scala +++ b/modules/studySearch/src/main/Env.scala @@ -31,11 +31,11 @@ final class Env( def apply(me: Option[User])(text: String, page: Int) = Paginator[Study.WithChaptersAndLiked]( - adapter = new AdapterLike[Study] { + adapter = new AdapterLike[Study]: def query = Query(text take 100, me.map(_.id)) def nbResults = api count query def slice(offset: Int, length: Int) = api.search(query, From(offset), Size(length)) - } mapFutureList pager.withChaptersAndLiking(me), + mapFutureList pager.withChaptersAndLiking(me), currentPage = page, maxPerPage = pager.maxPerPage ) diff --git a/modules/studySearch/src/main/StudySearchApi.scala b/modules/studySearch/src/main/StudySearchApi.scala index 8d4f8c5138f04..9f2ceffdb354d 100644 --- a/modules/studySearch/src/main/StudySearchApi.scala +++ b/modules/studySearch/src/main/StudySearchApi.scala @@ -107,7 +107,7 @@ final class StudySearchApi( case c: ESClientHttp => { val sinceOption: Either[Unit, Option[LocalDate]] = - if (sinceStr == "reset") Left(()) else Right(parseDate(sinceStr)) + if sinceStr == "reset" then Left(()) else Right(parseDate(sinceStr)) val since = sinceOption match case Right(None) => sys error "Missing since date argument" case Right(Some(date)) => diff --git a/modules/swiss/src/main/PairingSystem.scala b/modules/swiss/src/main/PairingSystem.scala index df7866e44643c..9950284cf6999 100644 --- a/modules/swiss/src/main/PairingSystem.scala +++ b/modules/swiss/src/main/PairingSystem.scala @@ -21,8 +21,8 @@ final private class PairingSystem(trf: SwissTrf, executable: String)(using private def invoke(swiss: Swiss, input: Source[String, ?]): Fu[List[String]] = withTempFile(swiss, input) { file => val flavour = - if (swiss.nbPlayers < 250) "dutch" - else if (swiss.nbPlayers < 700) "burstein" + if swiss.nbPlayers < 250 then "dutch" + else if swiss.nbPlayers < 700 then "burstein" else "fast" val command = s"$executable --$flavour $file -p" val stdout = new collection.mutable.ListBuffer[String] @@ -32,9 +32,9 @@ final private class PairingSystem(trf: SwissTrf, executable: String)(using command ! ProcessLogger(stdout append _, stderr append _ unit) } } - if (status != 0) + if status != 0 then val error = stderr.toString - if (error contains "No valid pairing exists") Nil + if error contains "No valid pairing exists" then Nil else throw PairingSystem.BBPairingException(error, swiss) else stdout.toList } @@ -49,10 +49,10 @@ final private class PairingSystem(trf: SwissTrf, executable: String)(using Left(SwissPairing.Bye(userId)) } case Array(w, b) => - for { + for white <- w.toIntOption flatMap idsToPlayers.get black <- b.toIntOption flatMap idsToPlayers.get - } yield Right(SwissPairing.Pending(white, black)) + yield Right(SwissPairing.Pending(white, black)) } .flatten diff --git a/modules/swiss/src/main/Swiss.scala b/modules/swiss/src/main/Swiss.scala index 6eec1c181d385..6227839f1dd59 100644 --- a/modules/swiss/src/main/Swiss.scala +++ b/modules/swiss/src/main/Swiss.scala @@ -54,8 +54,8 @@ case class Swiss( def estimatedDurationString = val minutes = estimatedDuration.toMinutes - if (minutes < 60) s"${minutes}m" - else s"${minutes / 60}h" + (if (minutes % 60 != 0) s" ${minutes % 60}m" else "") + if minutes < 60 then s"${minutes}m" + else s"${minutes / 60}h" + (if minutes % 60 != 0 then s" ${minutes % 60}m" else "") def roundInfo = Swiss.RoundInfo(teamId, settings.chatFor) diff --git a/modules/swiss/src/main/SwissApi.scala b/modules/swiss/src/main/SwissApi.scala index e79e01b5c7000..fb79844e6ade7 100644 --- a/modules/swiss/src/main/SwissApi.scala +++ b/modules/swiss/src/main/SwissApi.scala @@ -87,16 +87,17 @@ final class SwissApi( def update(swissId: SwissId, data: SwissForm.SwissData): Fu[Option[Swiss]] = Sequencing(swissId)(cache.swissCache.byId): old => val position = - if (old.isCreated || old.settings.position.isDefined) data.realVariant.standard so data.realPosition + if old.isCreated || old.settings.position.isDefined then + data.realVariant.standard so data.realPosition else old.settings.position val swiss = old.copy( name = data.name | old.name, - clock = if (old.isCreated) data.clock else old.clock, - variant = if (old.isCreated && data.variant.isDefined) data.realVariant else old.variant, + clock = if old.isCreated then data.clock else old.clock, + variant = if old.isCreated && data.variant.isDefined then data.realVariant else old.variant, startsAt = data.startsAt.ifTrue(old.isCreated) | old.startsAt, nextRoundAt = - if (old.isCreated) Some(data.startsAt | old.startsAt) + if old.isCreated then Some(data.startsAt | old.startsAt) else old.nextRoundAt, settings = old.settings.copy( nbRounds = data.nbRounds, @@ -105,7 +106,7 @@ final class SwissApi( position = position, chatFor = data.chatFor | old.settings.chatFor, roundInterval = - if (data.roundInterval.isDefined) data.realRoundInterval + if data.roundInterval.isDefined then data.realRoundInterval else old.settings.roundInterval, password = data.password, conditions = data.conditions, @@ -113,12 +114,9 @@ final class SwissApi( manualPairings = ~data.manualPairings ) ) pipe { s => - if ( - s.isStarted && s.nbOngoing == 0 && (s.nextRoundAt.isEmpty || old.settings.manualRounds) && !s.settings.manualRounds - ) - s.copy(nextRoundAt = nowInstant.plusSeconds(s.settings.roundInterval.toSeconds.toInt).some) - else if (s.settings.manualRounds && !old.settings.manualRounds) - s.copy(nextRoundAt = none) + if s.isStarted && s.nbOngoing == 0 && (s.nextRoundAt.isEmpty || old.settings.manualRounds) && !s.settings.manualRounds + then s.copy(nextRoundAt = nowInstant.plusSeconds(s.settings.roundInterval.toSeconds.toInt).some) + else if s.settings.manualRounds && !old.settings.manualRounds then s.copy(nextRoundAt = none) else s } mongo.swiss.update.one($id(old.id), addFeaturable(swiss)).void >> { @@ -388,7 +386,7 @@ final class SwissApi( private[swiss] def finishGame(game: Game): Funit = game.swissId.so: swissId => Sequencing(swissId)(cache.swissCache.byId): swiss => - if (!swiss.isStarted) + if !swiss.isStarted then logger.info(s"Removing pairing ${game.id} finished after swiss ${swiss.id}") mongo.pairing.delete.one($id(game.id)) inject false else @@ -399,11 +397,10 @@ final class SwissApi( Right(game.winnerColor): SwissPairing.Status ) .flatMap { result => - if (result.nModified == 0) fuccess(false) // dedup + if result.nModified == 0 then fuccess(false) // dedup else { - if (swiss.nbOngoing > 0) - mongo.swiss.update.one($id(swiss.id), $inc("nbOngoing" -> -1)) + if swiss.nbOngoing > 0 then mongo.swiss.update.one($id(swiss.id), $inc("nbOngoing" -> -1)) else fuccess: logger.warn(s"swiss ${swiss.id} nbOngoing = ${swiss.nbOngoing}") @@ -415,9 +412,10 @@ final class SwissApi( .void } >> { (swiss.nbOngoing <= 1) so { - if (swiss.round.value == swiss.settings.nbRounds) doFinish(swiss) - else if (swiss.settings.manualRounds) fuccess: - systemChat(swiss.id, s"Round ${swiss.round.value + 1} needs to be scheduled.") + if swiss.round.value == swiss.settings.nbRounds then doFinish(swiss) + else if swiss.settings.manualRounds then + fuccess: + systemChat(swiss.id, s"Round ${swiss.round.value + 1} needs to be scheduled.") else mongo.swiss .updateField( @@ -447,7 +445,7 @@ final class SwissApi( private[swiss] def finish(oldSwiss: Swiss): Funit = Sequencing(oldSwiss.id)(cache.swissCache.startedById): swiss => mongo.pairing.exists($doc(SwissPairing.Fields.swissId -> swiss.id)) flatMap { - if (_) doFinish(swiss) + if _ then doFinish(swiss) else destroy(swiss) } private def doFinish(swiss: Swiss): Funit = @@ -467,7 +465,7 @@ final class SwissApi( .void zip SwissPairing.fields { f => mongo.pairing.delete.one($doc(f.swissId -> swiss.id, f.status -> true)) map { res => - if (res.n > 0) logger.warn(s"Swiss ${swiss.id} finished with ${res.n} ongoing pairings") + if res.n > 0 then logger.warn(s"Swiss ${swiss.id} finished with ${res.n} ongoing pairings") } } void } >>- { @@ -485,12 +483,12 @@ final class SwissApi( } def kill(swiss: Swiss): Funit = { - if (swiss.isStarted) + if swiss.isStarted then finish(swiss) >>- { logger.info(s"Tournament ${swiss.id} cancelled by its creator.") systemChat(swiss.id, "Tournament cancelled by its creator.") } - else if (swiss.isCreated) destroy(swiss) + else if swiss.isCreated then destroy(swiss) else funit } >>- cache.featuredInTeam.invalidate(swiss.teamId) @@ -522,10 +520,10 @@ final class SwissApi( .flatMap: _.traverse_ : id => Sequencing(id)(cache.swissCache.notFinishedById) { swiss => - if (swiss.round.value >= swiss.settings.nbRounds) doFinish(swiss) - else if (swiss.nbPlayers >= 2) + if swiss.round.value >= swiss.settings.nbRounds then doFinish(swiss) + else if swiss.nbPlayers >= 2 then countPresentPlayers(swiss) flatMap { nbPresent => - if (nbPresent < 2) + if nbPresent < 2 then systemChat(swiss.id, "Not enough players left.") doFinish(swiss) else @@ -545,7 +543,7 @@ final class SwissApi( } } >>- cache.swissCache.clear(swiss.id) } - else if (swiss.startsAt isBefore nowInstant.minusMinutes(60)) destroy(swiss) + else if swiss.startsAt isBefore nowInstant.minusMinutes(60) then destroy(swiss) else systemChat(swiss.id, "Not enough players for first round; delaying start.", volatile = true) mongo.swiss.update @@ -586,10 +584,9 @@ final class SwissApi( lila.mon.swiss.games("ongoing").record(ongoing.size) lila.mon.swiss.games("flagged").record(flagged.size) lila.mon.swiss.games("missing").record(missingIds.size) - if (flagged.nonEmpty) + if flagged.nonEmpty then Bus.publish(lila.hub.actorApi.map.TellMany(flagged.map(_.id.value), QuietFlag), "roundSocket") - if (missingIds.nonEmpty) - mongo.pairing.delete.one($inIds(missingIds)) + if missingIds.nonEmpty then mongo.pairing.delete.one($inIds(missingIds)) finished } } flatMap { diff --git a/modules/swiss/src/main/SwissBan.scala b/modules/swiss/src/main/SwissBan.scala index bbaff76bafab0..a5b86f3f19022 100644 --- a/modules/swiss/src/main/SwissBan.scala +++ b/modules/swiss/src/main/SwissBan.scala @@ -21,7 +21,7 @@ final class SwissBanApi(mongo: SwissMongo)(using Executor): def onGameFinish(game: Game) = game.userIds .map { userId => - if (game.playerWhoDidNotMove.exists(_.userId has userId)) onStall(userId) + if game.playerWhoDidNotMove.exists(_.userId has userId) then onStall(userId) else onGoodGame(userId) } .parallel @@ -30,8 +30,8 @@ final class SwissBanApi(mongo: SwissMongo)(using Executor): private def onStall(user: UserId): Funit = get(user) flatMap { prev => val hours: Int = prev .fold(24) { ban => - if (ban.until.isBefore(nowInstant)) ban.hours * 2 // consecutive - else (ban.hours * 1.5).toInt // simultaneous + if ban.until.isBefore(nowInstant) then ban.hours * 2 // consecutive + else (ban.hours * 1.5).toInt // simultaneous } .atMost(30 * 24) mongo.ban.update diff --git a/modules/swiss/src/main/SwissBoard.scala b/modules/swiss/src/main/SwissBoard.scala index 4eba7a26aaf2d..d046687c79508 100644 --- a/modules/swiss/src/main/SwissBoard.scala +++ b/modules/swiss/src/main/SwissBoard.scala @@ -55,14 +55,14 @@ final private class SwissBoardApi( .distinct .take(displayBoards) .flatMap { pairing => - for { + for p1 <- playerMap get pairing.white p2 <- playerMap get pairing.black u1 <- lightUserApi sync p1.userId u2 <- lightUserApi sync p2.userId r1 <- ranks get p1.userId r2 <- ranks get p2.userId - } yield SwissBoard( + yield SwissBoard( pairing.gameId, white = SwissBoard.Player(u1, r1, p1.rating), black = SwissBoard.Player(u2, r2, p2.rating) diff --git a/modules/swiss/src/main/SwissCondition.scala b/modules/swiss/src/main/SwissCondition.scala index c07c604d7f884..84eb9a0ebf69b 100644 --- a/modules/swiss/src/main/SwissCondition.scala +++ b/modules/swiss/src/main/SwissCondition.scala @@ -7,7 +7,7 @@ import lila.user.{ Me, UserPerfs } import lila.gathering.{ Condition, ConditionList } import lila.gathering.Condition.* import alleycats.Zero -import lila.i18n.{ I18nKeys => trans } +import lila.i18n.{ I18nKeys as trans } import lila.rating.Perf object SwissCondition: diff --git a/modules/swiss/src/main/SwissDirector.scala b/modules/swiss/src/main/SwissDirector.scala index 8451b737eb391..66113438f209d 100644 --- a/modules/swiss/src/main/SwissDirector.scala +++ b/modules/swiss/src/main/SwissDirector.scala @@ -23,10 +23,10 @@ final private class SwissDirector( (manualPairing(from) | pairingSystem(from)) .flatMap { pendings => val pendingPairings = pendings.collect { case Right(p) => p } - if (pendingPairings.isEmpty) fuccess(none) // terminate + if pendingPairings.isEmpty then fuccess(none) // terminate else val swiss = from.startRound - for { + for players <- SwissPlayer.fields { f => mongo.player.list[SwissPlayer]($doc(f.swissId -> swiss.id)) } @@ -67,10 +67,10 @@ final private class SwissDirector( games = pairings.map(makeGame(swiss, players.mapBy(_.userId))) _ <- games.traverse_ : game => gameRepo.insertDenormalized(game) >>- onStart(game.id) - } yield swiss.some + yield swiss.some } .recover { case PairingSystem.BBPairingException(msg, input) => - if (msg contains "The number of rounds is larger than the reported number of rounds.") none + if msg contains "The number of rounds is larger than the reported number of rounds." then none else logger.warn(s"BBPairing ${from.id} $msg") logger.info(s"BBPairing ${from.id} $input") @@ -84,7 +84,7 @@ final private class SwissDirector( chess = chess .Game( variantOption = Some { - if (swiss.settings.position.isEmpty) swiss.variant + if swiss.settings.position.isEmpty then swiss.variant else chess.variant.FromPosition }, fen = swiss.settings.position diff --git a/modules/swiss/src/main/SwissForm.scala b/modules/swiss/src/main/SwissForm.scala index 5b0e8d85ccc8f..ddb4619b3430e 100644 --- a/modules/swiss/src/main/SwissForm.scala +++ b/modules/swiss/src/main/SwissForm.scala @@ -60,7 +60,7 @@ final class SwissForm(using mode: Mode): name = none, clock = ClockConfig(LimitSeconds(180), IncrementSeconds(0)), startsAt = Some(nowInstant plusSeconds { - if (mode == Mode.Prod) 60 * 10 else 20 + if mode == Mode.Prod then 60 * 10 else 20 }), variant = Variant.default.key.some, rated = true.some, @@ -110,7 +110,7 @@ object SwissForm: LimitSeconds raw clockLimits, l => s"${chess.Clock.Config(LimitSeconds(l), IncrementSeconds(0)).limitString}${ - if (l <= 1) " minute" else " minutes" + if l <= 1 then " minute" else " minutes" }" ) @@ -141,11 +141,11 @@ object SwissForm: val roundIntervalChoices = options( roundIntervals, s => - if (s == Swiss.RoundInterval.auto) s"Automatic" - else if (s == Swiss.RoundInterval.manual) s"Manually schedule each round" - else if (s < 60) s"$s seconds" - else if (s < 3600) s"${s / 60} minute(s)" - else if (s < 24 * 3600) s"${s / 3600} hour(s)" + if s == Swiss.RoundInterval.auto then s"Automatic" + else if s == Swiss.RoundInterval.manual then s"Manually schedule each round" + else if s < 60 then s"$s seconds" + else if s < 3600 then s"${s / 60} minute(s)" + else if s < 24 * 3600 then s"${s / 3600} hour(s)" else s"${s / 24 / 3600} days(s)" ) diff --git a/modules/swiss/src/main/SwissJson.scala b/modules/swiss/src/main/SwissJson.scala index 320cea7e6ac78..e6399642dd443 100644 --- a/modules/swiss/src/main/SwissJson.scala +++ b/modules/swiss/src/main/SwissJson.scala @@ -42,14 +42,14 @@ final class SwissJson( socketVersion: Option[SocketVersion] = None, playerInfo: Option[SwissPlayer.ViewExt] = None )(using lang: Lang): Fu[JsObject] = { - for { + for myInfo <- me.so { fetchMyInfo(swiss, _) } page = reqPage orElse myInfo.map(_.page) getOrElse 1 standing <- standingApi(swiss, page) podium <- podiumJson(swiss) boards <- boardApi(swiss.id) stats <- statsApi(swiss) - } yield swissJsonBase(swiss) ++ Json + yield swissJsonBase(swiss) ++ Json .obj( "canJoin" -> { { @@ -167,8 +167,8 @@ object SwissJson: "nbPlayers" -> swiss.nbPlayers, "nbOngoing" -> swiss.nbOngoing, "status" -> { - if (swiss.isStarted) "started" - else if (swiss.isFinished) "finished" + if swiss.isStarted then "started" + else if swiss.isFinished then "finished" else "created" } ) @@ -241,8 +241,8 @@ object SwissJson: private def pairingJsonMin(player: SwissPlayer, pairing: SwissPairing): String = val status = - if (pairing.isOngoing) "o" - else pairing.resultFor(player.userId).fold("d") { r => if (r) "w" else "l" } + if pairing.isOngoing then "o" + else pairing.resultFor(player.userId).fold("d") { r => if r then "w" else "l" } s"${pairing.gameId}$status" private def pairingJson(player: SwissPlayer, pairing: SwissPairing) = diff --git a/modules/swiss/src/main/SwissOfficialSchedule.scala b/modules/swiss/src/main/SwissOfficialSchedule.scala index 8c2991e9441c0..f0d19fbabf7fd 100644 --- a/modules/swiss/src/main/SwissOfficialSchedule.scala +++ b/modules/swiss/src/main/SwissOfficialSchedule.scala @@ -57,7 +57,7 @@ final private class SwissOfficialSchedule(mongo: SwissMongo, cache: SwissCache)( } .parallel .map { res => - if (res.exists(identity)) cache.featuredInTeam.invalidate(lichessTeamId) + if res.exists(identity) then cache.featuredInTeam.invalidate(lichessTeamId) } private def makeSwiss(config: Config, startAt: Instant) = diff --git a/modules/swiss/src/main/SwissPairing.scala b/modules/swiss/src/main/SwissPairing.scala index 9610a538ef185..5ddc547950621 100644 --- a/modules/swiss/src/main/SwissPairing.scala +++ b/modules/swiss/src/main/SwissPairing.scala @@ -16,14 +16,14 @@ case class SwissPairing( def players = List(white, black) def has(userId: UserId) = white == userId || black == userId def colorOf(userId: UserId) = chess.Color.fromWhite(white == userId) - def opponentOf(userId: UserId) = if (white == userId) black else white + def opponentOf(userId: UserId) = if white == userId then black else white def winner: Option[UserId] = (~status.toOption).map(apply) def isOngoing = status.isLeft def resultFor(userId: UserId) = winner.map(userId.==) def whiteWins = status == Right(Some(Color.White)) def blackWins = status == Right(Some(Color.Black)) def isDraw = status == Right(None) - def strResultOf(color: Color) = status.fold(_ => "*", _.fold("1/2")(c => if (c == color) "1" else "0")) + def strResultOf(color: Color) = status.fold(_ => "*", _.fold("1/2")(c => if c == color then "1" else "0")) def forfeit(userId: UserId) = copy(status = Right(Some(!colorOf(userId))), isForfeit = true) object SwissPairing: diff --git a/modules/swiss/src/main/SwissSheet.scala b/modules/swiss/src/main/SwissSheet.scala index 629d5342cea86..80deee3d36bd2 100644 --- a/modules/swiss/src/main/SwissSheet.scala +++ b/modules/swiss/src/main/SwissSheet.scala @@ -77,8 +77,8 @@ private object SwissSheet: case Left(_) => Ongoing case Right(None) => Draw case Right(Some(color)) if pairing.isForfeit => - if (pairing(color) == player.userId) ForfeitWin else ForfeitLoss - case Right(Some(color)) => if (pairing(color) == player.userId) Win else Loss + if pairing(color) == player.userId then ForfeitWin else ForfeitLoss + case Right(Some(color)) => if pairing(color) == player.userId then Win else Loss case None if player.byes(round) => Bye case None if round.value == 1 => Late case None => Absent diff --git a/modules/swiss/src/main/SwissStandingApi.scala b/modules/swiss/src/main/SwissStandingApi.scala index 1b906cf52f6ce..750736d1ef8b4 100644 --- a/modules/swiss/src/main/SwissStandingApi.scala +++ b/modules/swiss/src/main/SwissStandingApi.scala @@ -27,7 +27,7 @@ final class SwissStandingApi( def apply(swiss: Swiss, forPage: Int): Fu[JsObject] = val page = forPage atMost Math.ceil(swiss.nbPlayers.toDouble / perPage).toInt atLeast 1 fuccess(pageCache.getIfPresent(swiss.id -> page)) getOrElse { - if (page == 1) first get swiss.id + if page == 1 then first get swiss.id else compute(swiss, page) } @@ -73,7 +73,7 @@ final class SwissStandingApi( mongo.swiss.byId[Swiss](id) orFail s"No such tournament: $id" flatMap { compute(_, page) } private def compute(swiss: Swiss, page: Int): Fu[JsObject] = - for { + for rankedPlayers <- bestWithRankByPage(swiss.id, perPage, page atLeast 1) pairings <- !swiss.isCreated so SwissPairing.fields { f => mongo.pairing @@ -85,7 +85,7 @@ final class SwissStandingApi( } sheets = SwissSheet.many(swiss, rankedPlayers.map(_.player), pairings) users <- lightUserApi asyncManyFallback rankedPlayers.map(_.player.userId) - } yield Json.obj( + yield Json.obj( "page" -> page, "players" -> rankedPlayers .zip(users) diff --git a/modules/swiss/src/main/SwissStats.scala b/modules/swiss/src/main/SwissStats.scala index 693e44bf78a53..d94a41223ac8c 100644 --- a/modules/swiss/src/main/SwissStats.scala +++ b/modules/swiss/src/main/SwissStats.scala @@ -50,14 +50,14 @@ final class SwissStatsApi( blackWins + pairing.blackWins.so(1), draws + pairing.isDraw.so(1) ) - } match { + } match case (games, whiteWins, blackWins, draws) => sheet.outcomes.foldLeft((0, 0)) { case ((byes, absences), outcome) => ( byes + (outcome == SwissSheet.Outcome.Bye).so(1), absences + (outcome == SwissSheet.Outcome.Absent).so(1) ) - } match { + } match case (byes, absences) => stats.copy( games = stats.games + games, @@ -68,8 +68,6 @@ final class SwissStatsApi( absences = stats.absences + absences, averageRating = stats.averageRating + player.rating ) - } - } })(Keep.right) .run() .dmap { s => diff --git a/modules/swiss/src/main/SwissTrf.scala b/modules/swiss/src/main/SwissTrf.scala index 83d7d1187d38a..703439b793234 100644 --- a/modules/swiss/src/main/SwissTrf.scala +++ b/modules/swiss/src/main/SwissTrf.scala @@ -63,7 +63,7 @@ final class SwissTrf( 97 -> pairing.map(_ colorOf p.userId).so(_.fold("w", "b")), 99 -> { import SwissSheet.Outcome.* - outcome match { + outcome match case Absent => "-" case Late => "H" case Bye => "U" @@ -73,7 +73,6 @@ final class SwissTrf( case Ongoing => "Z" case ForfeitLoss => "-" case ForfeitWin => "+" - } } ).map { case (l, s) => (l + (rn.value - 1) * 10, s) } } @@ -113,16 +112,16 @@ final class SwissTrf( .toMap private def forbiddenPairings(swiss: Swiss, playerIds: PlayerIds): Source[String, ?] = - if (swiss.settings.forbiddenPairings.isEmpty) Source.empty[String] + if swiss.settings.forbiddenPairings.isEmpty then Source.empty[String] else Source.fromIterator { () => swiss.settings.forbiddenPairings.linesIterator.flatMap { _.trim.toLowerCase.split(' ').map(_.trim) match case Array(u1, u2) if u1 != u2 => - for { + for id1 <- playerIds.get(UserId(u1)) id2 <- playerIds.get(UserId(u2)) - } yield s"XXP $id1 $id2" + yield s"XXP $id1 $id2" case _ => none } } diff --git a/modules/swiss/src/test/SwissScoringTest.scala b/modules/swiss/src/test/SwissScoringTest.scala index 645261b78a6f5..8d45735847a43 100644 --- a/modules/swiss/src/test/SwissScoringTest.scala +++ b/modules/swiss/src/test/SwissScoringTest.scala @@ -91,7 +91,8 @@ class SwissScoringTest extends munit.FunSuite: extension (e: SwissPlayer) def pointsAndTieBreak: (Float, Float) = (e.points.value, e.tieBreak.value.toFloat) - def print = { println(e); e } + def print = + println(e); e def makeUserId(name: Char) = UserId(s"user-$name") def makeSwissId = SwissId("swissId") diff --git a/modules/team/src/main/MemberRepo.scala b/modules/team/src/main/MemberRepo.scala index 6252741d151dc..0c54ad7d05318 100644 --- a/modules/team/src/main/MemberRepo.scala +++ b/modules/team/src/main/MemberRepo.scala @@ -43,7 +43,7 @@ final class MemberRepo(val coll: Coll)(using Executor): coll.update .one( selectId(teamId, userId), - if (v) $unset("unsub") + if v then $unset("unsub") else $set("unsub" -> true) ) .void diff --git a/modules/team/src/main/PaginatorBuilder.scala b/modules/team/src/main/PaginatorBuilder.scala index 20028050904db..afc6a9e9fc391 100644 --- a/modules/team/src/main/PaginatorBuilder.scala +++ b/modules/team/src/main/PaginatorBuilder.scala @@ -53,7 +53,7 @@ final private[team] class PaginatorBuilder( final private class TeamAdapter(val team: Team) extends AdapterLike[LightUser] with MembersAdapter: def slice(offset: Int, length: Int): Fu[Seq[LightUser]] = - for { + for docs <- memberRepo.coll .find(selector, $doc("user" -> true, "_id" -> false).some) @@ -63,13 +63,13 @@ final private[team] class PaginatorBuilder( .list(length) userIds = docs.flatMap(_.getAsOpt[UserId]("user")) users <- lightUserApi asyncManyFallback userIds - } yield users + yield users final private class TeamAdapterWithDate(val team: Team) extends AdapterLike[TeamMember.UserAndDate] with MembersAdapter: def slice(offset: Int, length: Int): Fu[Seq[TeamMember.UserAndDate]] = - for { + for docs <- memberRepo.coll .find(selector, $doc("user" -> true, "date" -> true, "_id" -> false).some) @@ -80,7 +80,7 @@ final private[team] class PaginatorBuilder( userIds = docs.flatMap(_.getAsOpt[UserId]("user")) dates = docs.flatMap(_.getAsOpt[Instant]("date")) users <- lightUserApi asyncManyFallback userIds - } yield users.zip(dates) map TeamMember.UserAndDate.apply + yield users.zip(dates) map TeamMember.UserAndDate.apply def declinedRequests(team: Team, page: Int): Fu[Paginator[RequestWithUser]] = Paginator( diff --git a/modules/team/src/main/Request.scala b/modules/team/src/main/Request.scala index a00d42a0037f0..afd3b89450bb2 100644 --- a/modules/team/src/main/Request.scala +++ b/modules/team/src/main/Request.scala @@ -29,7 +29,7 @@ object Request: ) case class RequestWithUser(request: Request, user: User.WithPerfs): - export request.{ user => _, * } + export request.{ user as _, * } object RequestWithUser: def combine(reqs: List[Request], users: List[User.WithPerfs]): List[RequestWithUser] = for diff --git a/modules/team/src/main/Team.scala b/modules/team/src/main/Team.scala index 9e47e8705a269..ec5c48df368a2 100644 --- a/modules/team/src/main/Team.scala +++ b/modules/team/src/main/Team.scala @@ -57,7 +57,7 @@ object Team: val maxJoinCeiling = 50 def maxJoin(u: User) = - if (u.isVerified) maxJoinCeiling * 2 + if u.isVerified then maxJoinCeiling * 2 else { 15 + daysBetween(u.createdAt, nowInstant) / 7 @@ -124,7 +124,7 @@ object Team: def nameToId(name: String) = lila.common.String.slugify(name) pipe { slug => // if most chars are not latin, go for random slug - if (slug.lengthIs > (name.length / 2)) TeamId(slug) else randomId() + if slug.lengthIs > (name.length / 2) then TeamId(slug) else randomId() } private[team] def randomId() = TeamId(ThreadLocalRandom nextString 8) diff --git a/modules/team/src/main/TeamApi.scala b/modules/team/src/main/TeamApi.scala index 96d1d80d39b73..76eed5d3dfe87 100644 --- a/modules/team/src/main/TeamApi.scala +++ b/modules/team/src/main/TeamApi.scala @@ -112,7 +112,7 @@ final class TeamApi( cached .teamIdsList(userIdOf(member)) .map(_.take(lila.team.Team.maxJoinCeiling)) flatMap { allIds => - if (viewer.exists(_ is member) || Granter.opt(_.UserModView)) fuccess(allIds) + if viewer.exists(_ is member) || Granter.opt(_.UserModView) then fuccess(allIds) else allIds.nonEmpty.so: teamRepo.filterHideMembers(allIds) flatMap { hiddenIds => @@ -331,18 +331,16 @@ final class TeamApi( } def toggleEnabled(team: Team, explain: String)(using me: Me): Funit = - if ( - Granter(_.ManageTeam) || me.is(team.createdBy) || + if Granter(_.ManageTeam) || me.is(team.createdBy) || (team.leaders(me) && !team.leaders(team.createdBy)) - ) + then logger.info(s"toggleEnabled ${team.id}: ${!team.enabled} by @${me}: $explain") - if (team.enabled) + if team.enabled then teamRepo.disable(team).void >> memberRepo.userIdsByTeam(team.id).map { _ foreach cached.invalidateTeamIds } >> requestRepo.removeByTeam(team.id).void >>- (indexer ! RemoveTeam(team.id)) - else - teamRepo.enable(team).void >>- (indexer ! InsertTeam(team)) + else teamRepo.enable(team).void >>- (indexer ! InsertTeam(team)) else teamRepo.setLeaders(team.id, team.leaders - me) // delete for ever, with members but not forums diff --git a/modules/teamSearch/src/main/Env.scala b/modules/teamSearch/src/main/Env.scala index 1221627f12af3..22669b3eb76c9 100644 --- a/modules/teamSearch/src/main/Env.scala +++ b/modules/teamSearch/src/main/Env.scala @@ -42,12 +42,12 @@ final class Env( } system.actorOf( - Props(new Actor { + Props(new Actor: import lila.team.{ InsertTeam, RemoveTeam } def receive = { case InsertTeam(team) => api.store(team).unit case RemoveTeam(id) => client.deleteById(id into Id).unit } - }), + ), name = config.actorName ) diff --git a/modules/timeline/src/main/EntryApi.scala b/modules/timeline/src/main/EntryApi.scala index e810b9ad44dec..12544f5e54b9d 100644 --- a/modules/timeline/src/main/EntryApi.scala +++ b/modules/timeline/src/main/EntryApi.scala @@ -88,11 +88,11 @@ final class EntryApi( bcs.headOption.fold(entries) { mostRecentBc => val interleaved = val oldestEntry = entries.lastOption - if (oldestEntry.fold(true)(_.date isBefore mostRecentBc.date)) + if oldestEntry.fold(true)(_.date isBefore mostRecentBc.date) then (entries ++ bcs).sortBy(-_.date.toMillis) else entries // sneak recent broadcast at first place - if (mostRecentBc.date.isAfter(nowInstant minusDays 1)) + if mostRecentBc.date.isAfter(nowInstant minusDays 1) then mostRecentBc +: interleaved.filter(mostRecentBc !=) else interleaved } diff --git a/modules/timeline/src/main/TimelinePush.scala b/modules/timeline/src/main/TimelinePush.scala index 462bd1e460eef..1a874654e46e7 100644 --- a/modules/timeline/src/main/TimelinePush.scala +++ b/modules/timeline/src/main/TimelinePush.scala @@ -21,14 +21,15 @@ final private[timeline] class TimelinePush( private val dedup = lila.memo.OnceEvery.hashCode[Atom](10 minutes) def receive = { case Propagate(data, propagations) => - if (dedup(data)) propagate(propagations) flatMap { users => - unsubApi.filterUnsub(data.channel, users) - } foreach { users => - if (users.nonEmpty) - insertEntry(users, data) >>- - lila.common.Bus.publish(ReloadTimelines(users), "lobbySocket") - lila.mon.timeline.notification.increment(users.size) - } + if dedup(data) then + propagate(propagations) flatMap { users => + unsubApi.filterUnsub(data.channel, users) + } foreach { users => + if users.nonEmpty then + insertEntry(users, data) >>- + lila.common.Bus.publish(ReloadTimelines(users), "lobbySocket") + lila.mon.timeline.notification.increment(users.size) + } } private def propagate(propagations: List[Propagation]): Fu[List[UserId]] = diff --git a/modules/timeline/src/main/UnsubApi.scala b/modules/timeline/src/main/UnsubApi.scala index 9a780febe5de5..2a36e0efe91df 100644 --- a/modules/timeline/src/main/UnsubApi.scala +++ b/modules/timeline/src/main/UnsubApi.scala @@ -11,7 +11,7 @@ final class UnsubApi(coll: Coll)(using Executor): private def select(channel: String, userId: UserId) = $id(makeId(channel, userId)) def set(channel: String, userId: UserId, v: Boolean): Funit = { - if (v) coll.insert.one(select(channel, userId)).void + if v then coll.insert.one(select(channel, userId)).void else coll.delete.one(select(channel, userId)).void } recover { case _: Exception => () diff --git a/modules/tournament/src/main/AutoPairing.scala b/modules/tournament/src/main/AutoPairing.scala index ae6c0f91f1fa2..12119277b8f51 100644 --- a/modules/tournament/src/main/AutoPairing.scala +++ b/modules/tournament/src/main/AutoPairing.scala @@ -19,7 +19,7 @@ final class AutoPairing( chess = chess .Game( variantOption = Some { - if (tour.position.isEmpty) tour.variant + if tour.position.isEmpty then tour.variant else chess.variant.FromPosition }, fen = fen diff --git a/modules/tournament/src/main/ColorHistory.scala b/modules/tournament/src/main/ColorHistory.scala index c8e76b8316254..a609d360b4087 100644 --- a/modules/tournament/src/main/ColorHistory.scala +++ b/modules/tournament/src/main/ColorHistory.scala @@ -9,10 +9,10 @@ import lila.memo.CacheApi case class ColorHistory(strike: Int, balance: Int) extends Ordered[ColorHistory]: override def compare(that: ColorHistory): Int = - if (strike < that.strike) -1 - else if (strike > that.strike) 1 - else if (balance < that.balance) -1 - else if (balance > that.balance) 1 + if strike < that.strike then -1 + else if strike > that.strike then 1 + else if balance < that.balance then -1 + else if balance > that.balance then 1 else 0 def firstGetsWhite(that: ColorHistory)(fallback: () => Boolean) = diff --git a/modules/tournament/src/main/Duel.scala b/modules/tournament/src/main/Duel.scala index cdd558dea1c97..3642a0606bab4 100644 --- a/modules/tournament/src/main/Duel.scala +++ b/modules/tournament/src/main/Duel.scala @@ -51,7 +51,7 @@ final private class DuelStore: get(tour.id) flatMap { _.find(_ has user).map(_.gameId) } def add(tour: Tournament, game: Game, p1: UsernameRating, p2: UsernameRating, ranking: Ranking): Unit = - for { + for p1 <- tbUser(p1, ranking) p2 <- tbUser(p2, ranking) tb = Duel( @@ -60,22 +60,21 @@ final private class DuelStore: p2 = p2, averageRating = IntRating((p1.rating.value + p2.rating.value) / 2) ) - } byTourId.compute( - tour.id, - (_: TourId, v: TreeSet[Duel]) => { - if (v == null) TreeSet(tb)(gameIdOrdering) - else v + tb - } - ) + do + byTourId.compute( + tour.id, + (_: TourId, v: TreeSet[Duel]) => + if v == null then TreeSet(tb)(gameIdOrdering) + else v + tb + ) def remove(game: Game): Unit = game.tournamentId foreach { tourId => byTourId.computeIfPresent( tourId, - (_: TourId, tb: TreeSet[Duel]) => { + (_: TourId, tb: TreeSet[Duel]) => val w = tb - emptyGameId(game.id) - if (w.isEmpty) null else w - } + if w.isEmpty then null else w ) } def remove(tour: Tournament): Unit = byTourId.remove(tour.id).unit diff --git a/modules/tournament/src/main/Env.scala b/modules/tournament/src/main/Env.scala index 1fd4ab5fa0e73..da23e62036988 100644 --- a/modules/tournament/src/main/Env.scala +++ b/modules/tournament/src/main/Env.scala @@ -71,8 +71,8 @@ final class Env( clearWinnersCache = winners.clearCache, clearTrophyCache = tour => { - if (tour.isShield) scheduler.scheduleOnce(10 seconds) { shieldApi.clear() } - else if (Revolution is tour) scheduler.scheduleOnce(10 seconds) { revolutionApi.clear() }.unit + if tour.isShield then scheduler.scheduleOnce(10 seconds) { shieldApi.clear() } + else if Revolution is tour then scheduler.scheduleOnce(10 seconds) { revolutionApi.clear() }.unit }.unit, indexLeaderboard = leaderboardIndexer.indexOne ) diff --git a/modules/tournament/src/main/JsonView.scala b/modules/tournament/src/main/JsonView.scala index 532ac9faa4a2d..2c2b425564398 100644 --- a/modules/tournament/src/main/JsonView.scala +++ b/modules/tournament/src/main/JsonView.scala @@ -76,9 +76,8 @@ final class JsonView( .dmap(some) stats <- statsApi(tour) shieldOwner <- full.so { shieldApi currentOwner tour } - teamsToJoinWith <- full.so(~(for { - u <- me; battle <- tour.teamBattle - } yield getMyTeamIds(u) map { teams => + teamsToJoinWith <- full.so(~(for u <- me; battle <- tour.teamBattle + yield getMyTeamIds(u) map { teams => battle.teams.intersect(teams.toSet).toList })) teamStanding <- getTeamStanding(tour) @@ -134,7 +133,7 @@ final class JsonView( def addReloadEndpoint(js: JsObject, tour: Tournament, useLilaHttp: Tournament => Boolean) = js + ("reloadEndpoint" -> JsString({ - if (useLilaHttp(tour)) reloadEndpointSetting.get() else reloadEndpointSetting.default + if useLilaHttp(tour) then reloadEndpointSetting.get() else reloadEndpointSetting.default }.replace("{id}", tour.id.value))) def clearCache(tour: Tournament): Unit = @@ -201,7 +200,7 @@ final class JsonView( ) private def fetchCurrentGameId(tour: Tournament, user: User): Fu[Option[GameId]] = - if (Uptime.startedSinceSeconds(60)) fuccess(duelStore.find(tour, user)) + if Uptime.startedSinceSeconds(60) then fuccess(duelStore.find(tour, user)) else pairingRepo.playingByTourAndUserId(tour.id, user.id) private def fetchFeaturedGame(tour: Tournament): Fu[Option[FeaturedGame]] = @@ -209,11 +208,11 @@ final class JsonView( proxyRepo game pairing.gameId flatMapz { game => cached ranking tour flatMap { ranking => playerRepo.pairByTourAndUserIds(tour.id, pairing.user1, pairing.user2) map { pairOption => - for { + for (p1, p2) <- pairOption rp1 <- RankedPlayer(ranking.ranking)(p1) rp2 <- RankedPlayer(ranking.ranking)(p2) - } yield FeaturedGame(game, rp1, rp2) + yield FeaturedGame(game, rp1, rp2) } } } diff --git a/modules/tournament/src/main/LeaderboardApi.scala b/modules/tournament/src/main/LeaderboardApi.scala index d0ebdd07fea41..5fe60cd4cf2cf 100644 --- a/modules/tournament/src/main/LeaderboardApi.scala +++ b/modules/tournament/src/main/LeaderboardApi.scala @@ -71,7 +71,7 @@ final class LeaderboardApi( Paginator( currentPage = page, maxPerPage = maxPerPage, - adapter = new AdapterLike[TourEntry] { + adapter = new AdapterLike[TourEntry]: private val selector = $doc("u" -> user.id) def nbResults: Fu[Int] = repo.coll.countSel(selector) def slice(offset: Int, length: Int): Fu[Seq[TourEntry]] = @@ -79,7 +79,7 @@ final class LeaderboardApi( .aggregateList(length, _.sec): framework => import framework.* Match(selector) -> List( - Sort(if (sortBest) Ascending("w") else Descending("d")), + Sort(if sortBest then Ascending("w") else Descending("d")), Skip(offset), Limit(length), PipelineOperator( @@ -98,8 +98,6 @@ final class LeaderboardApi( entry <- doc.asOpt[Entry] tour <- doc.getAsOpt[Tournament]("tour") yield TourEntry(tour, entry) - - } ) object LeaderboardApi: diff --git a/modules/tournament/src/main/LeaderboardIndexer.scala b/modules/tournament/src/main/LeaderboardIndexer.scala index ddf6d231993e6..4e751e7ad4b57 100644 --- a/modules/tournament/src/main/LeaderboardIndexer.scala +++ b/modules/tournament/src/main/LeaderboardIndexer.scala @@ -38,10 +38,10 @@ final private class LeaderboardIndexer( entries.nonEmpty so leaderboardRepo.coll.insert.many(entries).void private def generateTourEntries(tour: Tournament): Fu[List[Entry]] = - for { + for nbGames <- pairingRepo.countByTourIdAndUserIds(tour.id) players <- playerRepo.bestByTourWithRank(tour.id, nb = 9000, skip = 0) - } yield players.flatMap { case RankedPlayer(rank, player) => + yield players.flatMap { case RankedPlayer(rank, player) => nbGames get player.userId map { nb => Entry( id = player._id, @@ -50,7 +50,7 @@ final private class LeaderboardIndexer( nbGames = nb, score = player.score, rank = rank, - rankRatio = Ratio(if (tour.nbPlayers > 0) rank.value.toDouble / tour.nbPlayers else 0), + rankRatio = Ratio(if tour.nbPlayers > 0 then rank.value.toDouble / tour.nbPlayers else 0), freq = tour.schedule.map(_.freq), speed = tour.schedule.map(_.speed), perf = tour.perfType, diff --git a/modules/tournament/src/main/Pairing.scala b/modules/tournament/src/main/Pairing.scala index 1d1f15b24c899..5386be6eb2734 100644 --- a/modules/tournament/src/main/Pairing.scala +++ b/modules/tournament/src/main/Pairing.scala @@ -26,8 +26,8 @@ case class Pairing( def notContains(user: UserId) = !contains(user) def opponentOf(userId: UserId) = - if (userId == user1) user2.some - else if (userId == user2) user1.some + if userId == user1 then user2.some + else if userId == user2 then user1.some else none def finished = status >= chess.Status.Mate @@ -36,11 +36,11 @@ case class Pairing( def quickFinish = finished && turns.exists(20 >) def quickDraw = draw && turns.exists(20 >) def notSoQuickFinish = finished && turns.exists(14 <=) - def longGame(variant: Variant) = turns.exists(_ >= (variant match { + def longGame(variant: Variant) = turns.exists(_ >= (variant match case Standard | Chess960 | Horde => 60 case Antichess | Crazyhouse | KingOfTheHill => 40 case ThreeCheck | Atomic | RacingKings => 20 - })) + )) def wonBy(user: UserId): Boolean = winner.exists(user is _) def lostBy(user: UserId): Boolean = winner.exists(user isnt _) @@ -90,9 +90,9 @@ private[tournament] object Pairing: WithPlayers(make(gameId, tourId, player1.userId, player2.userId), player1, player2) def prepWithColor(p1: RankedPlayerWithColorHistory, p2: RankedPlayerWithColorHistory) = - if (p1.colorHistory.firstGetsWhite(p2.colorHistory)(() => ThreadLocalRandom.nextBoolean())) + if p1.colorHistory.firstGetsWhite(p2.colorHistory)(() => ThreadLocalRandom.nextBoolean()) then Prep(p1.player, p2.player) else Prep(p2.player, p1.player) def prepWithRandomColor(p1: Player, p2: Player) = - if (ThreadLocalRandom.nextBoolean()) Prep(p1, p2) else Prep(p2, p1) + if ThreadLocalRandom.nextBoolean() then Prep(p1, p2) else Prep(p2, p1) diff --git a/modules/tournament/src/main/PairingRepo.scala b/modules/tournament/src/main/PairingRepo.scala index 9d0080aa49a1e..68ea15faa0929 100644 --- a/modules/tournament/src/main/PairingRepo.scala +++ b/modules/tournament/src/main/PairingRepo.scala @@ -46,8 +46,8 @@ final class PairingRepo(coll: Coll)(using Executor, Materializer): case (acc, List(u1, u2)) => val b1 = userIds.contains(u1) val b2 = !b1 || userIds.contains(u2) - val acc1 = if (!b1 || acc.contains(u1)) acc else acc.updated(u1, u2) - if (!b2 || acc.contains(u2)) acc1 else acc1.updated(u2, u1) + val acc1 = if !b1 || acc.contains(u1) then acc else acc.updated(u1, u2) + if !b2 || acc.contains(u2) then acc1 else acc1.updated(u2, u1) case (acc, _) => acc } .takeWhile( @@ -168,7 +168,7 @@ final class PairingRepo(coll: Coll)(using Executor, Materializer): }.void def finishAndGet(g: Game): Fu[Option[Pairing]] = - if (g.aborted) coll.delete.one($id(g.id)) inject none + if g.aborted then coll.delete.one($id(g.id)) inject none else coll.findAndUpdateSimplified[Pairing]( selector = $id(g.id), @@ -181,8 +181,8 @@ final class PairingRepo(coll: Coll)(using Executor, Materializer): ) def setBerserk(pairing: Pairing, userId: UserId) = { - if (pairing.user1 == userId) "b1".some - else if (pairing.user2 == userId) "b2".some + if pairing.user1 == userId then "b1".some + else if pairing.user2 == userId then "b2".some else none } so { field => coll.update diff --git a/modules/tournament/src/main/PlayerRepo.scala b/modules/tournament/src/main/PlayerRepo.scala index 30116c1f81474..f9c78b38e1337 100644 --- a/modules/tournament/src/main/PlayerRepo.scala +++ b/modules/tournament/src/main/PlayerRepo.scala @@ -101,7 +101,7 @@ final class PlayerRepo(coll: Coll)(using Executor): .sorted.mapWithIndex: (rt, pos) => rt.updateRank(pos + 1) } map { ranked => - if (ranked.sizeIs == battle.teams.size) ranked + if ranked.sizeIs == battle.teams.size then ranked else ranked ::: battle.teams .foldLeft(List.empty[RankedTeam]) { @@ -138,7 +138,7 @@ final class PlayerRepo(coll: Coll)(using Executor): ) } .map { docO => - for { + for doc <- docO aggs <- doc.getAsOpt[List[Bdoc]]("agg") agg <- aggs.headOption @@ -147,7 +147,7 @@ final class PlayerRepo(coll: Coll)(using Executor): perf = agg.double("perf").so(math.round) score = agg.double("score").so(math.round) topPlayers <- doc.getAsOpt[List[Player]]("topPlayers") - } yield TeamBattle.TeamInfo(teamId, nbPlayers, rating.toInt, perf.toInt, score.toInt, topPlayers) + yield TeamBattle.TeamInfo(teamId, nbPlayers, rating.toInt, perf.toInt, score.toInt, topPlayers) } .dmap(_ | TeamBattle.TeamInfo(teamId, 0, 0, 0, 0, Nil)) @@ -264,7 +264,7 @@ final class PlayerRepo(coll: Coll)(using Executor): val playerIndex = new Array[TourPlayerId](all.size) val ranking = Map.newBuilder[UserId, Rank] var r = 0 - for (u <- all.values) + for u <- all.values do val both = u.asInstanceOf[BSONString].value val userId = UserId(both.drop(8)) playerIndex(r) = TourPlayerId(both.take(8)) diff --git a/modules/tournament/src/main/Revolution.scala b/modules/tournament/src/main/Revolution.scala index 6c6db9863308e..07f704518d351 100644 --- a/modules/tournament/src/main/Revolution.scala +++ b/modules/tournament/src/main/Revolution.scala @@ -33,12 +33,12 @@ final class RevolutionApi( .cursor[Bdoc](ReadPref.sec) .list(300) map { docOpt => val awards = - for { + for doc <- docOpt winner <- doc.getAsOpt[UserId]("winner") variant <- doc.getAsOpt[Variant.Id]("variant") map Variant.orDefault id <- doc.getAsOpt[TourId]("_id") - } yield Award( + yield Award( owner = winner, variant = variant, tourId = id diff --git a/modules/tournament/src/main/Schedule.scala b/modules/tournament/src/main/Schedule.scala index cd8e7c3961021..4e047ccc523b2 100644 --- a/modules/tournament/src/main/Schedule.scala +++ b/modules/tournament/src/main/Schedule.scala @@ -25,7 +25,7 @@ case class Schedule( import Schedule.Freq.* import Schedule.Speed.* import lila.i18n.I18nKeys.tourname.* - if (variant.standard && position.isEmpty) + if variant.standard && position.isEmpty then (conditions.minRating, conditions.maxRating) match case (None, None) => (freq, speed) match @@ -75,11 +75,11 @@ case class Schedule( case (Some(_), _) => eliteX.txt(speed.trans) case (_, Some(max)) if full => s"≤${max.rating} ${xArena.txt(speed.trans)}" case (_, Some(max)) => s"≤${max.rating} ${speed.trans}" - else if (variant.standard) + else if variant.standard then val n = position.flatMap(Thematic.byFen).fold(speed.trans) { pos => s"${pos.family.name} ${speed.trans}" } - if (full) xArena.txt(n) else n + if full then xArena.txt(n) else n else freq match case Hourly if full => hourlyXArena.txt(variant.name) @@ -98,7 +98,7 @@ case class Schedule( case Shield => xShield.txt(variant.name) case _ => val n = s"${freq.name} ${variant.name}" - if (full) xArena.txt(n) else n + if full then xArena.txt(n) else n def day = at.withTimeAtStartOfDay @@ -208,12 +208,12 @@ object Schedule: case _ => false def fromClock(clock: chess.Clock.Config) = val time = clock.estimateTotalSeconds - if (time < 30) UltraBullet - else if (time < 60) HyperBullet - else if (time < 120) Bullet - else if (time < 180) HippoBullet - else if (time < 480) Blitz - else if (time < 1500) Rapid + if time < 30 then UltraBullet + else if time < 60 then HyperBullet + else if time < 120 then Bullet + else if time < 180 then HippoBullet + else if time < 480 then Blitz + else if time < 1500 then Rapid else Classical def toPerfType(speed: Speed) = speed match diff --git a/modules/tournament/src/main/StartedOrganizer.scala b/modules/tournament/src/main/StartedOrganizer.scala index 997feda241989..8dd51d0956406 100644 --- a/modules/tournament/src/main/StartedOrganizer.scala +++ b/modules/tournament/src/main/StartedOrganizer.scala @@ -24,8 +24,8 @@ final private class StartedOrganizer( tournamentRepo .startedCursorWithNbPlayersGte { - if (doAllTournaments) none // every 15s, do all tournaments - else if (runCounter % 2 == 0) 50.some // every 2s, do all decent tournaments + if doAllTournaments then none // every 15s, do all tournaments + else if runCounter % 2 == 0 then 50.some // every 2s, do all decent tournaments else 1000.some // always do massive tournaments } .documentSource() @@ -38,7 +38,7 @@ final private class StartedOrganizer( .toMat(LilaStream.sinkCount)(Keep.right) .run() .addEffect { nb => - if (doAllTournaments) lila.mon.tournament.started.update(nb).unit + if doAllTournaments then lila.mon.tournament.started.update(nb).unit runCounter = runCounter + 1 } .monSuccess(_.tournament.startedOrganizer.tick) @@ -46,12 +46,12 @@ final private class StartedOrganizer( } private def processTour(tour: Tournament): Funit = - if (tour.secondsToFinish <= 0) api finish tour - else if (api.killSchedule contains tour.id) + if tour.secondsToFinish <= 0 then api finish tour + else if api.killSchedule contains tour.id then api.killSchedule remove tour.id api finish tour - else if (tour.nbPlayers < 2) funit - else if (tour.nbPlayers < 30) + else if tour.nbPlayers < 2 then funit + else if tour.nbPlayers < 30 then playerRepo nbActivePlayers tour.id flatMap { nb => (nb >= 2) so startPairing(tour, nb.some) } diff --git a/modules/tournament/src/main/TeamBattle.scala b/modules/tournament/src/main/TeamBattle.scala index 635cc98c1733b..35dfeffa8ee6f 100644 --- a/modules/tournament/src/main/TeamBattle.scala +++ b/modules/tournament/src/main/TeamBattle.scala @@ -35,8 +35,8 @@ object TeamBattle: this(rank, teamId, leaders, leaders.foldLeft(0)(_ + _.score)) def updateRank(newRank: Int) = new RankedTeam(newRank, teamId, leaders, score) override def compare(that: RankedTeam) = - if (this.score > that.score) -1 - else if (this.score < that.score) 1 + if this.score > that.score then -1 + else if this.score < that.score then 1 else that.magicScore - this.magicScore case class TeamLeader(userId: UserId, magicScore: Int): @@ -75,6 +75,6 @@ object TeamBattle: def potentialTeamIds: Set[TeamId] = val lines = teams.linesIterator.toList val dirtyIds = - if (lines.sizeIs > 1) lines.map(_.takeWhile(' ' !=)) + if lines.sizeIs > 1 then lines.map(_.takeWhile(' ' !=)) else lines.headOption.so(_.split(',').toList) dirtyIds.map(_.trim).filter(_.nonEmpty).map(TeamId(_)).toSet diff --git a/modules/tournament/src/main/Tournament.scala b/modules/tournament/src/main/Tournament.scala index a4dd32a2a504d..49cac532dc9d6 100644 --- a/modules/tournament/src/main/Tournament.scala +++ b/modules/tournament/src/main/Tournament.scala @@ -48,10 +48,10 @@ case class Tournament( def isTeamBattle = teamBattle.isDefined def name(full: Boolean = true)(using Lang): String = - if (isMarathon || isUnique) name - else if (isTeamBattle && full) lila.i18n.I18nKeys.tourname.xTeamBattle.txt(name) - else if (isTeamBattle) name - else schedule.fold(if (full) s"$name Arena" else name)(_.name(full)) + if isMarathon || isUnique then name + else if isTeamBattle && full then lila.i18n.I18nKeys.tourname.xTeamBattle.txt(name) + else if isTeamBattle then name + else schedule.fold(if full then s"$name Arena" else name)(_.name(full)) def isMarathon = schedule.map(_.freq) exists { @@ -108,8 +108,8 @@ case class Tournament( def perfType: PerfType = PerfType(variant, speed) def durationString = - if (minutes < 60) s"${minutes}m" - else s"${minutes / 60}h" + (if (minutes % 60 != 0) s" ${minutes % 60}m" else "") + if minutes < 60 then s"${minutes}m" + else s"${minutes / 60}h" + (if minutes % 60 != 0 then s" ${minutes % 60}m" else "") def berserkable = !noBerserk && clock.berserkable def streakable = !noStreak @@ -133,7 +133,7 @@ case class Tournament( def nonLichessCreatedBy = (createdBy != User.lichessId) option createdBy - def ratingVariant = if (variant.fromPosition) chess.variant.Standard else variant + def ratingVariant = if variant.fromPosition then chess.variant.Standard else variant def startingPosition = position flatMap Thematic.byFen diff --git a/modules/tournament/src/main/TournamentApi.scala b/modules/tournament/src/main/TournamentApi.scala index 880c02d27641e..08f655f4b0e7e 100644 --- a/modules/tournament/src/main/TournamentApi.scala +++ b/modules/tournament/src/main/TournamentApi.scala @@ -232,8 +232,8 @@ final class TournamentApi( private[tournament] val killSchedule = scala.collection.mutable.Set.empty[TourId] def kill(tour: Tournament): Funit = - if (tour.isStarted) fuccess(killSchedule add tour.id).void - else if (tour.isCreated) destroy(tour) + if tour.isStarted then fuccess(killSchedule add tour.id).void + else if tour.isCreated then destroy(tour) else funit private def awardTrophies(tour: Tournament): Funit = @@ -276,7 +276,7 @@ final class TournamentApi( playerRepo.find(tour.id, me) flatMap { prevPlayer => import Tournament.JoinResult val fuResult: Fu[JoinResult] = - if (me.marks.prizeban && tour.looksLikePrize) fuccess(JoinResult.PrizeBanned) + if me.marks.prizeban && tour.looksLikePrize then fuccess(JoinResult.PrizeBanned) else if prevPlayer.nonEmpty || tour.password.forall(p => // plain text access code MessageDigest.isEqual(p.getBytes(UTF_8), (~data.password).getBytes(UTF_8)) || @@ -289,8 +289,8 @@ final class TournamentApi( ) then getVerdicts(tour, prevPlayer.isDefined) flatMap { verdicts => - if (!verdicts.accepted) fuccess(JoinResult.Verdicts) - else if (!pause.canJoin(me, tour)) fuccess(JoinResult.Paused) + if !verdicts.accepted then fuccess(JoinResult.Verdicts) + else if !pause.canJoin(me, tour) then fuccess(JoinResult.Paused) else def proceedWithTeam(team: Option[TeamId]): Fu[JoinResult] = for user <- perfsRepo.withPerf(me.value, tour.perfType) @@ -369,7 +369,7 @@ final class TournamentApi( then cached.ranking(tour).map { _.ranking get userId exists (_ < 7) } else fuccess(isStalling) yield - if (pausable) pause.add(userId) + if pausable then pause.add(userId) socket.reload(tour.id) publish() case _ => funit @@ -442,15 +442,16 @@ final class TournamentApi( private def performanceOf(g: Game, userId: UserId): Option[IntRating] = for opponent <- g.opponentByUserId(userId) opponentRating <- opponent.rating - multiplier = g.winnerUserId.so(winner => if (winner == userId) 1 else -1) + multiplier = g.winnerUserId.so(winner => if winner == userId then 1 else -1) yield opponentRating + 500 * multiplier private def withdrawNonMover(game: Game): Unit = - if (game.status == chess.Status.NoStart) for - tourId <- game.tournamentId - player <- game.playerWhoDidNotMove - userId <- player.userId - yield withdraw(tourId, userId, isPause = false, isStalling = false) + if game.status == chess.Status.NoStart then + for + tourId <- game.tournamentId + player <- game.playerWhoDidNotMove + userId <- player.userId + yield withdraw(tourId, userId, isPause = false, isStalling = false) def pausePlaybanned(userId: UserId) = tournamentRepo.withdrawableIds(userId, reason = "pausePlaybanned") flatMap { @@ -464,7 +465,7 @@ final class TournamentApi( _.map { tourId => Parallel(tourId, "kickFromTeam")(tournamentRepo.byId) { tour => val fu = - if (tour.isCreated) playerRepo.remove(tour.id, userId) + if tour.isCreated then playerRepo.remove(tour.id, userId) else playerRepo.withdraw(tour.id, userId) fu >> updateNbPlayers(tourId) >>- socket.reload(tourId) } @@ -474,8 +475,7 @@ final class TournamentApi( // withdraws the player and forfeits all pairings in ongoing tournaments private[tournament] def ejectLameFromEnterable(tourId: TourId, userId: UserId): Funit = Parallel(tourId, "ejectLameFromEnterable")(cached.tourCache.enterable) { tour => - if (tour.isCreated) - playerRepo.remove(tour.id, userId) >> updateNbPlayers(tour.id) + if tour.isCreated then playerRepo.remove(tour.id, userId) >> updateNbPlayers(tour.id) else playerRepo.remove(tourId, userId) >> { tour.isStarted so { @@ -710,12 +710,11 @@ final class TournamentApi( (Tournament.PastAndNext.apply).tupled def toggleFeaturing(tourId: TourId, v: Boolean): Funit = - if (v) + if v then tournamentRepo.byId(tourId) flatMapz { tour => tournamentRepo.setSchedule(tour.id, Schedule.uniqueFor(tour).some) } - else - tournamentRepo.setSchedule(tourId, none) + else tournamentRepo.setSchedule(tourId, none) private def playerPovs(tour: Tournament, userId: UserId, nb: Int): Fu[List[LightPov]] = pairingRepo.recentIdsByTourAndUserId(tour.id, userId, nb) flatMap @@ -754,7 +753,7 @@ final class TournamentApi( private def publishNow(tourId: TourId) = tournamentTop(tourId) map { top => val lastHash: Int = ~lastPublished.getIfPresent(tourId) - if (lastHash != top.hashCode) + if lastHash != top.hashCode then Bus.publish( lila.hub.actorApi.round.TourStanding(tourId, JsonView.top(top, lightUserApi.sync)), "tourStanding" @@ -765,7 +764,7 @@ final class TournamentApi( private val throttler = new lila.hub.EarlyMultiThrottler[TourId](logger) def apply(tour: Tournament): Unit = - if (!tour.isTeamBattle) throttler(tour.id, 15.seconds) { publishNow(tour.id) } + if !tour.isTeamBattle then throttler(tour.id, 15.seconds) { publishNow(tour.id) } private object TournamentApi: diff --git a/modules/tournament/src/main/TournamentCache.scala b/modules/tournament/src/main/TournamentCache.scala index 5aa3f2a3beeda..83e9f390f368e 100644 --- a/modules/tournament/src/main/TournamentCache.scala +++ b/modules/tournament/src/main/TournamentCache.scala @@ -41,7 +41,7 @@ final class TournamentCache( .buildAsyncFuture(_ => tournamentRepo.onHomepage) def ranking(tour: Tournament): Fu[FullRanking] = - if (tour.isFinished) finishedRanking get tour.id + if tour.isFinished then finishedRanking get tour.id else ongoingRanking get tour.id // only applies to ongoing tournaments diff --git a/modules/tournament/src/main/TournamentForm.scala b/modules/tournament/src/main/TournamentForm.scala index bcb622dff9050..248adef672364 100644 --- a/modules/tournament/src/main/TournamentForm.scala +++ b/modules/tournament/src/main/TournamentForm.scala @@ -157,7 +157,7 @@ private[tournament] case class TournamentSetup( def validClock = (clockTime + clockIncrement.value) > 0 def realMode = - if (realPosition.isDefined) Mode.Casual + if realPosition.isDefined then Mode.Casual else Mode(rated.orElse(mode.map(Mode.Rated.id ===)) | true) def realVariant = variant.flatMap(TournamentForm.guessVariant) | chess.variant.Standard @@ -187,18 +187,18 @@ private[tournament] case class TournamentSetup( // update all fields and use default values for missing fields // meant for HTML form updates def updateAll(old: Tournament): Tournament = - val newVariant = if (old.isCreated && variant.isDefined) realVariant else old.variant + val newVariant = if old.isCreated && variant.isDefined then realVariant else old.variant old .copy( name = name | old.name, - clock = if (old.isCreated) clockConfig else old.clock, + clock = if old.isCreated then clockConfig else old.clock, minutes = minutes, mode = realMode, variant = newVariant, startsAt = startDate | old.startsAt, password = password, position = newVariant.standard so { - if (old.isCreated || old.position.isDefined) realPosition + if old.isCreated || old.position.isDefined then realPosition else old.position }, noBerserk = !isBerserkable, @@ -211,18 +211,18 @@ private[tournament] case class TournamentSetup( // update only fields that are specified // meant for API updates def updatePresent(old: Tournament): Tournament = - val newVariant = if (old.isCreated) realVariant else old.variant + val newVariant = if old.isCreated then realVariant else old.variant old .copy( name = name | old.name, - clock = if (old.isCreated) clockConfig else old.clock, + clock = if old.isCreated then clockConfig else old.clock, minutes = minutes, - mode = if (rated.isDefined) realMode else old.mode, + mode = if rated.isDefined then realMode else old.mode, variant = newVariant, startsAt = startDate | old.startsAt, password = password.fold(old.password)(_.some.filter(_.nonEmpty)), position = newVariant.standard so { - if (position.isDefined && (old.isCreated || old.position.isDefined)) realPosition + if position.isDefined && (old.isCreated || old.position.isDefined) then realPosition else old.position }, noBerserk = berserkable.fold(old.noBerserk)(!_) || timeControlPreventsBerserk, diff --git a/modules/tournament/src/main/TournamentNotify.scala b/modules/tournament/src/main/TournamentNotify.scala index 38266cc2189fc..530cf3a36c35c 100644 --- a/modules/tournament/src/main/TournamentNotify.scala +++ b/modules/tournament/src/main/TournamentNotify.scala @@ -19,7 +19,7 @@ final private class TournamentNotify(repo: TournamentRepo, cached: TournamentCac lila.mon.tournament.notifier.tournaments.increment() doneMemo put tour.id cached ranking tour map { ranking => - if (ranking.ranking.nonEmpty) + if ranking.ranking.nonEmpty then Bus .publish( TourSoon( diff --git a/modules/tournament/src/main/TournamentRepo.scala b/modules/tournament/src/main/TournamentRepo.scala index b248b01d78581..ffac944cc4f9b 100644 --- a/modules/tournament/src/main/TournamentRepo.scala +++ b/modules/tournament/src/main/TournamentRepo.scala @@ -20,7 +20,7 @@ final class TournamentRepo(val coll: Coll, playerCollName: CollName)(using Execu private def forTeamsSelect(ids: Seq[TeamId]) = $doc("forTeams" $in ids) private def sinceSelect(date: Instant) = $doc("startsAt" $gt date) private def variantSelect(variant: Variant) = - if (variant.standard) $doc("variant" $exists false) + if variant.standard then $doc("variant" $exists false) else $doc("variant" -> variant.id) private def nbPlayersSelect(nb: Int) = $doc("nbPlayers" $gte nb) private val nonEmptySelect = nbPlayersSelect(1) @@ -236,7 +236,7 @@ final class TournamentRepo(val coll: Coll, playerCollName: CollName)(using Execu case Weekly | Weekend => 3 * 45 case Daily => 1 * 30 case _ => 20 - if (tour.variant.exotic && schedule.freq != Unique) base / 3 else base + if tour.variant.exotic && schedule.freq != Unique then base / 3 else base } } @@ -281,11 +281,10 @@ final class TournamentRepo(val coll: Coll, playerCollName: CollName)(using Execu case ((tours, skip), (tour, sched)) => ( tour :: tours, - sched.freq match { + sched.freq match case Schedule.Freq.Daily => Schedule.Freq.Eastern.some case Schedule.Freq.Eastern => Schedule.Freq.Daily.some case _ => skip - } ) }._1 .reverse diff --git a/modules/tournament/src/main/TournamentScheduler.scala b/modules/tournament/src/main/TournamentScheduler.scala index f4572aff8f6c7..675e766fae5cc 100644 --- a/modules/tournament/src/main/TournamentScheduler.scala +++ b/modules/tournament/src/main/TournamentScheduler.scala @@ -172,7 +172,7 @@ Thank you all, you rock!""", at(day, 19) map { date => Schedule( Monthly, - if (variant == Chess960 || variant == Crazyhouse) Blitz else SuperBlitz, + if variant == Chess960 || variant == Crazyhouse then Blitz else SuperBlitz, variant, none, date @@ -243,7 +243,7 @@ Thank you all, you rock!""", at(day, 19) map { date => Schedule( Weekly, - if (variant == Chess960 || variant == Crazyhouse) Blitz else SuperBlitz, + if variant == Chess960 || variant == Crazyhouse then Blitz else SuperBlitz, variant, none, date pipe orNextWeek @@ -389,7 +389,7 @@ Thank you all, you rock!""", allowList = none ) val finalWhen = when plusHours hourDelay - if (speed == Bullet) + if speed == Bullet then List( Schedule(Hourly, speed, Standard, none, finalWhen, conditions).plan, Schedule(Hourly, speed, Standard, none, finalWhen plusMinutes 30, conditions) @@ -480,7 +480,7 @@ Thank you all, you rock!""", private def pruneConflicts(scheds: List[Tournament], newTourns: List[Tournament]) = newTourns .foldLeft(List[Tournament]()): (tourns, t) => - if (overlaps(t, tourns) || overlaps(t, scheds)) tourns + if overlaps(t, tourns) || overlaps(t, scheds) then tourns else t :: tourns .reverse diff --git a/modules/tournament/src/main/TournamentShield.scala b/modules/tournament/src/main/TournamentShield.scala index 85c2adc0636c2..d9e6f1fa5b5f1 100644 --- a/modules/tournament/src/main/TournamentShield.scala +++ b/modules/tournament/src/main/TournamentShield.scala @@ -40,7 +40,7 @@ final class TournamentShieldApi( private[tournament] def clearAfterMarking(userId: UserId): Funit = cache.getUnit map { hist => import cats.syntax.all.* - if (hist.value.exists(_._2.exists(_.owner == userId))) clear() + if hist.value.exists(_._2.exists(_.owner == userId)) then clear() } private val cache = cacheApi.unit[History]: diff --git a/modules/tournament/src/main/TournamentStandingApi.scala b/modules/tournament/src/main/TournamentStandingApi.scala index 530c63935033e..3e26222e43de1 100644 --- a/modules/tournament/src/main/TournamentStandingApi.scala +++ b/modules/tournament/src/main/TournamentStandingApi.scala @@ -44,8 +44,8 @@ final class TournamentStandingApi( def apply(tour: Tournament, forPage: Int, withScores: Boolean): Fu[JsObject] = val page = forPage atMost Math.ceil(tour.nbPlayers.toDouble / perPage).toInt atLeast 1 - if (page == 1) first get tour.id - else if (page > 50 && tour.isCreated) createdCache.get(tour.id -> page) + if page == 1 then first get tour.id + else if page > 50 && tour.isCreated then createdCache.get(tour.id -> page) else compute(tour, page, withScores) private val first = cacheApi[TourId, JsObject](64, "tournament.page.first") { @@ -74,9 +74,9 @@ final class TournamentStandingApi( } private def compute(tour: Tournament, page: Int, withScores: Boolean): Fu[JsObject] = - for { + for rankedPlayers <- - if (page < 10) playerRepo.bestByTourWithRankByPage(tour.id, perPage, page) + if page < 10 then playerRepo.bestByTourWithRankByPage(tour.id, perPage, page) else playerIdsOnPage(tour, page) flatMap { playerRepo.byPlayerIdsOnPage(_, page) } sheets <- rankedPlayers .map { p => @@ -87,7 +87,7 @@ final class TournamentStandingApi( players <- rankedPlayers .map(JsonView.playerJson(lightUserApi, sheets, streakable = tour.streakable, withScores = withScores)) .parallel - } yield Json.obj( + yield Json.obj( "page" -> page, "players" -> players ) diff --git a/modules/tournament/src/main/TournamentStats.scala b/modules/tournament/src/main/TournamentStats.scala index 6bcf289845291..268e727d17b59 100644 --- a/modules/tournament/src/main/TournamentStats.scala +++ b/modules/tournament/src/main/TournamentStats.scala @@ -24,10 +24,10 @@ final class TournamentStatsApi( } private def fetch(tournamentId: TourId): Fu[TournamentStats] = - for { + for rating <- playerRepo.averageRating(tournamentId) rawStats <- pairingRepo.rawStats(tournamentId) - } yield TournamentStats.readAggregation(rating)(rawStats) + yield TournamentStats.readAggregation(rating)(rawStats) case class TournamentStats( games: Int, diff --git a/modules/tournament/src/main/WaitingUsers.scala b/modules/tournament/src/main/WaitingUsers.scala index 0107277b956f4..31b032646ad2c 100644 --- a/modules/tournament/src/main/WaitingUsers.scala +++ b/modules/tournament/src/main/WaitingUsers.scala @@ -19,8 +19,8 @@ private case class WaitingUsers( // 5+0 -> 36 -> 36 // 10+0 -> 66 -> 50 private val waitSeconds: Int = - if (clock.estimateTotalSeconds < 30) 8 - else if (clock.estimateTotalSeconds < 60) 10 + if clock.estimateTotalSeconds < 30 then 8 + else if clock.estimateTotalSeconds < 60 then 10 else (clock.estimateTotalSeconds / 10 + 6) atMost 50 atLeast 15 lazy val all = hash.keySet @@ -30,7 +30,7 @@ private case class WaitingUsers( // skips the most recent user if odd def evenNumber: Set[UserId] = - if (isOdd) all - hash.maxBy(_._2.toMillis)._1 + if isOdd then all - hash.maxBy(_._2.toMillis)._1 else all lazy val haveWaitedEnough: Boolean = @@ -56,7 +56,7 @@ private case class WaitingUsers( def addApiUser(userId: UserId) = val memo = apiUsers | new ExpireSetMemo[UserId](70 seconds) memo put userId - if (apiUsers.isEmpty) copy(apiUsers = memo.some) else this + if apiUsers.isEmpty then copy(apiUsers = memo.some) else this def removePairedUsers(us: Set[UserId]) = apiUsers.foreach(_ removeAll us) @@ -75,11 +75,10 @@ final private class WaitingUsersApi: def registerWaitingUsers(tourId: TourId, users: Set[UserId]) = store.computeIfPresent( tourId, - (_: TourId, cur: WaitingUsers.WithNext) => { + (_: TourId, cur: WaitingUsers.WithNext) => val newWaiting = cur.waiting.update(users) cur.next.foreach(_ success newWaiting) WaitingUsers.WithNext(newWaiting, none) - } ) def registerPairedUsers(tourId: TourId, users: Set[UserId]) = diff --git a/modules/tournament/src/main/WinnersApi.scala b/modules/tournament/src/main/WinnersApi.scala index 431b6422397af..0bdbac6535669 100644 --- a/modules/tournament/src/main/WinnersApi.scala +++ b/modules/tournament/src/main/WinnersApi.scala @@ -87,14 +87,14 @@ final class WinnersApi( tours.find(_.variant == variant).flatMap(_.winner) private def fetchAll: Fu[AllWinners] = - for { + for yearlies <- fetchLastFreq(Freq.Yearly, nowInstant.minusYears(1)) monthlies <- fetchLastFreq(Freq.Monthly, nowInstant.minusMonths(2)) weeklies <- fetchLastFreq(Freq.Weekly, nowInstant.minusWeeks(2)) dailies <- fetchLastFreq(Freq.Daily, nowInstant.minusDays(2)) elites <- fetchLastFreq(Freq.Weekend, nowInstant.minusWeeks(3)) marathons <- fetchLastFreq(Freq.Marathon, nowInstant.minusMonths(13)) - } yield + yield def standardFreqWinners(speed: Speed): FreqWinners = FreqWinners( yearly = firstStandardWinner(yearlies, speed), @@ -132,11 +132,11 @@ final class WinnersApi( // because we read on secondaries, delay cache clear def clearCache(tour: Tournament): Unit = - if (tour.schedule.exists(_.freq.isDailyOrBetter)) + if tour.schedule.exists(_.freq.isDailyOrBetter) then scheduler.scheduleOnce(5.seconds) { allCache.invalidate {}.unit }.unit private[tournament] def clearAfterMarking(userId: UserId): Funit = all map { winners => - if (winners.userIds contains userId) allCache.invalidate {}.unit + if winners.userIds contains userId then allCache.invalidate {}.unit } object WinnersApi: diff --git a/modules/tournament/src/main/arena/AntmaPairing.scala b/modules/tournament/src/main/arena/AntmaPairing.scala index a104eafab4a2e..0433e9941b596 100644 --- a/modules/tournament/src/main/arena/AntmaPairing.scala +++ b/modules/tournament/src/main/arena/AntmaPairing.scala @@ -21,10 +21,9 @@ private object AntmaPairing: lastOpponents.hash.get(u2).contains(u1) def pairScore(a: RPlayer, b: RPlayer): Option[Int] = - if ( - justPlayedTogether(a.player.userId, b.player.userId) || + if justPlayedTogether(a.player.userId, b.player.userId) || !a.colorHistory.couldPlay(b.colorHistory, maxStrike) - ) None + then None else Some { Math.abs(a.rank.value - b.rank.value) * rankFactor(a, b) + @@ -39,14 +38,14 @@ private object AntmaPairing: Chronometer.syncMon(_.tournament.pairing.wmmatching) { WMMatching( players.toArray, - if (data.tour.isTeamBattle) battleScore - else if (data.onlyTwoActivePlayers) duelScore + if data.tour.isTeamBattle then battleScore + else if data.onlyTwoActivePlayers then duelScore else pairScore ).fold( - err => { + err => logger.error("WMMatching", err) Nil - }, + , _ map { case (a, b) => Pairing.prepWithColor(a, b) } diff --git a/modules/tournament/src/main/arena/ArenaSheet.scala b/modules/tournament/src/main/arena/ArenaSheet.scala index 9657f245b238d..6fbc0fb709453 100644 --- a/modules/tournament/src/main/arena/ArenaSheet.scala +++ b/modules/tournament/src/main/arena/ArenaSheet.scala @@ -13,24 +13,23 @@ case class Sheet(scores: List[Sheet.Score], total: Int, variant: Variant): def addResult(userId: UserId, p: Pairing, version: Version, streakable: Streakable): Sheet = val berserk = - if (p berserkOf userId) - if p.notSoQuickFinish then Berserk.Valid else Berserk.Invalid + if p berserkOf userId then if p.notSoQuickFinish then Berserk.Valid else Berserk.Invalid else Berserk.No val score = p.winner match case None if p.quickDraw => Score(Result.DQ, Flag.Normal, berserk) case None => Score( Result.Draw, - if (streakable && isOnFire) Flag.Double - else if (version != Version.V1 && !p.longGame(variant) && isDrawStreak(scores)) Flag.Null + if streakable && isOnFire then Flag.Double + else if version != Version.V1 && !p.longGame(variant) && isDrawStreak(scores) then Flag.Null else Flag.Normal, berserk ) case Some(w) if userId == w => Score( Result.Win, - if (!streakable) Flag.Normal - else if (isOnFire) Flag.Double + if !streakable then Flag.Normal + else if isOnFire then Flag.Double else Flag.StreakStarter, berserk ) diff --git a/modules/tournament/src/main/arena/PairingSystem.scala b/modules/tournament/src/main/arena/PairingSystem.scala index 8bf6c3c1ef008..2318e7c14d67b 100644 --- a/modules/tournament/src/main/arena/PairingSystem.scala +++ b/modules/tournament/src/main/arena/PairingSystem.scala @@ -21,15 +21,15 @@ final private[tournament] class PairingSystem( ranking: FullRanking, smallTourNbActivePlayers: Option[Int] ): Fu[List[Pairing.WithPlayers]] = { - for { + for lastOpponents <- - if (tour.isRecentlyStarted) fuccess(Pairing.LastOpponents(Map.empty)) + if tour.isRecentlyStarted then fuccess(Pairing.LastOpponents(Map.empty)) else pairingRepo.lastOpponents(tour.id, users.all, Math.min(300, users.size * 4)) onlyTwoActivePlayers = smallTourNbActivePlayers.exists(2 ==) data = Data(tour, lastOpponents, ranking.ranking, onlyTwoActivePlayers) preps <- evenOrAll(data, users) pairings <- prepsToPairings(tour, preps) - } yield pairings + yield pairings }.chronometer .logIfSlow(500, pairingLogger) { pairings => s"createPairings ${tournamentUrl(tour.id)} ${pairings.size} pairings" @@ -46,13 +46,13 @@ final private[tournament] class PairingSystem( private def makePreps(data: Data, users: Set[UserId]): Fu[List[Pairing.Prep]] = { import data.* - if (users.sizeIs < 2) fuccess(Nil) + if users.sizeIs < 2 then fuccess(Nil) else playerRepo.rankedByTourAndUserIds(tour.id, users, ranking) map { idles => lazy val nbIdles = idles.size - if (nbIdles < 2) Nil - else if (data.tour.isRecentlyStarted && !data.tour.isTeamBattle) initialPairings(idles) - else if (nbIdles <= maxGroupSize) bestPairings(data, idles) + if nbIdles < 2 then Nil + else if data.tour.isRecentlyStarted && !data.tour.isTeamBattle then initialPairings(idles) + else if nbIdles <= maxGroupSize then bestPairings(data, idles) else // make sure groupSize is even with / 4 * 2 val groupSize = (nbIdles / 4 * 2) atMost maxGroupSize @@ -116,7 +116,6 @@ private object PairingSystem: players: List[RankedPlayerWithColorHistory] ): (RankedPlayerWithColorHistory, RankedPlayerWithColorHistory) => Int = val maxRank = players.maxBy(_.rank.value).rank - (a, b) => { + (a, b) => val rank = a.rank atMost b.rank 300 + 1700 * (maxRank - rank).value / maxRank.value - } diff --git a/modules/tournament/src/main/crud/CrudApi.scala b/modules/tournament/src/main/crud/CrudApi.scala index c09c9769e868a..d038bb3e69861 100644 --- a/modules/tournament/src/main/crud/CrudApi.scala +++ b/modules/tournament/src/main/crud/CrudApi.scala @@ -93,7 +93,7 @@ final class CrudApi(tournamentRepo: TournamentRepo, crudForm: CrudForm): clock = clock, minutes = minutes, variant = realVariant, - mode = if (data.rated) Mode.Rated else Mode.Casual, + mode = if data.rated then Mode.Rated else Mode.Casual, startsAt = date.instant, schedule = Schedule( freq = Schedule.Freq.Unique, diff --git a/modules/tournament/src/main/model.scala b/modules/tournament/src/main/model.scala index e28bc895a5302..3f2d0ca4d7c2a 100644 --- a/modules/tournament/src/main/model.scala +++ b/modules/tournament/src/main/model.scala @@ -61,10 +61,10 @@ case class RankedPairing(pairing: Pairing, rank1: Rank, rank2: Rank): object RankedPairing: def apply(ranking: Ranking)(pairing: Pairing): Option[RankedPairing] = - for { + for r1 <- ranking get pairing.user1 r2 <- ranking get pairing.user2 - } yield RankedPairing(pairing, r1 + 1, r2 + 1) + yield RankedPairing(pairing, r1 + 1, r2 + 1) case class RankedPlayer(rank: Rank, player: Player): diff --git a/modules/tournament/src/test/ColorHistoryTest.scala b/modules/tournament/src/test/ColorHistoryTest.scala index cd77f86ee9c23..f8b86d5456bf0 100644 --- a/modules/tournament/src/test/ColorHistoryTest.scala +++ b/modules/tournament/src/test/ColorHistoryTest.scala @@ -1,14 +1,12 @@ package lila.tournament -object ColorHistoryTest { - def apply(s: String): ColorHistory = { +object ColorHistoryTest: + def apply(s: String): ColorHistory = s.foldLeft(ColorHistory(0, 0)) { (acc, c) => - c match { + c match case 'W' => acc.inc(chess.White) case 'B' => acc.inc(chess.Black) - } } - } def toTuple2(history: ColorHistory): (Int, Int) = (history.strike, history.balance) def unpack(s: String): (Int, Int) = toTuple2(apply(s)) def couldPlay(s1: String, s2: String, maxStreak: Int): Boolean = apply(s1).couldPlay(apply(s2), maxStreak) @@ -17,9 +15,8 @@ object ColorHistoryTest { apply(s1).firstGetsWhite(apply(s2)) { () => true } -} -class ColorHistoryTest extends munit.FunSuite { +class ColorHistoryTest extends munit.FunSuite: import ColorHistoryTest.{ apply, couldPlay, firstGetsWhite, sameColors, unpack } test("hand tests") { assertEquals(unpack("WWW"), ((3, 3))) @@ -49,4 +46,3 @@ class ColorHistoryTest extends munit.FunSuite { assertEquals(apply(""), apply("")) assertEquals(apply("WBW"), apply("W")) } -} diff --git a/modules/tutor/src/main/TutorBsonHandlers.scala b/modules/tutor/src/main/TutorBsonHandlers.scala index eeb0a95798afe..7c1077dc7ab98 100644 --- a/modules/tutor/src/main/TutorBsonHandlers.scala +++ b/modules/tutor/src/main/TutorBsonHandlers.scala @@ -25,12 +25,12 @@ private object TutorBsonHandlers: quickHandler[Option[ValueCount[V]]]( { case arr: BSONArray => - for { v <- arr.getAsOpt[V](0); c <- arr.getAsOpt[Int](1) } yield ValueCount(v, c) + for v <- arr.getAsOpt[V](0); c <- arr.getAsOpt[Int](1) yield ValueCount(v, c) case _ => None }, vcOpt => { - for { vc <- vcOpt; v <- handler.writeOpt(vc.value) } yield $arr(v, BSONInteger(vc.count)) + for vc <- vcOpt; v <- handler.writeOpt(vc.value) yield $arr(v, BSONInteger(vc.count)) } getOrElse BSONNull ) diff --git a/modules/tutor/src/main/TutorCompare.scala b/modules/tutor/src/main/TutorCompare.scala index dd89a107359fc..1e4d4ac190cad 100644 --- a/modules/tutor/src/main/TutorCompare.scala +++ b/modules/tutor/src/main/TutorCompare.scala @@ -17,10 +17,10 @@ case class TutorCompare[D, V]( lazy val dimensionComparisons: List[AnyComparison] = val myPoints: List[(D, ValueCount[V])] = points.collect { case (dim, TutorBothValueOptions(Some(mine), _)) => dim -> mine } - for { + for (dim1, met1) <- myPoints.filter(_._2 relevantTo totalCountMine) avg = number.mean(myPoints.filter(_._1 != dim1).map(_._2)) - } yield Comparison(dimensionType, dim1, metric, met1, DimAvg(avg), color) + yield Comparison(dimensionType, dim1, metric, met1, DimAvg(avg), color) lazy val peerComparisons: List[AnyComparison] = points.collect { case (dim, TutorBothValueOptions(Some(mine), Some(peer))) @@ -75,6 +75,7 @@ object TutorCompare: } .toList - sealed trait Reference[V] { val value: ValueCount[V] } + sealed trait Reference[V]: + val value: ValueCount[V] case class Peers[V](value: ValueCount[V]) extends Reference[V] case class DimAvg[V](value: ValueCount[V]) extends Reference[V] diff --git a/modules/tutor/src/main/TutorFlagging.scala b/modules/tutor/src/main/TutorFlagging.scala index 3d7437b8d67c5..7c52f506352cc 100644 --- a/modules/tutor/src/main/TutorFlagging.scala +++ b/modules/tutor/src/main/TutorFlagging.scala @@ -20,10 +20,10 @@ object TutorFlagging: val question = Question(InsightDimension.Result, InsightMetric.Termination) filter TutorBuilder.perfFilter(user.perfType) val clockFlagValueName = InsightMetric.MetricValueName(Termination.ClockFlag.name) - for { + for mine <- insightApi.ask(question, user.user, withPovs = false) peer <- insightApi.askPeers(question, user.perfStats.rating, nbGames = maxPeerGames) - } yield + yield def valueCountOf(answer: Answer[Result], result: Result) = answer.clusters.collectFirst { case Cluster(res, Insight.Stacked(points), _, _) if res == result => diff --git a/modules/tutor/src/main/TutorNumber.scala b/modules/tutor/src/main/TutorNumber.scala index 54599934e501f..5576eb5de919a 100644 --- a/modules/tutor/src/main/TutorNumber.scala +++ b/modules/tutor/src/main/TutorNumber.scala @@ -14,9 +14,9 @@ trait TutorNumber[V]: vs.foldLeft((0d, 0)) { case ((sum, total), ValueCount(value, count)) => (sum + iso.to(value) * count, total + count) } match - case (sum, total) => ValueCount(iso.from(if (total > 0) sum / total else 0), total) + case (sum, total) => ValueCount(iso.from(if total > 0 then sum / total else 0), total) def mean(a: ValueCount[V], b: ValueCount[V]): ValueCount[V] = - if (a.count < 1 && b.count < 1) ValueCount(iso from 0, 0) + if a.count < 1 && b.count < 1 then ValueCount(iso from 0, 0) else ValueCount( iso.from((double(a.value) * a.count + double(b.value) * b.count) / (a.count + b.count)), diff --git a/modules/tutor/src/main/model.scala b/modules/tutor/src/main/model.scala index 8fbc18564724b..599e077215ab6 100644 --- a/modules/tutor/src/main/model.scala +++ b/modules/tutor/src/main/model.scala @@ -31,7 +31,7 @@ case class TutorBothValueOptions[A](mine: Option[ValueCount[A]], peer: Option[Va ): def map[B: Ordering](f: A => B) = TutorBothValueOptions(mine.map(_ map f), peer.map(_ map f)) def higher = mine.exists(m => peer.exists(p => o.compare(m.value, p.value) >= 0)) - def asAvailable = for { m <- mine; p <- peer } yield TutorBothValuesAvailable(m, p) + def asAvailable = for m <- mine; p <- peer yield TutorBothValuesAvailable(m, p) def grade(using TutorNumber[A]): Option[Grade] = asAvailable.map(_.grade) def mix(other: TutorBothValueOptions[A])(using number: TutorNumber[A]): TutorBothValueOptions[A] = diff --git a/modules/tutor/src/test/GlickoTest.scala b/modules/tutor/src/test/GlickoTest.scala index f19b90fa1a27d..9ebcbcd9c9206 100644 --- a/modules/tutor/src/test/GlickoTest.scala +++ b/modules/tutor/src/test/GlickoTest.scala @@ -2,7 +2,7 @@ package lila.tutor import lila.rating.Perf -class GlickoTest extends munit.FunSuite { +class GlickoTest extends munit.FunSuite: test("glicko for arbitrary outcomes") { assertEquals( @@ -16,4 +16,3 @@ class GlickoTest extends munit.FunSuite { 1669 ) } -} diff --git a/modules/tv/src/main/Tv.scala b/modules/tv/src/main/Tv.scala index 818f947eea298..550615358eeb9 100644 --- a/modules/tv/src/main/Tv.scala +++ b/modules/tv/src/main/Tv.scala @@ -27,7 +27,7 @@ final class Tv( def getGameAndHistory(channel: Tv.Channel): Fu[Option[(Game, List[Pov])]] = trouper.ask[GameIdAndHistory](TvSyncActor.GetGameIdAndHistory(channel, _)) flatMap { case GameIdAndHistory(gameId, historyIds) => - for { + for game <- gameId so roundProxyGame games <- historyIds @@ -37,7 +37,7 @@ final class Tv( .parallel .dmap(_.flatten) history = games map Pov.naturalOrientation - } yield game map (_ -> history) + yield game map (_ -> history) } def getGames(channel: Tv.Channel, max: Int): Fu[List[Game]] = diff --git a/modules/tv/src/main/TvSyncActor.scala b/modules/tv/src/main/TvSyncActor.scala index 9b58ecbcd57a0..b78f612d5156a 100644 --- a/modules/tv/src/main/TvSyncActor.scala +++ b/modules/tv/src/main/TvSyncActor.scala @@ -53,7 +53,7 @@ final private[tv] class TvSyncActor( case GetChampions(promise) => promise success Tv.Champions(channelChampions) case lila.game.actorApi.StartGame(g) => - if (g.hasClock) + if g.hasClock then val candidate = Tv.Candidate(g, g.userIds.exists(lightUserApi.isBotSync)) channelTroupers collect { case (chan, trouper) if chan filter candidate => trouper @@ -89,7 +89,7 @@ final private[tv] class TvSyncActor( } ) Bus.publish(lila.hub.actorApi.tv.TvSelect(game.id, game.speed, data), "tvSelect") - if (channel == Tv.Channel.Best) + if channel == Tv.Channel.Best then actorAsk(renderer.actor, RenderFeaturedJs(game))(makeTimeout(100 millis)) foreach { case html: String => val pov = Pov naturalOrientation game diff --git a/modules/ublog/src/main/UblogApi.scala b/modules/ublog/src/main/UblogApi.scala index a4958e15a991f..c14776cb925d0 100644 --- a/modules/ublog/src/main/UblogApi.scala +++ b/modules/ublog/src/main/UblogApi.scala @@ -39,11 +39,11 @@ final class UblogApi( colls.post.updateField($id(post.id), "rank", rank).void } >>- { lila.common.Bus.publish(UblogPost.Create(post), "ublogPost") - if (blog.visible) + if blog.visible then timeline ! Propagate( lila.hub.actorApi.timeline.UblogPost(user.id, post.id, post.slug, post.title) ).toFollowersOf(user.id) - if (blog.modTier.isEmpty) sendPostToZulipMaybe(user, post).unit + if blog.modTier.isEmpty then sendPostToZulipMaybe(user, post).unit } def getUserBlog(user: User, insertMissing: Boolean = false): Fu[UblogBlog] = @@ -146,7 +146,7 @@ final class UblogApi( colls.post.find($doc("blog" -> s"user:${user.id}")).cursor[UblogPost](temporarilyPrimary) private[ublog] def setShadowban(userId: UserId, v: Boolean) = { - if (v) fuccess(UblogBlog.Tier.HIDDEN) + if v then fuccess(UblogBlog.Tier.HIDDEN) else userApi.withPerfs(userId).map(_.fold(UblogBlog.Tier.HIDDEN)(UblogBlog.Tier.default)) }.flatMap: setTier(UblogBlog.Id.User(userId), _) diff --git a/modules/ublog/src/main/UblogPaginator.scala b/modules/ublog/src/main/UblogPaginator.scala index d573c55b458f1..5c21b6febedf9 100644 --- a/modules/ublog/src/main/UblogPaginator.scala +++ b/modules/ublog/src/main/UblogPaginator.scala @@ -31,7 +31,7 @@ final class UblogPaginator( collection = colls.post, selector = $doc("blog" -> blog, "live" -> live), projection = previewPostProjection.some, - sort = if (live) $doc("lived.at" -> -1) else $doc("created.at" -> -1), + sort = if live then $doc("lived.at" -> -1) else $doc("created.at" -> -1), _.sec ), currentPage = page, @@ -40,12 +40,12 @@ final class UblogPaginator( def liveByCommunity(lang: Option[Lang], page: Int): Fu[Paginator[PreviewPost]] = Paginator( - adapter = new AdapterLike[PreviewPost] { + adapter = new AdapterLike[PreviewPost]: val select = $doc("live" -> true, "topics" $ne UblogTopic.offTopic) ++ lang.so: l => $doc("language" -> l.code) def nbResults: Fu[Int] = fuccess(10 * maxPerPage.value) def slice(offset: Int, length: Int) = aggregateVisiblePosts(select, offset, length) - }, + , currentPage = page, maxPerPage = maxPerPage ) @@ -65,11 +65,11 @@ final class UblogPaginator( def liveByTopic(topic: UblogTopic, page: Int): Fu[Paginator[PreviewPost]] = Paginator( - adapter = new AdapterLike[PreviewPost] { + adapter = new AdapterLike[PreviewPost]: def nbResults: Fu[Int] = fuccess(10 * maxPerPage.value) def slice(offset: Int, length: Int) = aggregateVisiblePosts($doc("topics" -> topic), offset, length) - }, + , currentPage = page, maxPerPage = maxPerPage ) diff --git a/modules/ublog/src/main/UblogViewCounter.scala b/modules/ublog/src/main/UblogViewCounter.scala index 0df818507e612..8ce8f275cb931 100644 --- a/modules/ublog/src/main/UblogViewCounter.scala +++ b/modules/ublog/src/main/UblogViewCounter.scala @@ -13,13 +13,14 @@ final class UblogViewCounter(colls: UblogColls)(using Executor): ) def apply(post: UblogPost, ip: IpAddress): UblogPost = - if (post.live) post.copy(views = - val key = s"${post.id}:${ip.value}" - if bloomFilter mightContain key then post.views - else - bloomFilter.add(key) - lila.mon.ublog.view(post.created.by.value).increment() - colls.post.incFieldUnchecked($id(post.id), "views") - post.views + 1 - ) + if post.live then + post.copy(views = + val key = s"${post.id}:${ip.value}" + if bloomFilter mightContain key then post.views + else + bloomFilter.add(key) + lila.mon.ublog.view(post.created.by.value).increment() + colls.post.incFieldUnchecked($id(post.id), "views") + post.views + 1 + ) else post diff --git a/modules/ublog/src/test/UblogMarkupTest.scala b/modules/ublog/src/test/UblogMarkupTest.scala index e6ba0c5b2e990..01da3e162b75c 100644 --- a/modules/ublog/src/test/UblogMarkupTest.scala +++ b/modules/ublog/src/test/UblogMarkupTest.scala @@ -2,7 +2,7 @@ package lila.ublog import lila.common.Markdown -class UblogMarkupTest extends munit.FunSuite { +class UblogMarkupTest extends munit.FunSuite: val m = UblogMarkup @@ -47,4 +47,3 @@ class UblogMarkupTest extends munit.FunSuite { assertEquals(m.unescapeAtUsername(Markdown("""> \(By @neio_1\)""")), Markdown("""> \(By @neio_1\)""")) assertEquals(m.unescapeAtUsername(Markdown("""> \(By @neio\_1\)""")), Markdown("""> \(By @neio_1\)""")) } -} diff --git a/modules/user/src/main/Authenticator.scala b/modules/user/src/main/Authenticator.scala index e6cec0c82cde0..1f133b820e958 100644 --- a/modules/user/src/main/Authenticator.scala +++ b/modules/user/src/main/Authenticator.scala @@ -18,7 +18,7 @@ final class Authenticator( def compare(auth: AuthData, p: ClearPassword): Boolean = val newP = auth.salt.fold(p) { s => val salted = s"${p.value}{$s}" // BC - ClearPassword(if (~auth.sha512) salted.sha512 else salted.sha1) + ClearPassword(if ~auth.sha512 then salted.sha512 else salted.sha1) } passHasher.check(auth.bpass, newP) @@ -50,7 +50,7 @@ final class Authenticator( private def authWithBenefits(auth: AuthData)(p: ClearPassword): Boolean = val res = compare(auth, p) - if (res && auth.salt.isDefined) + if res && auth.salt.isDefined then setPassword(id = auth._id, p) >>- lila.mon.user.auth.bcFullMigrate.increment().unit res diff --git a/modules/user/src/main/Cached.scala b/modules/user/src/main/Cached.scala index 3f99cded61758..564f286c6de81 100644 --- a/modules/user/src/main/Cached.scala +++ b/modules/user/src/main/Cached.scala @@ -98,5 +98,5 @@ final class Cached( _.expireAfterWrite(5 minutes).buildAsyncFuture(userIdsLikeFetch) def userIdsLike(text: UserStr): Fu[List[UserId]] = - if (text.value.lengthIs < 5) userIdsLikeCache get text + if text.value.lengthIs < 5 then userIdsLikeCache get text else userIdsLikeFetch(text) diff --git a/modules/user/src/main/LightUserApi.scala b/modules/user/src/main/LightUserApi.scala index 8f1e06d88d60e..16637e11aeba1 100644 --- a/modules/user/src/main/LightUserApi.scala +++ b/modules/user/src/main/LightUserApi.scala @@ -43,11 +43,12 @@ final class LightUserApi(repo: UserRepo, cacheApi: CacheApi)(using Executor) ext name = "user.light", initialCapacity = 1024 * 1024, compute = id => - if (User isGhost id) fuccess(LightUser.ghost.some) + if User isGhost id then fuccess(LightUser.ghost.some) else repo.coll.find($id(id), projection).one[LightUser] recover { case _: reactivemongo.api.bson.exceptions.BSONValueNotFoundException => LightUser.ghost.some - }, + } + , default = id => LightUser(id, id into UserName, None, isPatron = false).some, strategy = Syncache.Strategy.WaitAfterUptime(10 millis), expireAfter = Syncache.ExpireAfter.Write(20 minutes) diff --git a/modules/user/src/main/Links.scala b/modules/user/src/main/Links.scala index 9aab5b2bb5d7f..1653b5b0c31ae 100644 --- a/modules/user/src/main/Links.scala +++ b/modules/user/src/main/Links.scala @@ -17,11 +17,11 @@ object Links: } private def toLink(line: String): Option[Link] = - for { + for url <- Try(URL.parse(line)).toOption if url.scheme == "http" || url.scheme == "https" host <- Option(url.host).map(_.toHostString) - } yield Site.allKnown.find(_ matches host).map(site => Link(site, url.toString)) | Link( + yield Site.allKnown.find(_ matches host).map(site => Link(site, url.toString)) | Link( Site.Other(host), url.toString ) diff --git a/modules/user/src/main/PasswordHasher.scala b/modules/user/src/main/PasswordHasher.scala index 6ca6ef615f45a..8017610cc41ca 100644 --- a/modules/user/src/main/PasswordHasher.scala +++ b/modules/user/src/main/PasswordHasher.scala @@ -17,9 +17,9 @@ final private class Aes(secret: Secret): private val sKey = val sk = Base64.getDecoder.decode(secret.value) val kBits = sk.length * 8 - if (kBits != 128) - if (!(kBits == 192 || kBits == 256)) throw new IllegalArgumentException - if (kBits > Cipher.getMaxAllowedKeyLength("AES/CTS/NoPadding")) + if kBits != 128 then + if !(kBits == 192 || kBits == 256) then throw new IllegalArgumentException + if kBits > Cipher.getMaxAllowedKeyLength("AES/CTS/NoPadding") then throw new IllegalStateException(s"$kBits bit AES unavailable") new SecretKeySpec(sk, "AES") diff --git a/modules/user/src/main/Stat.scala b/modules/user/src/main/Stat.scala index cdac99bfb15a3..f8f7e64c7c111 100644 --- a/modules/user/src/main/Stat.scala +++ b/modules/user/src/main/Stat.scala @@ -8,6 +8,6 @@ object Stat: def percentile(ratings: List[Int], rating: IntRating): (Int, Int) = ratings.zipWithIndex.foldLeft(0 -> 0) { case ((under, sum), (nb, i)) => { - if (rating > minRating.value + i * group + group / 2) under + nb else under + if rating > minRating.value + i * group + group / 2 then under + nb else under } -> (sum + nb) } diff --git a/modules/user/src/main/Trophy.scala b/modules/user/src/main/Trophy.scala index f4f71865d6cf5..dd1d78da45639 100644 --- a/modules/user/src/main/Trophy.scala +++ b/modules/user/src/main/Trophy.scala @@ -11,7 +11,7 @@ case class Trophy( def timestamp = date.toMillis def compare(other: Trophy) = - if (kind.order == other.kind.order) date compareTo other.date + if kind.order == other.kind.order then date compareTo other.date else Integer.compare(kind.order, other.kind.order) def anyUrl = url orElse kind.url diff --git a/modules/user/src/main/TrophyApi.scala b/modules/user/src/main/TrophyApi.scala index 15b75a933b6a0..968a01dc929d4 100644 --- a/modules/user/src/main/TrophyApi.scala +++ b/modules/user/src/main/TrophyApi.scala @@ -15,10 +15,10 @@ final class TrophyApi( cacheApi.sync[String, TrophyKind]( name = "trophy.kind", initialCapacity = 32, - compute = id => { + compute = id => given BSONDocumentReader[TrophyKind] = Macros.reader[TrophyKind] kindColl.byId[TrophyKind](id).dmap(_ | TrophyKind.Unknown) - }, + , default = _ => TrophyKind.Unknown, strategy = Syncache.Strategy.WaitAfterUptime(20 millis), expireAfter = Syncache.ExpireAfter.Write(1 hour) diff --git a/modules/user/src/main/User.scala b/modules/user/src/main/User.scala index d1cdaed0f6eef..67bdbd97881b8 100644 --- a/modules/user/src/main/User.scala +++ b/modules/user/src/main/User.scala @@ -132,7 +132,7 @@ object User: if check(p.password) then user.totpSecret.fold[Result](Result.Success(user)) { tp => p.token.fold[Result](Result.MissingTotpToken) { token => - if (tp verify token) Result.Success(user) else Result.InvalidTotpToken + if tp verify token then Result.Success(user) else Result.InvalidTotpToken } } else if isBlanked then Result.BlankedPassword diff --git a/modules/user/src/main/UserApi.scala b/modules/user/src/main/UserApi.scala index 3d2ab6575ca9c..cd20bd75cd7a0 100644 --- a/modules/user/src/main/UserApi.scala +++ b/modules/user/src/main/UserApi.scala @@ -76,7 +76,7 @@ final class UserApi(userRepo: UserRepo, perfsRepo: UserPerfsRepo, cacheApi: Cach userRepo.addTitle(user.id, Title.BOT) >> perfsRepo.setBotInitialPerfs(user.id) - def botsByIdsStream(ids: Iterable[UserId], nb: Option[Int]): Source[User.WithPerfs, _] = + def botsByIdsStream(ids: Iterable[UserId], nb: Option[Int]): Source[User.WithPerfs, ?] = userRepo.coll .find($inIds(ids) ++ userRepo.botSelect(true)) .cursor[User](temporarilyPrimary) diff --git a/modules/user/src/main/UserMark.scala b/modules/user/src/main/UserMark.scala index 3fe52e42521d0..b09827f01e183 100644 --- a/modules/user/src/main/UserMark.scala +++ b/modules/user/src/main/UserMark.scala @@ -37,7 +37,7 @@ object UserMarks extends TotalWrapper[UserMarks, List[UserMark]]: def anyVisible = a.boost || a.engine def set(sel: UserMark.type => UserMark, v: Boolean) = UserMarks { - if (v) sel(UserMark) :: a.value + if v then sel(UserMark) :: a.value else a.value.filter(sel(UserMark) !=) } diff --git a/modules/user/src/main/UserPerfs.scala b/modules/user/src/main/UserPerfs.scala index 9aa033c13ac59..b99a933c44b55 100644 --- a/modules/user/src/main/UserPerfs.scala +++ b/modules/user/src/main/UserPerfs.scala @@ -91,7 +91,7 @@ case class UserPerfs( ps.foldLeft(none[IntRating]): case (ro, p) if p.nb >= minNb => ro.fold(p.intRating) { r => - if (p.intRating > r) p.intRating else r + if p.intRating > r then p.intRating else r }.some case (ro, _) => ro .getOrElse(Perf.default.intRating) @@ -108,7 +108,7 @@ case class UserPerfs( def bestProgressIn(types: List[PerfType]): IntRatingDiff = types.foldLeft(IntRatingDiff(0)): (max, t) => val p = apply(t).progress - if (p > max) p else max + if p > max then p else max lazy val perfsMap: Map[Perf.Key, Perf] = Map( Perf.Key("chess960") -> chess960, diff --git a/modules/user/src/main/UserRepo.scala b/modules/user/src/main/UserRepo.scala index be6441310dd46..61eade552259c 100644 --- a/modules/user/src/main/UserRepo.scala +++ b/modules/user/src/main/UserRepo.scala @@ -45,10 +45,9 @@ final class UserRepo(val coll: Coll, perfsRepo: UserPerfsRepo)(using Executor): def enabledById[U: UserIdOf](u: U): Fu[Option[User]] = User.noGhost(u.id) so coll.one[User](enabledSelect ++ $id(u)) - def enabledByIds[U: UserIdOf](us: Iterable[U]): Fu[List[User]] = { + def enabledByIds[U: UserIdOf](us: Iterable[U]): Fu[List[User]] = val ids = us.map(_.id).filter(User.noGhost) coll.list[User](enabledSelect ++ $inIds(ids), _.priTemp) - } def byIdOrGhost(id: UserId): Fu[Option[Either[LightUser.Ghost, User]]] = if User isGhost id @@ -165,8 +164,8 @@ final class UserRepo(val coll: Coll, perfsRepo: UserPerfsRepo)(using Executor): _.fold(ThreadLocalRandom.nextBoolean()): doc => doc.string("_id") contains u1 .addEffect: v => - incColor(u1, if (v) 1 else -1) - incColor(u2, if (v) -1 else 1) + incColor(u1, if v then 1 else -1) + incColor(u2, if v then -1 else 1) def firstGetsWhite(u1O: Option[UserId], u2O: Option[UserId]): Fu[Boolean] = (u1O, u2O).mapN(firstGetsWhite) | fuccess(ThreadLocalRandom.nextBoolean()) @@ -176,7 +175,7 @@ final class UserRepo(val coll: Coll, perfsRepo: UserPerfsRepo)(using Executor): .update(ordered = false, WriteConcern.Unacknowledged) .one( // limit to -3 <= colorIt <= 5 but set when undefined - $id(userId) ++ $doc(F.colorIt -> $not(if (value < 0) $lte(-3) else $gte(5))), + $id(userId) ++ $doc(F.colorIt -> $not(if value < 0 then $lte(-3) else $gte(5))), $inc(F.colorIt -> value) ) .unit @@ -189,12 +188,12 @@ final class UserRepo(val coll: Coll, perfsRepo: UserPerfsRepo)(using Executor): coll.updateField($id(id), F.profile, profile).void def setUsernameCased(id: UserId, name: UserName): Funit = - if (id is name) + if id is name then coll.update.one( $id(id) ++ (F.changedCase $exists false), $set(F.username -> name, F.changedCase -> true) ) flatMap { result => - if (result.n == 0) fufail(s"You have already changed your username") + if result.n == 0 then fufail(s"You have already changed your username") else funit } else fufail(s"Proposed username $name does not match old username $id") @@ -211,7 +210,7 @@ final class UserRepo(val coll: Coll, perfsRepo: UserPerfsRepo)(using Executor): val enabledSelect = $doc(F.enabled -> true) val disabledSelect = $doc(F.enabled -> false) def markSelect(mark: UserMark)(v: Boolean): Bdoc = - if (v) $doc(F.marks -> mark.key) + if v then $doc(F.marks -> mark.key) else F.marks $ne mark.key def engineSelect = markSelect(UserMark.Engine) def trollSelect = markSelect(UserMark.Troll) @@ -237,12 +236,12 @@ final class UserRepo(val coll: Coll, perfsRepo: UserPerfsRepo)(using Executor): "count.game".some, rated option "count.rated", ai option "count.ai", - (result match { + (result match case -1 => "count.loss".some case 1 => "count.win".some case 0 => "count.draw".some case _ => none - }), + ), (result match { case -1 => "count.lossH".some case 1 => "count.winH".some @@ -361,7 +360,7 @@ final class UserRepo(val coll: Coll, perfsRepo: UserPerfsRepo)(using Executor): .one( $id(user.id), $set(F.enabled -> false) ++ $unset(F.roles) ++ { - if (keepEmail) $unset(F.mustConfirmEmail) + if keepEmail then $unset(F.mustConfirmEmail) else $doc("$rename" -> $doc(F.email -> F.prevEmail)) } ) diff --git a/modules/user/src/test/AuthTest.scala b/modules/user/src/test/AuthTest.scala index 5e0f5dd9f0a61..758d224560939 100644 --- a/modules/user/src/test/AuthTest.scala +++ b/modules/user/src/test/AuthTest.scala @@ -2,11 +2,11 @@ package lila.user import java.util.Base64 import Authenticator.AuthData -import User.{ ClearPassword => P } +import User.{ ClearPassword as P } import lila.common.config.Secret import scala.concurrent.ExecutionContext.Implicits.global -class AuthTest extends munit.FunSuite { +class AuthTest extends munit.FunSuite: given Conversion[String, UserId] = UserId(_) @@ -86,4 +86,3 @@ class AuthTest extends munit.FunSuite { test("migrated wrong sha") { assert(!auth.compare(shaToBcrypt.copy(sha512 = Some(true)), P("password"))) } -} diff --git a/modules/user/src/test/BCryptTest.scala b/modules/user/src/test/BCryptTest.scala index 051d09c45308a..16dbb0c3e67af 100644 --- a/modules/user/src/test/BCryptTest.scala +++ b/modules/user/src/test/BCryptTest.scala @@ -3,7 +3,7 @@ package lila.user import java.nio.charset.StandardCharsets.UTF_8 import org.mindrot.BCrypt -class BCryptTest extends munit.FunSuite { +class BCryptTest extends munit.FunSuite: // From jBcrypt test suite. val pass = "abc" @@ -28,7 +28,7 @@ class BCryptTest extends munit.FunSuite { assertEquals(rawHash.size, 23) } - import BCrypt.{ encode_base64 => bc64 } + import BCrypt.{ encode_base64 as bc64 } val bString = "$2a$06$" + bc64(salt) + bc64(rawHash) test("raw bytes accept good") { assert(BCrypt.checkpw(pass, bString)) @@ -36,4 +36,3 @@ class BCryptTest extends munit.FunSuite { test("raw bytes reject bad") { assert(!BCrypt.checkpw("", bString)) } -} diff --git a/modules/user/src/test/PasswordHasherTest.scala b/modules/user/src/test/PasswordHasherTest.scala index eee1313bb8b4c..c5d9d79552db0 100644 --- a/modules/user/src/test/PasswordHasherTest.scala +++ b/modules/user/src/test/PasswordHasherTest.scala @@ -1,9 +1,9 @@ package lila.user import lila.common.config.Secret -import User.{ ClearPassword => P } +import User.{ ClearPassword as P } -class PasswordHasherTest extends munit.FunSuite { +class PasswordHasherTest extends munit.FunSuite: test("bad secrets throw exceptions") { intercept[IllegalArgumentException] { @@ -57,4 +57,3 @@ class PasswordHasherTest extends munit.FunSuite { test("hasher uniq hash") { assertNotEquals(liHash, passHasher.hash(P("abc"))) } -} diff --git a/modules/user/src/test/TotpTest.scala b/modules/user/src/test/TotpTest.scala index 30e66229a5ac7..c2fe6ff6caaa1 100644 --- a/modules/user/src/test/TotpTest.scala +++ b/modules/user/src/test/TotpTest.scala @@ -3,7 +3,7 @@ package lila.user import java.nio.charset.StandardCharsets.UTF_8 import User.TotpToken -class TotpTest extends munit.FunSuite { +class TotpTest extends munit.FunSuite: test("read and write secret") { val secret = TotpSecret.random @@ -33,4 +33,3 @@ class TotpTest extends munit.FunSuite { assertEquals(secret.totp(2000000000L / 30), TotpToken("279037")) assertEquals(secret.totp(20000000000L / 30), TotpToken("353130")) } -} diff --git a/modules/user/src/test/UserTest.scala b/modules/user/src/test/UserTest.scala index bea864af82a8b..145a3a8d09bdf 100644 --- a/modules/user/src/test/UserTest.scala +++ b/modules/user/src/test/UserTest.scala @@ -1,6 +1,6 @@ package lila.user -class UserTest extends munit.FunSuite { +class UserTest extends munit.FunSuite: given Conversion[String, UserStr] = UserStr(_) given Conversion[String, UserId] = UserId(_) @@ -53,5 +53,3 @@ class UserTest extends munit.FunSuite { assert(couldBeUsername("G_FOo")) assert(couldBeUsername("g-foo")) } - -} diff --git a/modules/video/src/main/CsvParser.scala b/modules/video/src/main/CsvParser.scala index bb9180759070f..b3cfe2a8cdbfa 100644 --- a/modules/video/src/main/CsvParser.scala +++ b/modules/video/src/main/CsvParser.scala @@ -38,94 +38,76 @@ object CSVParser: var pos = 0 val buflen = buf.length - if (buf.length > 0 && buf(0) == '\uFEFF') - pos += 1 + if buf.length > 0 && buf(0) == '\uFEFF' then pos += 1 - while (state != End && pos < buflen) + while state != End && pos < buflen do val c = buf(pos) (state: @switch) match - case Start => { + case Start => c match - case `quoteChar` => { + case `quoteChar` => state = QuoteStart pos += 1 - } - case `delimiter` => { + case `delimiter` => fields :+= field.toString field = new StringBuilder state = Delimiter pos += 1 - } - case '\n' | '\u2028' | '\u2029' | '\u0085' => { + case '\n' | '\u2028' | '\u2029' | '\u0085' => fields :+= field.toString field = new StringBuilder state = End pos += 1 - } - case '\r' => { - if (pos + 1 < buflen && buf(1) == '\n') - pos += 1 + case '\r' => + if pos + 1 < buflen && buf(1) == '\n' then pos += 1 fields :+= field.toString field = new StringBuilder state = End pos += 1 - } - case x => { + case x => field += x state = Field pos += 1 - } - } - case Delimiter => { + case Delimiter => c match - case `quoteChar` => { + case `quoteChar` => state = QuoteStart pos += 1 - } - case `escapeChar` => { - if ( - pos + 1 < buflen + case `escapeChar` => + if pos + 1 < buflen && (buf(pos + 1) == escapeChar || buf(pos + 1) == delimiter) - ) + then field += buf(pos + 1) state = Field pos += 2 else throw new MalformedCSVException(buf.mkString) - } - case `delimiter` => { + case `delimiter` => fields :+= field.toString field = new StringBuilder state = Delimiter pos += 1 - } - case '\n' | '\u2028' | '\u2029' | '\u0085' => { + case '\n' | '\u2028' | '\u2029' | '\u0085' => fields :+= field.toString field = new StringBuilder state = End pos += 1 - } - case '\r' => { - if (pos + 1 < buflen && buf(1) == '\n') - pos += 1 + case '\r' => + if pos + 1 < buflen && buf(1) == '\n' then pos += 1 fields :+= field.toString field = new StringBuilder state = End pos += 1 - } - case x => { + case x => field += x state = Field pos += 1 - } - } - case Field => { + case Field => c match - case `escapeChar` => { - if (pos + 1 < buflen) - if ( - buf(pos + 1) == escapeChar + case `escapeChar` => + if pos + 1 < buflen then + if buf(pos + 1) == escapeChar || buf(pos + 1) == delimiter - ) + then field += buf(pos + 1) state = Field pos += 2 @@ -133,97 +115,77 @@ object CSVParser: else state = QuoteEnd pos += 1 - } - case `delimiter` => { + case `delimiter` => fields :+= field.toString field = new StringBuilder state = Delimiter pos += 1 - } - case '\n' | '\u2028' | '\u2029' | '\u0085' => { + case '\n' | '\u2028' | '\u2029' | '\u0085' => fields :+= field.toString field = new StringBuilder state = End pos += 1 - } - case '\r' => { - if (pos + 1 < buflen && buf(1) == '\n') - pos += 1 + case '\r' => + if pos + 1 < buflen && buf(1) == '\n' then pos += 1 fields :+= field.toString field = new StringBuilder state = End pos += 1 - } - case x => { + case x => field += x state = Field pos += 1 - } - } - case QuoteStart => { + case QuoteStart => c match - case `escapeChar` if escapeChar != quoteChar => { - if (pos + 1 < buflen) - if ( - buf(pos + 1) == escapeChar + case `escapeChar` if escapeChar != quoteChar => + if pos + 1 < buflen then + if buf(pos + 1) == escapeChar || buf(pos + 1) == quoteChar - ) + then field += buf(pos + 1) state = QuotedField pos += 2 else throw new MalformedCSVException(buf.mkString) - else - throw new MalformedCSVException(buf.mkString) - } - case `quoteChar` => { - if (pos + 1 < buflen && buf(pos + 1) == quoteChar) + else throw new MalformedCSVException(buf.mkString) + case `quoteChar` => + if pos + 1 < buflen && buf(pos + 1) == quoteChar then field += quoteChar state = QuotedField pos += 2 else state = QuoteEnd pos += 1 - } - case x => { + case x => field += x state = QuotedField pos += 1 - } - } - case QuoteEnd => { + case QuoteEnd => c match - case `delimiter` => { + case `delimiter` => fields :+= field.toString field = new StringBuilder state = Delimiter pos += 1 - } - case '\n' | '\u2028' | '\u2029' | '\u0085' => { + case '\n' | '\u2028' | '\u2029' | '\u0085' => fields :+= field.toString field = new StringBuilder state = End pos += 1 - } - case '\r' => { - if (pos + 1 < buflen && buf(1) == '\n') - pos += 1 + case '\r' => + if pos + 1 < buflen && buf(1) == '\n' then pos += 1 fields :+= field.toString field = new StringBuilder state = End pos += 1 - } - case _ => { + case _ => throw new MalformedCSVException(buf.mkString) - } - } - case QuotedField => { + case QuotedField => c match - case `escapeChar` if escapeChar != quoteChar => { - if (pos + 1 < buflen) - if ( - buf(pos + 1) == escapeChar + case `escapeChar` if escapeChar != quoteChar => + if pos + 1 < buflen then + if buf(pos + 1) == escapeChar || buf(pos + 1) == quoteChar - ) + then field += buf(pos + 1) state = QuotedField pos += 2 @@ -232,41 +194,31 @@ object CSVParser: field += buf(pos + 1) state = QuotedField pos += 2 - else - throw new MalformedCSVException(buf.mkString) - } - case `quoteChar` => { - if (pos + 1 < buflen && buf(pos + 1) == quoteChar) + else throw new MalformedCSVException(buf.mkString) + case `quoteChar` => + if pos + 1 < buflen && buf(pos + 1) == quoteChar then field += quoteChar state = QuotedField pos += 2 else state = QuoteEnd pos += 1 - } - case x => { + case x => field += x state = QuotedField pos += 1 - } - } - case End => { + case End => sys.error("unexpected error") - } (state: @switch) match - case Delimiter => { + case Delimiter => fields :+= "" Some(fields.toList) - } - case QuotedField => { + case QuotedField => None - } - case _ => { + case _ => // When no crlf at end of file state match - case Field | QuoteEnd => { + case Field | QuoteEnd => fields :+= field.toString - } case _ => {} Some(fields.toList) - } diff --git a/modules/video/src/main/Env.scala b/modules/video/src/main/Env.scala index 1010a4da49a47..9997c5ef7ca8e 100644 --- a/modules/video/src/main/Env.scala +++ b/modules/video/src/main/Env.scala @@ -52,7 +52,7 @@ final class Env( case "video" :: "sheet" :: Nil => sheet.fetchAll map { nb => s"Processed $nb videos" } - if (mode == Mode.Prod) + if mode == Mode.Prod then scheduler.scheduleWithFixedDelay(config.sheetDelay, config.sheetDelay) { () => sheet.fetchAll.logFailure(logger).unit } diff --git a/modules/video/src/main/Video.scala b/modules/video/src/main/Video.scala index 334067a79a7fd..a357440276d9c 100644 --- a/modules/video/src/main/Video.scala +++ b/modules/video/src/main/Video.scala @@ -20,7 +20,7 @@ case class Video( def similarity(other: Video) = (tags intersect other.tags).size + (targets intersect other.targets).size + - (if (author == other.author) 1 else 0) + (if author == other.author then 1 else 0) def durationString = metadata.duration.map { seconds => diff --git a/modules/video/src/main/VideoApi.scala b/modules/video/src/main/VideoApi.scala index 1a65d0e06f9cf..429c851e09a1b 100644 --- a/modules/video/src/main/VideoApi.scala +++ b/modules/video/src/main/VideoApi.scala @@ -94,7 +94,7 @@ final private[video] class VideoApi( ) def byTags(user: Option[User], tags: List[Tag], page: Int): Fu[Paginator[VideoView]] = - if (tags.isEmpty) popular(user, page) + if tags.isEmpty then popular(user, page) else Paginator( adapter = new Adapter[Video]( @@ -197,9 +197,10 @@ final private[video] class VideoApi( _.expireAfterAccess(10 minutes) .buildAsyncFuture { filterTags => val allPaths = - if (filterTags.isEmpty) allPopular map { tags => - tags.filterNot(_.isNumeric) - } + if filterTags.isEmpty then + allPopular map { tags => + tags.filterNot(_.isNumeric) + } else videoColl .aggregateList(maxDocs = Int.MaxValue, _.sec): framework => @@ -222,7 +223,7 @@ final private[video] class VideoApi( all find (_.tag == t) } list.sortBy { t => - if (filterTags contains t.tag) Int.MinValue + if filterTags contains t.tag then Int.MinValue else -t.nb } } diff --git a/modules/video/src/main/VideoSheet.scala b/modules/video/src/main/VideoSheet.scala index a976226d7545e..92ba9a6523a82 100644 --- a/modules/video/src/main/VideoSheet.scala +++ b/modules/video/src/main/VideoSheet.scala @@ -52,7 +52,7 @@ final private class VideoSheet(ws: StandaloneWSClient, url: String, api: VideoAp api.video .removeNotIn(entries.map(_.youtubeId)) .map: n => - if (n > 0) logger.info(s"$n videos removed") + if n > 0 then logger.info(s"$n videos removed") processed private def fetch: Fu[List[Entry]] = @@ -69,7 +69,7 @@ final private class VideoSheet(ws: StandaloneWSClient, url: String, api: VideoAp ) } .flatMap { parsed => - for { + for p <- parsed entry <- p match case List(id, author, title, target, tags, lang, ads, _, include, start, _, _) => @@ -80,8 +80,8 @@ final private class VideoSheet(ws: StandaloneWSClient, url: String, api: VideoAp title = title.trim, targets = targets, tags = tags.split(';').map(_.trim.toLowerCase).toList.filter(_.nonEmpty) ::: { - if (targets contains 1) List("beginner") - else if (targets contains 3) List("advanced") + if targets contains 1 then List("beginner") + else if targets contains 3 then List("advanced") else Nil }, lang = lang.trim, @@ -92,7 +92,7 @@ final private class VideoSheet(ws: StandaloneWSClient, url: String, api: VideoAp case _ => none if entry.include if entry.lang == "en" - } yield entry + yield entry } .toList } diff --git a/modules/video/src/main/control.scala b/modules/video/src/main/control.scala index 23d9697c7d0f7..34d86b4d7d417 100644 --- a/modules/video/src/main/control.scala +++ b/modules/video/src/main/control.scala @@ -12,7 +12,7 @@ case class Filter(tags: List[String]): def toggle(tag: String) = copy( - tags = if (tags contains tag) tags filter (tag !=) else tags :+ tag + tags = if tags contains tag then tags filter (tag !=) else tags :+ tag ) case class UserControl(