store seek rating stability; LobbyUser now has a perfMap

pull/2850/head
Thibault Duplessis 2017-03-24 23:27:10 +01:00
parent 3c87a228ca
commit 382b192de6
5 changed files with 50 additions and 23 deletions

View File

@ -90,7 +90,7 @@ private[lobby] object Biter {
!hook.userId.??(u.blocking.contains) &&
!hook.user.??(_.blocking).contains(u.id) &&
hook.realRatingRange.fold(true) { range =>
(hook.perfType.map(_.key) flatMap u.ratingMap.get) ?? range.contains
(hook.perfType map u.ratingAt) ?? range.contains
}
}
@ -100,7 +100,7 @@ private[lobby] object Biter {
!(user.blocking contains seek.user.id) &&
!(seek.user.blocking contains user.id) &&
seek.realRatingRange.fold(true) { range =>
(seek.perfType map (_.key) flatMap user.ratingMap.get) ?? range.contains
(seek.perfType map user.ratingAt) ?? range.contains
}
@inline final def showHookTo(hook: Hook, member: actorApi.Member): Boolean =

View File

@ -51,22 +51,24 @@ case class Hook(
def userId = user.map(_.id)
def username = user.fold(User.anonymous)(_.username)
def rating = user flatMap { u => perfType map (_.key) flatMap u.ratingMap.get }
def lame = user ?? (_.lame)
lazy val perf: Option[LobbyPerf] = for { u <- user; pt <- perfType } yield u perfAt pt
def rating: Option[Int] = perf.map(_.rating)
lazy val render: JsObject = Json.obj(
"id" -> id,
"uid" -> uid,
"u" -> user.map(_.username),
"rating" -> rating,
"variant" -> realVariant.exotic.option(realVariant.key),
"ra" -> realMode.rated.option(1),
"clock" -> clock.show,
"t" -> clock.estimateTotalTime,
"s" -> speed.id,
"c" -> chess.Color(color).map(_.name),
"perf" -> perfType.map(_.name)
).noNull
"s" -> speed.id
).add("prov" -> perf.map(_.provisional).filter(identity))
.add("u" -> user.map(_.username))
.add("rating" -> rating)
.add("variant" -> realVariant.exotic.option(realVariant.key))
.add("ra" -> realMode.rated.option(1))
.add("c" -> chess.Color(color).map(_.name))
.add("perf" -> perfType.map(_.name))
lazy val perfType = PerfPicker.perfType(speed, realVariant, none)

View File

@ -1,22 +1,43 @@
package lila.lobby
import lila.rating.{ PerfType, Perf, Glicko }
import lila.user.User
private[lobby] case class LobbyUser(
id: String,
username: String,
lame: Boolean,
ratingMap: Map[String, Int],
blocking: Set[String]
)
id: String,
username: String,
lame: Boolean,
perfMap: LobbyUser.PerfMap,
blocking: Set[String]
) {
def perfAt(pt: PerfType): LobbyPerf = perfMap.get(pt.key) | LobbyPerf.default
def ratingAt(pt: PerfType): Int = perfAt(pt).rating
}
private[lobby] object LobbyUser {
type PerfMap = Map[Perf.Key, LobbyPerf]
def make(user: User, blocking: Set[User.ID]) = LobbyUser(
id = user.id,
username = user.username,
lame = user.lame,
ratingMap = user.perfs.ratingMap,
perfMap = perfMapOf(user.perfs),
blocking = blocking
)
private def perfMapOf(perfs: lila.user.Perfs): PerfMap =
perfs.perfs collect {
case (key, perf) if key != "puzzle" && perf.nonEmpty =>
key -> LobbyPerf(perf.intRating, perf.provisional)
} toMap
}
case class LobbyPerf(rating: Int, provisional: Boolean)
object LobbyPerf {
val default = LobbyPerf(Glicko.defaultIntRating, true)
}

View File

@ -8,6 +8,7 @@ import play.api.libs.json._
import lila.game.PerfPicker
import lila.rating.RatingRange
import lila.user.User
import lila.common.PimpedJson._
// correspondence chess, persistent
case class Seek(
@ -35,15 +36,17 @@ case class Seek(
(realColor compatibleWith h.realColor) &&
ratingRangeCompatibleWith(h) && h.ratingRangeCompatibleWith(this)
private def ratingRangeCompatibleWith(h: Seek) = realRatingRange.fold(true) {
range => h.rating ?? range.contains
private def ratingRangeCompatibleWith(s: Seek) = realRatingRange.fold(true) {
range => s.rating ?? range.contains
}
private def compatibilityProperties = (variant, mode, daysPerTurn)
lazy val realRatingRange: Option[RatingRange] = RatingRange noneIfDefault ratingRange
def rating = perfType map (_.key) flatMap user.ratingMap.get
def perf = perfType map user.perfAt
def rating = perf.map(_.rating)
lazy val render: JsObject = Json.obj(
"id" -> _id,
@ -61,7 +64,7 @@ case class Seek(
"icon" -> perfType.map(_.iconChar.toString),
"name" -> perfType.map(_.name)
)
)
).add("provisional" -> perf.map(_.provisional).filter(identity))
lazy val perfType = PerfPicker.perfType(Speed.Correspondence, realVariant, daysPerTurn)
}
@ -103,6 +106,7 @@ object Seek {
import reactivemongo.bson.Macros
import lila.db.BSON.MapValue.MapHandler
import lila.db.BSON.BSONJodaDateTimeHandler
private[lobby] implicit val lobbyPerfBSONHandler = Macros.handler[LobbyPerf]
private[lobby] implicit val lobbyUserBSONHandler = Macros.handler[LobbyUser]
private[lobby] implicit val seekBSONHandler = Macros.handler[Seek]
}

View File

@ -70,7 +70,7 @@ private[lobby] final class SocketHandler(
PoolApi.Joiner(
userId = user.id,
socketId = lila.socket.Socket.Uid(member.uid),
ratingMap = user.ratingMap,
ratingMap = user.perfMap.mapValues(_.rating),
ratingRange = ratingRange,
lame = user.lame,
blocking = user.blocking