migration WIP
parent
c27821e881
commit
3d179646eb
|
@ -282,7 +282,7 @@ lazy val practice = module("practice", Seq(common, db, memo, user, study)).setti
|
|||
)
|
||||
|
||||
lazy val playban = module("playban", Seq(common, db, game, message, chat)).settings(
|
||||
libraryDependencies ++= provided(play.api) ++ reactivemongo.bundle
|
||||
libraryDependencies ++= provided(play.api, play.joda) ++ reactivemongo.bundle
|
||||
)
|
||||
|
||||
lazy val push = module("push", Seq(common, db, user, game, challenge, message)).settings(
|
||||
|
|
|
@ -3,7 +3,7 @@ package lila.game
|
|||
// Wrapper around newly created games. We do not know if the id is unique, yet.
|
||||
case class NewGame(sloppy: Game) extends AnyVal {
|
||||
def withId(id: Game.ID): Game = sloppy.withId(id)
|
||||
def withUniqueId(implicit idGenerator: IdGenerator): Fu[Game] =
|
||||
def withUniqueId(idGenerator: IdGenerator): Fu[Game] =
|
||||
idGenerator.game dmap sloppy.withId
|
||||
|
||||
def start: NewGame = NewGame(sloppy.start)
|
||||
|
|
|
@ -1,43 +1,27 @@
|
|||
package lila.playban
|
||||
|
||||
import com.typesafe.config.Config
|
||||
import com.softwaremill.macwire._
|
||||
import play.api.Configuration
|
||||
|
||||
import lila.common.config.CollName
|
||||
|
||||
final class Env(
|
||||
config: Config,
|
||||
appConfig: Configuration,
|
||||
messenger: lila.message.MessageApi,
|
||||
chatApi: lila.chat.ChatApi,
|
||||
userRepo: lila.user.UserRepo,
|
||||
lightUser: lila.common.LightUser.Getter,
|
||||
db: lila.db.Env,
|
||||
asyncCache: lila.memo.AsyncCache.Builder
|
||||
) {
|
||||
|
||||
private val settings = new {
|
||||
val CollectionPlayban = config getString "collection.playban"
|
||||
}
|
||||
import settings._
|
||||
|
||||
private lazy val feedback = new PlaybanFeedback(
|
||||
chatApi = chatApi,
|
||||
lightUser = lightUser
|
||||
private lazy val playbanColl = db(
|
||||
CollName(appConfig.get[String]("playban.collection.playban"))
|
||||
)
|
||||
|
||||
lazy val api = new PlaybanApi(
|
||||
coll = db(CollectionPlayban),
|
||||
sandbag = new SandbagWatch(messenger),
|
||||
feedback = feedback,
|
||||
asyncCache = asyncCache,
|
||||
messenger = messenger
|
||||
)
|
||||
}
|
||||
|
||||
object Env {
|
||||
|
||||
lazy val current: Env = "playban" boot new Env(
|
||||
config = lila.common.PlayApp loadConfig "playban",
|
||||
messenger = lila.message.Env.current.api,
|
||||
chatApi = lila.chat.Env.current.api,
|
||||
lightUser = lila.user.Env.current.lightUserApi.async,
|
||||
db = lila.db.Env.current,
|
||||
asyncCache = lila.memo.Env.current.asyncCache
|
||||
)
|
||||
private lazy val feedback = wire[PlaybanFeedback]
|
||||
|
||||
private lazy val sandbag = wire[SandbagWatch]
|
||||
|
||||
lazy val api = wire[PlaybanApi]
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@ import scala.concurrent.duration._
|
|||
|
||||
import chess.variant._
|
||||
import chess.{ Status, Color }
|
||||
import lila.common.PlayApp.startedSinceMinutes
|
||||
import lila.common.{ Bus, Iso }
|
||||
import lila.common.PlayApp.{ startedSinceMinutes, isDev }
|
||||
import lila.db.dsl._
|
||||
import lila.game.{ Pov, Game, Player, Source }
|
||||
import lila.message.{ MessageApi, ModPreset }
|
||||
|
@ -18,16 +18,17 @@ final class PlaybanApi(
|
|||
coll: Coll,
|
||||
sandbag: SandbagWatch,
|
||||
feedback: PlaybanFeedback,
|
||||
userRepo: UserRepo,
|
||||
asyncCache: lila.memo.AsyncCache.Builder,
|
||||
messenger: MessageApi
|
||||
) {
|
||||
|
||||
import lila.db.BSON.BSONJodaDateTimeHandler
|
||||
import reactivemongo.api.bson.Macros
|
||||
private implicit val OutcomeBSONHandler = new BSONHandler[BSONInteger, Outcome] {
|
||||
def read(bsonInt: BSONInteger): Outcome = Outcome(bsonInt.value) err s"No such playban outcome: ${bsonInt.value}"
|
||||
def write(x: Outcome) = BSONInteger(x.id)
|
||||
}
|
||||
private implicit val OutcomeBSONHandler = tryHandler[Outcome](
|
||||
{ case BSONInteger(v) => Outcome(v) toTry s"No such playban outcome: $v" },
|
||||
x => BSONInteger(x.id)
|
||||
)
|
||||
private implicit val RageSitBSONHandler = intIsoHandler(Iso.int[RageSit](RageSit.apply, _.counter))
|
||||
private implicit val BanBSONHandler = Macros.handler[TempBan]
|
||||
private implicit val UserRecordBSONHandler = Macros.handler[UserRecord]
|
||||
|
@ -39,11 +40,11 @@ final class PlaybanApi(
|
|||
private def blameable(game: Game): Fu[Boolean] =
|
||||
(game.source.exists(s => blameableSources(s)) && game.hasClock) ?? {
|
||||
if (game.rated) fuTrue
|
||||
else UserRepo.containsEngine(game.userIds) map (!_)
|
||||
else userRepo.containsEngine(game.userIds) map (!_)
|
||||
}
|
||||
|
||||
private def IfBlameable[A: ornicar.scalalib.Zero](game: Game)(f: => Fu[A]): Fu[A] =
|
||||
(isDev || startedSinceMinutes(10)) ?? {
|
||||
startedSinceMinutes(10) ?? {
|
||||
blameable(game) flatMap { _ ?? f }
|
||||
}
|
||||
|
||||
|
@ -143,11 +144,11 @@ final class PlaybanApi(
|
|||
private val cleanUserIds = new lila.memo.ExpireSetMemo(30 minutes)
|
||||
|
||||
def currentBan(userId: User.ID): Fu[Option[TempBan]] = !cleanUserIds.get(userId) ?? {
|
||||
coll.find(
|
||||
coll.ext.find(
|
||||
$doc("_id" -> userId, "b.0" $exists true),
|
||||
$doc("_id" -> false, "b" -> $doc("$slice" -> -1))
|
||||
).uno[Bdoc].map {
|
||||
_.flatMap(_.getAs[List[TempBan]]("b")).??(_.find(_.inEffect))
|
||||
).uno[Bdoc].dmap {
|
||||
_.flatMap(_.getAsOpt[List[TempBan]]("b")).??(_.find(_.inEffect))
|
||||
} addEffect { ban =>
|
||||
if (ban.isEmpty) cleanUserIds put userId
|
||||
}
|
||||
|
@ -166,15 +167,15 @@ final class PlaybanApi(
|
|||
}
|
||||
}
|
||||
|
||||
def bans(userIds: List[User.ID]): Fu[Map[User.ID, Int]] = coll.find(
|
||||
def bans(userIds: List[User.ID]): Fu[Map[User.ID, Int]] = coll.ext.find(
|
||||
$inIds(userIds),
|
||||
$doc("b" -> true)
|
||||
).list[Bdoc]().map {
|
||||
_.flatMap { obj =>
|
||||
obj.getAs[User.ID]("_id") flatMap { id =>
|
||||
obj.getAs[Barr]("b") map { id -> _.stream.size }
|
||||
obj.getAsOpt[User.ID]("_id") flatMap { id =>
|
||||
obj.getAsOpt[Barr]("b") map { id -> _.size }
|
||||
}
|
||||
}(scala.collection.breakOut)
|
||||
}.toMap
|
||||
}
|
||||
|
||||
def getRageSit(userId: User.ID) = rageSitCache get userId
|
||||
|
@ -196,10 +197,10 @@ final class PlaybanApi(
|
|||
),
|
||||
fetchNewObject = true,
|
||||
upsert = true
|
||||
).map(_.value) map2 UserRecordBSONHandler.read flatten
|
||||
).dmap(_.value flatMap UserRecordBSONHandler.readOpt) orFail
|
||||
s"can't find newly created record for user $userId" flatMap { record =>
|
||||
(outcome != Outcome.Good) ?? {
|
||||
UserRepo.createdAtById(userId).flatMap { _ ?? { legiferate(record, _) } }
|
||||
userRepo.createdAtById(userId).flatMap { _ ?? { legiferate(record, _) } }
|
||||
} >> {
|
||||
(rageSitDelta != 0) ?? registerRageSit(record, rageSitDelta)
|
||||
}
|
||||
|
@ -213,8 +214,8 @@ final class PlaybanApi(
|
|||
lila.log("ragesit").warn(s"Close https://lichess.org/@/${record.userId} ragesit=${record.rageSit}")
|
||||
funit
|
||||
} else if (record.rageSit.isVeryBad) for {
|
||||
mod <- UserRepo.lichess
|
||||
user <- UserRepo byId record.userId
|
||||
mod <- userRepo.lichess
|
||||
user <- userRepo byId record.userId
|
||||
} yield (mod zip user).headOption foreach {
|
||||
case (m, u) =>
|
||||
lila.log("ragesit").info(s"https://lichess.org/@/${u.username} ${record.rageSit.counterView}")
|
||||
|
|
|
@ -8,7 +8,10 @@ import lila.game.Game
|
|||
import lila.message.{ MessageApi, ModPreset }
|
||||
import lila.user.{ User, UserRepo }
|
||||
|
||||
private final class SandbagWatch(messenger: MessageApi) {
|
||||
private final class SandbagWatch(
|
||||
userRepo: UserRepo,
|
||||
messenger: MessageApi
|
||||
) {
|
||||
|
||||
import SandbagWatch._
|
||||
|
||||
|
@ -23,8 +26,8 @@ private final class SandbagWatch(messenger: MessageApi) {
|
|||
}
|
||||
|
||||
private def sendMessage(userId: User.ID): Funit = for {
|
||||
mod <- UserRepo.lichess
|
||||
user <- UserRepo byId userId
|
||||
mod <- userRepo.lichess
|
||||
user <- userRepo byId userId
|
||||
} yield (mod zip user).headOption.?? {
|
||||
case (m, u) =>
|
||||
lila.log("sandbag").info(s"https://lichess.org/@/${u.username}")
|
||||
|
|
|
@ -2,6 +2,7 @@ package lila.playban
|
|||
|
||||
import org.joda.time.DateTime
|
||||
import play.api.libs.json._
|
||||
import play.api.libs.json.JodaWrites._
|
||||
import scala.math.{ log10, sqrt }
|
||||
|
||||
import lila.game.Game
|
||||
|
|
|
@ -1,39 +1,32 @@
|
|||
package lila.pool
|
||||
|
||||
import com.softwaremill.macwire._
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import lila.hub.FutureSequencer
|
||||
import lila.common.Bus
|
||||
import lila.game.Game
|
||||
import lila.hub.FutureSequencer
|
||||
|
||||
final class Env(
|
||||
system: akka.actor.ActorSystem,
|
||||
userRepo: lila.user.UserRepo,
|
||||
gameRepo: lila.game.GameRepo,
|
||||
idGenerator: lila.game.IdGenerator,
|
||||
playbanApi: lila.playban.PlaybanApi
|
||||
) {
|
||||
)(implicit system: akka.actor.ActorSystem) {
|
||||
|
||||
private lazy val hookThieve = new HookThieve()(system)
|
||||
private lazy val hookThieve = wire[HookThieve]
|
||||
|
||||
lazy val api = new PoolApi(
|
||||
configs = PoolList.all,
|
||||
hookThieve = hookThieve,
|
||||
gameStarter = gameStarter,
|
||||
playbanApi = playbanApi,
|
||||
system = system
|
||||
private lazy val configs = PoolList.all
|
||||
|
||||
private lazy val sequencer = new FutureSequencer(
|
||||
system = system,
|
||||
executionTimeout = 5.seconds.some,
|
||||
logger = logger
|
||||
)
|
||||
|
||||
private lazy val gameStarter = new GameStarter(
|
||||
onStart = gameId => Bus.publish(lila.game.Game.Id(gameId), "gameStartId"),
|
||||
sequencer = new FutureSequencer(
|
||||
system = system,
|
||||
executionTimeout = 5.seconds.some,
|
||||
logger = logger
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
object Env {
|
||||
|
||||
lazy val current: Env = "pool" boot new Env(
|
||||
system = lila.common.PlayApp.system,
|
||||
playbanApi = lila.playban.Env.current.api
|
||||
)
|
||||
private val onStart = (gameId: Game.Id) => Bus.publish(gameId, "gameStartId")
|
||||
|
||||
private lazy val gameStarter = wire[GameStarter]
|
||||
|
||||
lazy val api = wire[PoolApi]
|
||||
}
|
||||
|
|
|
@ -3,13 +3,16 @@ package lila.pool
|
|||
import akka.actor._
|
||||
import scala.concurrent.Promise
|
||||
|
||||
import lila.game.{ Game, Player, GameRepo }
|
||||
import lila.game.{ Game, Player, GameRepo, IdGenerator }
|
||||
import lila.hub.FutureSequencer
|
||||
import lila.rating.Perf
|
||||
import lila.user.{ User, UserRepo }
|
||||
|
||||
private final class GameStarter(
|
||||
onStart: Game.ID => Unit,
|
||||
userRepo: UserRepo,
|
||||
gameRepo: GameRepo,
|
||||
idGenerator: IdGenerator,
|
||||
onStart: Game.Id => Unit,
|
||||
sequencer: FutureSequencer
|
||||
) {
|
||||
|
||||
|
@ -18,7 +21,7 @@ private final class GameStarter(
|
|||
def apply(pool: PoolConfig, couples: Vector[MatchMaking.Couple]): Funit = couples.nonEmpty ?? {
|
||||
sequencer {
|
||||
val userIds = couples.flatMap(_.userIds)
|
||||
UserRepo.perfOf(userIds, pool.perfType) flatMap { perfs =>
|
||||
userRepo.perfOf(userIds, pool.perfType) flatMap { perfs =>
|
||||
couples.map(one(pool, perfs)).sequenceFu.map { pairings =>
|
||||
lila.common.Bus.publish(Pairings(pairings.flatten.toList), "poolPairings")
|
||||
}
|
||||
|
@ -30,17 +33,17 @@ private final class GameStarter(
|
|||
import couple._
|
||||
(perfs.get(p1.userId) |@| perfs.get(p2.userId)).tupled ?? {
|
||||
case (perf1, perf2) => for {
|
||||
p1White <- UserRepo.firstGetsWhite(p1.userId, p2.userId)
|
||||
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
|
||||
game <- makeGame(
|
||||
pool,
|
||||
whiteMember.userId -> whitePerf,
|
||||
blackMember.userId -> blackPerf
|
||||
).start.withUniqueId
|
||||
_ <- GameRepo insertDenormalized game
|
||||
).start withUniqueId idGenerator
|
||||
_ <- gameRepo insertDenormalized game
|
||||
} yield {
|
||||
onStart(game.id)
|
||||
onStart(Game.Id(game.id))
|
||||
Pairing(
|
||||
game,
|
||||
whiteSri = whiteMember.sri,
|
||||
|
|
|
@ -76,7 +76,7 @@ object MatchMaking {
|
|||
none
|
||||
},
|
||||
pairs => Some {
|
||||
pairs.map { case (a, b) => Couple(a, b) }(scala.collection.breakOut)
|
||||
pairs.view.map { case (a, b) => Couple(a, b) } to Vector
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ object PoolList {
|
|||
PoolConfig(15 ++ 15, Wave(60 seconds, 16 players))
|
||||
)
|
||||
|
||||
val clockStringSet: Set[String] = all.map(_.clock.show)(scala.collection.breakOut)
|
||||
val clockStringSet: Set[String] = all.view.map(_.clock.show) to Set
|
||||
|
||||
private implicit class PimpedInt(self: Int) {
|
||||
def ++(increment: Int) = chess.Clock.Config(self * 60, increment)
|
||||
|
|
|
@ -15,7 +15,6 @@ final class ShutupApi(
|
|||
reporter: akka.actor.ActorSelection
|
||||
) {
|
||||
|
||||
private implicit val doubleListHandler = bsonArrayToListHandler[Double]
|
||||
private implicit val UserRecordBSONHandler = Macros.handler[UserRecord]
|
||||
import PublicLine.PublicLineBSONHandler
|
||||
|
||||
|
|
Loading…
Reference in New Issue