2016-11-30 07:06:24 -07:00
|
|
|
package lila.pool
|
|
|
|
|
2020-01-14 19:30:51 -07:00
|
|
|
import scala.concurrent.duration._
|
|
|
|
|
2019-12-13 07:30:20 -07:00
|
|
|
import lila.game.{ Game, GameRepo, IdGenerator, Player }
|
2016-12-01 08:31:03 -07:00
|
|
|
import lila.rating.Perf
|
2016-11-30 07:06:24 -07:00
|
|
|
import lila.user.{ User, UserRepo }
|
|
|
|
|
2019-12-13 07:30:20 -07:00
|
|
|
final private class GameStarter(
|
2019-12-01 11:03:39 -07:00
|
|
|
userRepo: UserRepo,
|
|
|
|
gameRepo: GameRepo,
|
|
|
|
idGenerator: IdGenerator,
|
2019-12-09 16:24:43 -07:00
|
|
|
onStart: Game.Id => Unit
|
2020-06-24 03:37:18 -06:00
|
|
|
)(implicit
|
|
|
|
ec: scala.concurrent.ExecutionContext,
|
|
|
|
system: akka.actor.ActorSystem
|
|
|
|
) {
|
2016-12-01 03:23:59 -07:00
|
|
|
|
2019-10-20 16:33:33 -06:00
|
|
|
import PoolApi._
|
|
|
|
|
2021-07-23 06:08:38 -06:00
|
|
|
private val workQueue = new lila.hub.AsyncActorSequencer(maxSize = 32, timeout = 10 seconds, name = "gameStarter")
|
2019-12-09 16:24:43 -07:00
|
|
|
|
2020-05-05 22:11:15 -06:00
|
|
|
def apply(pool: PoolConfig, couples: Vector[MatchMaking.Couple]): Funit =
|
|
|
|
couples.nonEmpty ?? {
|
|
|
|
workQueue {
|
|
|
|
val userIds = couples.flatMap(_.userIds)
|
|
|
|
userRepo.perfOf(userIds, pool.perfType) flatMap { perfs =>
|
2020-05-14 20:03:22 -06:00
|
|
|
idGenerator.games(couples.size) flatMap { ids =>
|
|
|
|
couples.zip(ids).map((one(pool, perfs) _).tupled).sequenceFu.map { pairings =>
|
|
|
|
lila.common.Bus.publish(Pairings(pairings.flatten.toList), "poolPairings")
|
|
|
|
}
|
2020-05-05 22:11:15 -06:00
|
|
|
}
|
2019-10-20 16:33:33 -06:00
|
|
|
}
|
2016-12-01 15:48:46 -07:00
|
|
|
}
|
2016-12-01 08:31:03 -07:00
|
|
|
}
|
|
|
|
|
2019-12-13 07:30:20 -07:00
|
|
|
private def one(pool: PoolConfig, perfs: Map[User.ID, Perf])(
|
2020-05-14 20:03:22 -06:00
|
|
|
couple: MatchMaking.Couple,
|
|
|
|
id: Game.ID
|
2019-12-13 07:30:20 -07:00
|
|
|
): Fu[Option[Pairing]] = {
|
2016-12-01 08:31:03 -07:00
|
|
|
import couple._
|
2020-08-12 00:23:33 -06:00
|
|
|
import cats.implicits._
|
2020-09-21 01:28:28 -06:00
|
|
|
(perfs.get(p1.userId), perfs.get(p2.userId)).mapN((_, _)) ?? { case (perf1, perf2) =>
|
|
|
|
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
|
|
|
|
game = makeGame(
|
|
|
|
id,
|
|
|
|
pool,
|
|
|
|
whiteMember.userId -> whitePerf,
|
|
|
|
blackMember.userId -> blackPerf
|
|
|
|
).start
|
|
|
|
_ <- gameRepo insertDenormalized game
|
|
|
|
} yield {
|
|
|
|
onStart(Game.Id(game.id))
|
|
|
|
Pairing(
|
|
|
|
game,
|
|
|
|
whiteSri = whiteMember.sri,
|
|
|
|
blackSri = blackMember.sri
|
|
|
|
).some
|
|
|
|
}
|
2016-11-30 07:06:24 -07:00
|
|
|
}
|
2016-12-01 08:31:03 -07:00
|
|
|
}
|
2016-11-30 07:06:24 -07:00
|
|
|
|
2016-12-01 08:31:03 -07:00
|
|
|
private def makeGame(
|
2020-05-14 20:03:22 -06:00
|
|
|
id: Game.ID,
|
2019-12-13 07:30:20 -07:00
|
|
|
pool: PoolConfig,
|
|
|
|
whiteUser: (User.ID, Perf),
|
|
|
|
blackUser: (User.ID, Perf)
|
2020-05-05 22:11:15 -06:00
|
|
|
) =
|
2020-05-14 20:03:22 -06:00
|
|
|
Game(
|
|
|
|
id = id,
|
2020-05-05 22:11:15 -06:00
|
|
|
chess = chess.Game(
|
|
|
|
situation = chess.Situation(chess.variant.Standard),
|
|
|
|
clock = pool.clock.toClock.some
|
|
|
|
),
|
|
|
|
whitePlayer = Player.make(chess.White, whiteUser),
|
|
|
|
blackPlayer = Player.make(chess.Black, blackUser),
|
|
|
|
mode = chess.Mode.Rated,
|
2020-05-14 20:03:22 -06:00
|
|
|
status = chess.Status.Created,
|
|
|
|
daysPerTurn = none,
|
|
|
|
metadata = Game.metadata(lila.game.Source.Pool)
|
2020-05-05 22:11:15 -06:00
|
|
|
)
|
2016-11-30 07:06:24 -07:00
|
|
|
}
|