enforce tournament conditions

This commit is contained in:
Thibault Duplessis 2016-06-18 13:21:30 +02:00
parent 46127c6d3d
commit d909489eea
7 changed files with 51 additions and 31 deletions

View file

@ -57,7 +57,7 @@ object Tournament extends LilaController {
env.version(tour.id) zip {
ctx.noKid ?? Env.chat.api.userChat.findMine(tour.id, ctx.me).map(some)
}).flatMap {
case ((verdicts, version), chat) => env.jsonView(tour, page, ctx.userId, none, version.some) map {
case ((verdicts, version), chat) => env.jsonView(tour, page, ctx.me, none, version.some) map {
html.tournament.show(tour, verdicts, _, chat)
}
}.map { Ok(_) }.mon(_.http.response.tournament.show.website)
@ -69,7 +69,7 @@ object Tournament extends LilaController {
get("playerInfo").?? { env.api.playerInfo(tour.id, _) } zip
getBool("socketVersion").??(env version tour.id map some) flatMap {
case (playerInfoExt, socketVersion) =>
env.jsonView(tour, page, ctx.userId, playerInfoExt, socketVersion)
env.jsonView(tour, page, ctx.me, playerInfoExt, socketVersion)
} map { Ok(_) }
}.mon(_.http.response.tournament.show.mobile)
} map (_ as JSON)

View file

@ -27,6 +27,9 @@
<div class="game_infos conditions @if(ctx.isAuth) {
@if(verdicts.accepted){accepted}else{refused}
}" data-icon="7">
@if(verdicts.list.size < 2) {
<p>Condition of entry:</p>
}
@verdicts.list.map { v =>
<p class="condition text @if(v.verdict.accepted){accepted}else{refused}">@v.condition</p>
}

View file

@ -4,7 +4,7 @@ import lila.perfStat.PerfStat
import lila.rating.PerfType
import lila.user.User
sealed abstract class Condition(val key: String) {
sealed trait Condition {
def apply(stats: Condition.GetStats)(user: User): Fu[Condition.Verdict]
@ -26,7 +26,7 @@ object Condition {
case class WithVerdict(condition: Condition, verdict: Verdict)
case class NbRatedGame(perf: Option[PerfType], nb: Int) extends Condition("nb") {
case class NbRatedGame(perf: Option[PerfType], nb: Int) extends Condition {
def apply(stats: GetStats)(user: User) = fuccess {
perf match {
@ -43,7 +43,7 @@ object Condition {
}
}
case class MaxRating(perf: PerfType, rating: Int) extends Condition("rating") {
case class MaxRating(perf: PerfType, rating: Int) extends Condition {
def apply(stats: GetStats)(user: User) = stats(perf) map { s =>
s.highest match {
@ -109,13 +109,18 @@ object Condition {
private implicit val perfTypeWriter: OWrites[PerfType] = OWrites { pt =>
Json.obj("key" -> pt.key, "name" -> pt.name)
}
implicit val NbRatedGameJSONWriter = Json.writes[NbRatedGame]
implicit val MaxRatingJSONWriter = Json.writes[MaxRating]
private implicit val conditionWriter: OWrites[Condition] = OWrites {
case x: NbRatedGame => NbRatedGameJSONWriter writes x
case x: MaxRating => MaxRatingJSONWriter writes x
private implicit val ConditionWriter: Writes[Condition] = Writes { o =>
JsString(o.name)
}
private implicit val VerdictWriter: Writes[Verdict] = Writes {
case Refused(reason) => JsString(reason)
case Accepted => JsString("ok")
}
implicit val AllJSONWriter = Json.writes[All]
implicit val WithVerdictJSONWriter = Json.writes[WithVerdict]
implicit val AllWithVerdictsJSONWriter = Writes[All.WithVerdicts] { o =>
Json.obj("list" -> o.list, "accepted" -> o.accepted)
}
}
object DataForm {

View file

@ -54,6 +54,8 @@ final class Env(
createdTtl = CreatedCacheTtl,
rankingTtl = RankingCacheTtl)
lazy val verify = new Condition.Verify(getStats)
lazy val api = new TournamentApi(
cached = cached,
scheduleJsonView = scheduleJsonView,
@ -67,7 +69,7 @@ final class Env(
site = hub.socket.site,
lobby = hub.socket.lobby,
trophyApi = trophyApi,
verify = new Condition.Verify(getStats),
verify = verify,
indexLeaderboard = leaderboardIndexer.indexOne _,
roundMap = roundMap,
roundSocketHub = roundSocketHub)
@ -88,7 +90,7 @@ final class Env(
mongoCache = mongoCache,
ttl = LeaderboardCacheTtl)
lazy val jsonView = new JsonView(lightUser, cached, performance)
lazy val jsonView = new JsonView(lightUser, cached, performance, verify)
lazy val scheduleJsonView = new ScheduleJsonView(lightUser)

View file

@ -13,7 +13,8 @@ import lila.user.User
final class JsonView(
getLightUser: String => Option[LightUser],
cached: Cached,
performance: Performance) {
performance: Performance,
verify: Condition.Verify) {
import JsonView._
import Condition.JSONHandlers._
@ -26,11 +27,11 @@ final class JsonView(
def apply(
tour: Tournament,
page: Option[Int],
me: Option[String],
me: Option[User],
playerInfoExt: Option[PlayerInfoExt],
socketVersion: Option[Int]): Fu[JsObject] = for {
data <- cachableData(tour.id)
myInfo <- me ?? { PlayerRepo.playerInfo(tour.id, _) }
myInfo <- me ?? { u => PlayerRepo.playerInfo(tour.id, u.id) }
stand <- (myInfo, page) match {
case (_, Some(p)) => standing(tour, p)
case (Some(i), _) => standing(tour, i.page)
@ -39,6 +40,11 @@ final class JsonView(
playerInfoJson <- playerInfoExt ?? { pie =>
playerInfo(pie).map(_.some)
}
verdicts <- me match {
case None => fuccess(tour.conditions.accepted)
case Some(user) if myInfo.isDefined => fuccess(tour.conditions.accepted)
case Some(user) => verify(tour.conditions, user)
}
} yield Json.obj(
"id" -> tour.id,
"createdBy" -> tour.createdBy,
@ -57,7 +63,7 @@ final class JsonView(
"clock" -> clockJson(tour.clock),
"position" -> tour.position.some.filterNot(_.initial).map(positionJson),
"private" -> tour.`private`.option(true),
"conditions" -> tour.conditions.ifNonEmpty,
"verdicts" -> verdicts,
"variant" -> tour.variant.key,
"isStarted" -> tour.isStarted,
"isFinished" -> tour.isFinished,

View file

@ -14,15 +14,15 @@ object PlayerRepo {
private lazy val coll = Env.current.playerColl
private def selectId(id: String) = BSONDocument("_id" -> id)
private def selectTour(tourId: String) = BSONDocument("tid" -> tourId)
private def selectUser(userId: String) = BSONDocument("uid" -> userId)
private def selectTourUser(tourId: String, userId: String) = BSONDocument(
private def selectId(id: String) = $doc("_id" -> id)
private def selectTour(tourId: String) = $doc("tid" -> tourId)
private def selectUser(userId: String) = $doc("uid" -> userId)
private def selectTourUser(tourId: String, userId: String) = $doc(
"tid" -> tourId,
"uid" -> userId)
private val selectActive = BSONDocument("w" -> BSONDocument("$ne" -> true))
private val selectWithdraw = BSONDocument("w" -> true)
private val bestSort = BSONDocument("m" -> -1)
private val selectActive = $doc("w" $ne true)
private val selectWithdraw = $doc("w" -> true)
private val bestSort = $doc("m" -> -1)
def byId(id: String): Fu[Option[Player]] = coll.uno[Player](selectId(id))
@ -59,7 +59,7 @@ object PlayerRepo {
def unWithdraw(tourId: String) = coll.update(
selectTour(tourId) ++ selectWithdraw,
BSONDocument("$unset" -> BSONDocument("w" -> true)),
$doc("$unset" -> $doc("w" -> true)),
multi = true).void
def find(tourId: String, userId: String): Fu[Option[Player]] =
@ -72,8 +72,8 @@ object PlayerRepo {
def playerInfo(tourId: String, userId: String): Fu[Option[PlayerInfo]] = find(tourId, userId) flatMap {
_ ?? { player =>
coll.count(Some(selectTour(tourId) ++ BSONDocument(
"m" -> BSONDocument("$gt" -> player.magicScore))
coll.count(Some(selectTour(tourId) ++ $doc(
"m" -> $doc("$gt" -> player.magicScore))
)) map { n =>
PlayerInfo((n + 1), player.withdraw).some
}
@ -82,21 +82,21 @@ object PlayerRepo {
def join(tourId: String, user: User, perfLens: Perfs => Perf) =
find(tourId, user.id) flatMap {
case Some(p) if p.withdraw => coll.update(selectId(p._id), BSONDocument("$unset" -> BSONDocument("w" -> true)))
case Some(p) if p.withdraw => coll.update(selectId(p._id), $doc("$unset" -> $doc("w" -> true)))
case Some(p) => funit
case None => coll.insert(Player.make(tourId, user, perfLens))
} void
def withdraw(tourId: String, userId: String) = coll.update(
selectTourUser(tourId, userId),
BSONDocument("$set" -> BSONDocument("w" -> true))).void
$doc("$set" -> $doc("w" -> true))).void
def withPoints(tourId: String): Fu[List[Player]] =
coll.find(
selectTour(tourId) ++ BSONDocument("m" -> BSONDocument("$gt" -> 0))
selectTour(tourId) ++ $doc("m" -> $doc("$gt" -> 0))
).cursor[Player]().gather[List]()
private def aggregationUserIdList(res: Stream[BSONDocument]): List[String] =
private def aggregationUserIdList(res: Stream[Bdoc]): List[String] =
res.headOption flatMap { _.getAs[List[String]]("uids") } getOrElse Nil
import reactivemongo.api.collections.bson.BSONBatchCommands.AggregationFramework.{ Descending, Group, Match, Push, Sort }
@ -145,7 +145,7 @@ object PlayerRepo {
}
def setPerformance(player: Player, performance: Int) =
coll.update(selectId(player.id), BSONDocument("$set" -> BSONDocument("e" -> performance))).void
coll.update(selectId(player.id), $doc("$set" -> $doc("e" -> performance))).void
private def rankPlayers(players: List[Player], ranking: Ranking): RankedPlayers =
players.flatMap { p =>

View file

@ -74,6 +74,10 @@ module.exports = function(env) {
}.bind(this);
this.join = function() {
if (!this.data.verdicts.accepted)
return this.data.verdicts.list.forEach(function(v) {
if (v.verdict !== 'ok') alert(v.verdict);
});
xhr.join(this);
this.vm.joinSpinner = true;
this.vm.focusOnMe = true;