2014-03-16 14:57:15 -06:00
|
|
|
package lila.game
|
|
|
|
|
2017-07-09 14:27:21 -06:00
|
|
|
import org.joda.time.DateTime
|
2020-04-03 07:03:57 -06:00
|
|
|
import scala.concurrent.ExecutionContext
|
2014-05-21 14:57:10 -06:00
|
|
|
|
2021-09-18 07:09:15 -06:00
|
|
|
import lila.db.AsyncCollFailingSilently
|
2016-04-01 06:23:56 -06:00
|
|
|
import lila.db.dsl._
|
2020-04-03 07:03:57 -06:00
|
|
|
import lila.user.User
|
2014-03-16 14:57:15 -06:00
|
|
|
|
2016-04-01 06:23:56 -06:00
|
|
|
final class CrosstableApi(
|
2021-09-18 07:09:15 -06:00
|
|
|
coll: AsyncCollFailingSilently,
|
|
|
|
matchupColl: AsyncCollFailingSilently,
|
2021-09-18 03:26:00 -06:00
|
|
|
enabled: () => Boolean
|
2020-04-03 07:03:57 -06:00
|
|
|
)(implicit ec: ExecutionContext) {
|
2014-03-16 14:57:15 -06:00
|
|
|
|
2017-10-21 14:01:50 -06:00
|
|
|
import Crosstable.{ Matchup, Result }
|
2017-07-09 14:27:21 -06:00
|
|
|
import Crosstable.{ BSONFields => F }
|
2014-03-16 14:57:15 -06:00
|
|
|
|
2020-05-05 22:11:15 -06:00
|
|
|
def apply(game: Game): Fu[Option[Crosstable]] =
|
2020-09-21 01:28:28 -06:00
|
|
|
game.twoUserIds ?? { case (u1, u2) =>
|
|
|
|
apply(u1, u2) dmap some
|
2020-05-05 22:11:15 -06:00
|
|
|
}
|
2014-03-16 14:57:15 -06:00
|
|
|
|
2020-05-05 22:11:15 -06:00
|
|
|
def withMatchup(game: Game): Fu[Option[Crosstable.WithMatchup]] =
|
2020-09-21 01:28:28 -06:00
|
|
|
game.twoUserIds ?? { case (u1, u2) =>
|
|
|
|
withMatchup(u1, u2) dmap some
|
2020-05-05 22:11:15 -06:00
|
|
|
}
|
2017-07-09 14:27:21 -06:00
|
|
|
|
2020-04-03 07:03:57 -06:00
|
|
|
def apply(u1: User.ID, u2: User.ID): Fu[Crosstable] =
|
2021-09-18 03:53:02 -06:00
|
|
|
justFetch(u1, u2) dmap { _ | Crosstable.empty(u1, u2) }
|
|
|
|
|
|
|
|
def justFetch(u1: User.ID, u2: User.ID): Fu[Option[Crosstable]] = enabled() ??
|
2021-09-18 07:09:15 -06:00
|
|
|
coll(_.one[Crosstable](select(u1, u2)))
|
2014-03-16 14:57:15 -06:00
|
|
|
|
2020-04-03 07:03:57 -06:00
|
|
|
def withMatchup(u1: User.ID, u2: User.ID): Fu[Crosstable.WithMatchup] =
|
2020-11-26 02:02:50 -07:00
|
|
|
apply(u1, u2) zip getMatchup(u1, u2) dmap { case (crosstable, matchup) =>
|
2020-09-21 01:28:28 -06:00
|
|
|
Crosstable.WithMatchup(crosstable, matchup)
|
2017-07-09 14:27:21 -06:00
|
|
|
}
|
|
|
|
|
2021-09-18 03:26:00 -06:00
|
|
|
def nbGames(u1: User.ID, u2: User.ID): Fu[Int] = enabled() ??
|
2021-09-18 07:09:15 -06:00
|
|
|
coll {
|
|
|
|
_.find(
|
2019-12-13 07:30:20 -07:00
|
|
|
select(u1, u2),
|
|
|
|
$doc("s1" -> true, "s2" -> true).some
|
|
|
|
)
|
2021-09-18 07:09:15 -06:00
|
|
|
.one[Bdoc] dmap { res =>
|
|
|
|
~(for {
|
|
|
|
o <- res
|
|
|
|
s1 <- o.int("s1")
|
|
|
|
s2 <- o.int("s2")
|
|
|
|
} yield (s1 + s2) / 10)
|
|
|
|
}
|
2019-12-13 07:30:20 -07:00
|
|
|
}
|
2015-05-24 06:30:18 -06:00
|
|
|
|
2021-09-18 03:30:41 -06:00
|
|
|
def add(game: Game): Funit =
|
2020-05-05 22:11:15 -06:00
|
|
|
game.userIds.distinct.sorted match {
|
|
|
|
case List(u1, u2) =>
|
|
|
|
val result = Result(game.id, game.winnerUserId)
|
|
|
|
val bsonResult = Crosstable.crosstableBSONHandler.writeResult(result, u1)
|
|
|
|
def incScore(userId: User.ID): Int =
|
|
|
|
game.winnerUserId match {
|
|
|
|
case Some(u) if u == userId => 10
|
|
|
|
case None => 5
|
|
|
|
case _ => 0
|
|
|
|
}
|
|
|
|
val inc1 = incScore(u1)
|
|
|
|
val inc2 = incScore(u2)
|
2021-09-18 07:09:15 -06:00
|
|
|
val updateCrosstable = enabled() ?? coll {
|
|
|
|
_.update
|
|
|
|
.one(
|
|
|
|
select(u1, u2),
|
|
|
|
$inc(
|
|
|
|
F.score1 -> inc1,
|
|
|
|
F.score2 -> inc2
|
|
|
|
) ++ $push(
|
|
|
|
Crosstable.BSONFields.results -> $doc(
|
|
|
|
"$each" -> List(bsonResult),
|
|
|
|
"$slice" -> -Crosstable.maxGames
|
|
|
|
)
|
|
|
|
),
|
|
|
|
upsert = true
|
|
|
|
)
|
|
|
|
.void
|
|
|
|
}
|
|
|
|
val updateMatchup = matchupColl {
|
|
|
|
_.update
|
|
|
|
.one(
|
|
|
|
select(u1, u2),
|
|
|
|
$inc(
|
|
|
|
F.score1 -> inc1,
|
|
|
|
F.score2 -> inc2
|
|
|
|
) ++ $set(
|
|
|
|
F.lastPlayed -> DateTime.now
|
|
|
|
),
|
|
|
|
upsert = true
|
|
|
|
)
|
|
|
|
.void
|
|
|
|
}
|
2020-05-05 22:11:15 -06:00
|
|
|
updateCrosstable zip updateMatchup void
|
|
|
|
case _ => funit
|
|
|
|
}
|
2014-03-16 14:57:15 -06:00
|
|
|
|
2017-07-10 02:28:14 -06:00
|
|
|
private val matchupProjection = $doc(F.lastPlayed -> false)
|
2017-07-09 14:27:21 -06:00
|
|
|
|
2020-09-23 04:35:08 -06:00
|
|
|
def getMatchup(u1: User.ID, u2: User.ID): Fu[Option[Matchup]] =
|
2021-09-18 07:09:15 -06:00
|
|
|
matchupColl(_.find(select(u1, u2), matchupProjection.some).one[Matchup])
|
2017-07-09 14:27:21 -06:00
|
|
|
|
2019-01-22 03:41:39 -07:00
|
|
|
private def select(u1: User.ID, u2: User.ID) =
|
2016-07-10 02:08:02 -06:00
|
|
|
$id(Crosstable.makeKey(u1, u2))
|
2014-03-16 14:57:15 -06:00
|
|
|
}
|