anonymous challenge join
This commit is contained in:
parent
f486211a2c
commit
01630eb87b
|
@ -3,7 +3,7 @@ package controllers
|
|||
import play.api.data.Form
|
||||
import play.api.i18n.Messages.Implicits._
|
||||
import play.api.libs.json._
|
||||
import play.api.mvc.{ Result, Results, Call, RequestHeader, Accepting }
|
||||
import play.api.mvc.Result
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import lila.api.{ Context, BodyContext }
|
||||
|
@ -53,10 +53,15 @@ object Challenge extends LilaController {
|
|||
|
||||
def accept(id: String) = Open { implicit ctx =>
|
||||
OptionFuResult(env.api byId id) { c =>
|
||||
if (isForMe(c)) env.api.accept(c, ctx.me) map { game =>
|
||||
Redirect(routes.Round.watcher(game.id, "white"))
|
||||
isForMe(c) ?? env.api.accept(c, ctx.me).flatMap {
|
||||
case Some(pov) => negotiate(
|
||||
html = Setup.redirectPov(pov).fuccess,
|
||||
api = apiVersion =>
|
||||
Env.api.roundApi.player(pov, apiVersion) map { Ok(_) })
|
||||
case None => negotiate(
|
||||
html = Redirect(routes.Round.watcher(c.id, "white")).fuccess,
|
||||
api = _ => notFoundJson("Someone else accepted the challenge"))
|
||||
}
|
||||
else notFound
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,9 +37,7 @@ object Setup extends LilaController with TheftPrevention {
|
|||
|
||||
def ai = process(env.forms.ai) { config =>
|
||||
implicit ctx =>
|
||||
env.processor ai config map { pov =>
|
||||
pov -> routes.Round.player(pov.fullId)
|
||||
}
|
||||
env.processor ai config
|
||||
}
|
||||
|
||||
def friendForm(userId: Option[String]) = Open { implicit ctx =>
|
||||
|
@ -196,7 +194,7 @@ object Setup extends LilaController with TheftPrevention {
|
|||
}
|
||||
}
|
||||
|
||||
private def process[A](form: Context => Form[A])(op: A => BodyContext[_] => Fu[(Pov, Call)]) =
|
||||
private def process[A](form: Context => Form[A])(op: A => BodyContext[_] => Fu[Pov]) =
|
||||
OpenBody { implicit ctx =>
|
||||
implicit val req = ctx.body
|
||||
form(ctx).bindFromRequest.fold(
|
||||
|
@ -204,9 +202,9 @@ object Setup extends LilaController with TheftPrevention {
|
|||
html = Lobby.renderHome(Results.BadRequest),
|
||||
api = _ => fuccess(BadRequest(errorsAsJson(f)))
|
||||
),
|
||||
config => op(config)(ctx) flatMap {
|
||||
case (pov, call) => negotiate(
|
||||
html = fuccess(redirectPov(pov, call)),
|
||||
config => op(config)(ctx) flatMap { pov =>
|
||||
negotiate(
|
||||
html = fuccess(redirectPov(pov)),
|
||||
api = apiVersion => Env.api.roundApi.player(pov, apiVersion) map { data =>
|
||||
Created(data) as JSON
|
||||
}
|
||||
|
@ -215,11 +213,14 @@ object Setup extends LilaController with TheftPrevention {
|
|||
)
|
||||
}
|
||||
|
||||
private def redirectPov(pov: Pov, call: Call)(implicit ctx: Context, req: RequestHeader) =
|
||||
if (ctx.isAuth) Redirect(call)
|
||||
else Redirect(call) withCookies LilaCookie.cookie(
|
||||
private[controllers] def redirectPov(pov: Pov)(implicit ctx: Context) = {
|
||||
implicit val req = ctx.req
|
||||
val redir = Redirect(routes.Round.player(pov.fullId))
|
||||
if (ctx.isAuth) redir
|
||||
else redir withCookies LilaCookie.cookie(
|
||||
AnonCookie.name,
|
||||
pov.playerId,
|
||||
maxAge = AnonCookie.maxAge.some,
|
||||
httpOnly = false.some)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import akka.actor._
|
|||
import org.joda.time.DateTime
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import lila.game.Game
|
||||
import lila.game.{ Game, Pov }
|
||||
import lila.hub.actorApi.map.Tell
|
||||
import lila.hub.actorApi.SendTo
|
||||
import lila.memo.{ MixedCache, AsyncCache }
|
||||
|
@ -46,9 +46,10 @@ final class ChallengeApi(
|
|||
|
||||
def decline(c: Challenge) = (repo decline c) >> uncacheAndNotify(c)
|
||||
|
||||
def accept(c: Challenge, user: Option[User]): Fu[Game] =
|
||||
joiner(c, user).flatMap { game =>
|
||||
(repo accept c) >> uncacheAndNotify(c) inject game
|
||||
def accept(c: Challenge, user: Option[User]): Fu[Option[Pov]] =
|
||||
joiner(c, user).flatMap {
|
||||
case None => fuccess(None)
|
||||
case Some(pov) => (repo accept c) >> uncacheAndNotify(c) inject pov.some
|
||||
}
|
||||
|
||||
private[challenge] def sweep: Funit =
|
||||
|
|
|
@ -6,58 +6,60 @@ import akka.pattern.ask
|
|||
import chess.format.Forsyth
|
||||
import chess.format.Forsyth.SituationPlus
|
||||
import chess.{ Situation, Mode }
|
||||
import lila.game.{ GameRepo, Game, Source, Player, AnonCookie, PerfPicker }
|
||||
import lila.game.{ GameRepo, Game, Pov, Source, Player, AnonCookie, PerfPicker }
|
||||
import lila.user.{ User, UserRepo }
|
||||
|
||||
private[challenge] final class Joiner(onStart: String => Unit) {
|
||||
|
||||
def apply(c: Challenge, destUser: Option[User]): Fu[Game] = GameRepo game c.id getOrElse {
|
||||
def apply(c: Challenge, destUser: Option[User]): Fu[Option[Pov]] =
|
||||
GameRepo exists c.id flatMap {
|
||||
case true => fuccess(None)
|
||||
case false =>
|
||||
c.challengerUserId.??(UserRepo.byId) flatMap { challengerUser =>
|
||||
|
||||
c.challengerUserId.??(UserRepo.byId) flatMap { challengerUser =>
|
||||
def makeChess(variant: chess.variant.Variant): chess.Game =
|
||||
chess.Game(board = chess.Board init variant, clock = c.clock.map(_.chessClock))
|
||||
|
||||
def makeChess(variant: chess.variant.Variant): chess.Game =
|
||||
chess.Game(board = chess.Board init variant, clock = c.clock.map(_.chessClock))
|
||||
|
||||
val baseState = c.initialFen.ifTrue(c.variant == chess.variant.FromPosition) flatMap Forsyth.<<<
|
||||
val (chessGame, state) = baseState.fold(makeChess(c.variant) -> none[SituationPlus]) {
|
||||
case sit@SituationPlus(Situation(board, color), _) =>
|
||||
val game = chess.Game(
|
||||
board = board,
|
||||
player = color,
|
||||
turns = sit.turns,
|
||||
startedAtTurn = sit.turns,
|
||||
clock = c.clock.map(_.chessClock))
|
||||
if (Forsyth.>>(game) == Forsyth.initial) makeChess(chess.variant.Standard) -> none
|
||||
else game -> baseState
|
||||
}
|
||||
val realVariant = chessGame.board.variant
|
||||
def makePlayer(color: chess.Color, userOption: Option[User]) = Player.make(color, None) |> { p =>
|
||||
userOption.fold(p) { user =>
|
||||
p.withUser(user.id, user.perfs(c.perfType))
|
||||
}
|
||||
}
|
||||
val game = Game.make(
|
||||
game = chessGame,
|
||||
whitePlayer = makePlayer(chess.White, c.chessColor.fold(challengerUser, destUser)),
|
||||
blackPlayer = makePlayer(chess.Black, c.chessColor.fold(destUser, challengerUser)),
|
||||
mode = (realVariant == chess.variant.FromPosition).fold(Mode.Casual, c.mode),
|
||||
variant = realVariant,
|
||||
source = (realVariant == chess.variant.FromPosition).fold(Source.Position, Source.Friend),
|
||||
daysPerTurn = c.daysPerTurn,
|
||||
pgnImport = None).copy(id = c.id).|> { g =>
|
||||
state.fold(g) {
|
||||
case sit@SituationPlus(Situation(board, _), _) => g.copy(
|
||||
variant = chess.variant.FromPosition,
|
||||
castleLastMoveTime = g.castleLastMoveTime.copy(
|
||||
lastMove = board.history.lastMove.map(_.origDest),
|
||||
castles = board.history.castles
|
||||
),
|
||||
turns = sit.turns)
|
||||
val baseState = c.initialFen.ifTrue(c.variant == chess.variant.FromPosition) flatMap Forsyth.<<<
|
||||
val (chessGame, state) = baseState.fold(makeChess(c.variant) -> none[SituationPlus]) {
|
||||
case sit@SituationPlus(Situation(board, color), _) =>
|
||||
val game = chess.Game(
|
||||
board = board,
|
||||
player = color,
|
||||
turns = sit.turns,
|
||||
startedAtTurn = sit.turns,
|
||||
clock = c.clock.map(_.chessClock))
|
||||
if (Forsyth.>>(game) == Forsyth.initial) makeChess(chess.variant.Standard) -> none
|
||||
else game -> baseState
|
||||
}
|
||||
}.start
|
||||
(GameRepo insertDenormalized game) >>- onStart(game.id) inject game
|
||||
val realVariant = chessGame.board.variant
|
||||
def makePlayer(color: chess.Color, userOption: Option[User]) = Player.make(color, None) |> { p =>
|
||||
userOption.fold(p) { user =>
|
||||
p.withUser(user.id, user.perfs(c.perfType))
|
||||
}
|
||||
}
|
||||
val game = Game.make(
|
||||
game = chessGame,
|
||||
whitePlayer = makePlayer(chess.White, c.chessColor.fold(challengerUser, destUser)),
|
||||
blackPlayer = makePlayer(chess.Black, c.chessColor.fold(destUser, challengerUser)),
|
||||
mode = (realVariant == chess.variant.FromPosition).fold(Mode.Casual, c.mode),
|
||||
variant = realVariant,
|
||||
source = (realVariant == chess.variant.FromPosition).fold(Source.Position, Source.Friend),
|
||||
daysPerTurn = c.daysPerTurn,
|
||||
pgnImport = None).copy(id = c.id).|> { g =>
|
||||
state.fold(g) {
|
||||
case sit@SituationPlus(Situation(board, _), _) => g.copy(
|
||||
variant = chess.variant.FromPosition,
|
||||
castleLastMoveTime = g.castleLastMoveTime.copy(
|
||||
lastMove = board.history.lastMove.map(_.origDest),
|
||||
castles = board.history.castles
|
||||
),
|
||||
turns = sit.turns)
|
||||
}
|
||||
}.start
|
||||
(GameRepo insertDenormalized game) >>- onStart(game.id) inject Pov(game, !c.chessColor).some
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// def apply(game: Game, user: Option[User]): Valid[Fu[(Pov, List[Event])]] =
|
||||
// game.notStarted option {
|
||||
|
|
|
@ -174,6 +174,8 @@ object GameRepo {
|
|||
def isAnalysed(id: ID): Fu[Boolean] =
|
||||
$count.exists($select(id) ++ Query.analysed(true))
|
||||
|
||||
def exists(id: ID) = $count.exists($select(id))
|
||||
|
||||
def filterAnalysed(ids: Seq[String]): Fu[Set[String]] =
|
||||
gameTube.coll.distinct("_id", BSONDocument(
|
||||
"_id" -> BSONDocument("$in" -> ids),
|
||||
|
|
Loading…
Reference in a new issue