Implement lobby hook matching
This commit is contained in:
parent
2ad61ad857
commit
97b92844b3
|
@ -48,7 +48,7 @@ final class Preload(
|
||||||
entries ← entryRepo.recent
|
entries ← entryRepo.recent
|
||||||
} yield Right(Map(
|
} yield Right(Map(
|
||||||
"version" -> history.version,
|
"version" -> history.version,
|
||||||
"pool" -> renderHooks(hooks, myHook).pp,
|
"pool" -> renderHooks(hooks, myHook),
|
||||||
"chat" -> (messages.reverse map (_.render)),
|
"chat" -> (messages.reverse map (_.render)),
|
||||||
"timeline" -> (entries.reverse map (_.render))
|
"timeline" -> (entries.reverse map (_.render))
|
||||||
))
|
))
|
||||||
|
|
|
@ -18,6 +18,7 @@ object Lobby extends LilaController {
|
||||||
def preloader = env.preloader
|
def preloader = env.preloader
|
||||||
def hookRepo = env.lobby.hookRepo
|
def hookRepo = env.lobby.hookRepo
|
||||||
def fisherman = env.lobby.fisherman
|
def fisherman = env.lobby.fisherman
|
||||||
|
def joiner = env.setup.hookJoiner
|
||||||
|
|
||||||
val home = Open { implicit ctx ⇒
|
val home = Open { implicit ctx ⇒
|
||||||
renderHome(none).fold(identity, Ok(_))
|
renderHome(none).fold(identity, Ok(_))
|
||||||
|
@ -35,7 +36,7 @@ object Lobby extends LilaController {
|
||||||
myHook = myHook
|
myHook = myHook
|
||||||
).unsafePerformIO.bimap(
|
).unsafePerformIO.bimap(
|
||||||
url ⇒ Redirect(url),
|
url ⇒ Redirect(url),
|
||||||
preload ⇒ html.lobby.home(toJson(preload))
|
preload ⇒ html.lobby.home(toJson(preload), myHook)
|
||||||
)
|
)
|
||||||
|
|
||||||
def socket = WebSocket.async[JsValue] { implicit req ⇒
|
def socket = WebSocket.async[JsValue] { implicit req ⇒
|
||||||
|
@ -49,11 +50,22 @@ object Lobby extends LilaController {
|
||||||
}
|
}
|
||||||
|
|
||||||
def hook(ownerId: String) = Open { implicit ctx ⇒
|
def hook(ownerId: String) = Open { implicit ctx ⇒
|
||||||
hookRepo.ownedHook(ownerId.pp).unsafePerformIO.pp.fold(
|
hookRepo.ownedHook(ownerId).unsafePerformIO.fold(
|
||||||
hook ⇒ renderHome(hook.some).fold(identity, Ok(_)),
|
hook ⇒ renderHome(hook.some).fold(identity, Ok(_)),
|
||||||
Redirect(routes.Lobby.home))
|
Redirect(routes.Lobby.home))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def join(hookId: String) = Open { implicit ctx ⇒
|
||||||
|
IORedirect {
|
||||||
|
val myHookId = get("cancel")
|
||||||
|
joiner(hookId, myHookId)(ctx.me) map { result ⇒
|
||||||
|
result.fold(
|
||||||
|
_ ⇒ myHookId.fold(routes.Lobby.hook(_), routes.Lobby.home),
|
||||||
|
pov ⇒ routes.Round.player(pov.fullId))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def cancel(ownerId: String) = Open { implicit ctx ⇒
|
def cancel(ownerId: String) = Open { implicit ctx ⇒
|
||||||
IORedirect {
|
IORedirect {
|
||||||
for {
|
for {
|
||||||
|
@ -63,8 +75,6 @@ object Lobby extends LilaController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def join(hookId: String) = TODO
|
|
||||||
|
|
||||||
//def join(gameId: String, color: String) = Action { implicit req ⇒
|
//def join(gameId: String, color: String) = Action { implicit req ⇒
|
||||||
//FormValidIOk[LobbyJoinData](lobbyJoinForm)(join ⇒
|
//FormValidIOk[LobbyJoinData](lobbyJoinForm)(join ⇒
|
||||||
//api.join(gameId, color, join._1, join._2, join._3, join._4)
|
//api.join(gameId, color, join._1, join._2, join._3, join._4)
|
||||||
|
|
|
@ -20,7 +20,7 @@ object Round extends LilaController {
|
||||||
private val hand = env.round.hand
|
private val hand = env.round.hand
|
||||||
private val messenger = env.round.messenger
|
private val messenger = env.round.messenger
|
||||||
private val rematcher = env.setup.rematcher
|
private val rematcher = env.setup.rematcher
|
||||||
private val joiner = env.setup.joiner
|
private val joiner = env.setup.friendJoiner
|
||||||
|
|
||||||
def websocketWatcher(gameId: String, color: String) = WebSocket.async[JsValue] { req ⇒
|
def websocketWatcher(gameId: String, color: String) = WebSocket.async[JsValue] { req ⇒
|
||||||
implicit val ctx = reqToCtx(req)
|
implicit val ctx = reqToCtx(req)
|
||||||
|
|
|
@ -38,12 +38,13 @@ final class CoreEnv private (application: Application, val settings: Settings) {
|
||||||
settings = settings,
|
settings = settings,
|
||||||
mongodb = mongodb.apply _,
|
mongodb = mongodb.apply _,
|
||||||
gameRepo = game.gameRepo,
|
gameRepo = game.gameRepo,
|
||||||
|
hookRepo = lobby.hookRepo,
|
||||||
fisherman = lobby.fisherman,
|
fisherman = lobby.fisherman,
|
||||||
userRepo = user.userRepo,
|
userRepo = user.userRepo,
|
||||||
timelinePush = timeline.push.apply,
|
timelinePush = timeline.push.apply,
|
||||||
roundMessenger = round.messenger,
|
roundMessenger = round.messenger,
|
||||||
ai = ai.ai,
|
ai = ai.ai,
|
||||||
dbRef = user.userRepo.dbRef)
|
userDbRef = user.userRepo.dbRef)
|
||||||
|
|
||||||
lazy val timeline = new lila.timeline.TimelineEnv(
|
lazy val timeline = new lila.timeline.TimelineEnv(
|
||||||
settings = settings,
|
settings = settings,
|
||||||
|
|
|
@ -28,9 +28,9 @@ object Cron {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
message(1 seconds) {
|
//message(1 seconds) {
|
||||||
env.monitor.reporting -> monitor.Update(env)
|
//env.monitor.reporting -> monitor.Update(env)
|
||||||
}
|
//}
|
||||||
|
|
||||||
message(1 second) {
|
message(1 second) {
|
||||||
env.lobby.hub -> lobby.WithHooks(env.lobby.hookMemo.putAll)
|
env.lobby.hub -> lobby.WithHooks(env.lobby.hookMemo.putAll)
|
||||||
|
@ -52,28 +52,28 @@ object Cron {
|
||||||
env.lobby.hookRepo.cleanupOld
|
env.lobby.hookRepo.cleanupOld
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe(3 seconds) {
|
//unsafe(3 seconds) {
|
||||||
Future.traverse(hubs) { hub ⇒
|
//Future.traverse(hubs) { hub ⇒
|
||||||
hub ? socket.GetUsernames mapTo manifest[Iterable[String]]
|
//hub ? socket.GetUsernames mapTo manifest[Iterable[String]]
|
||||||
} map (_.flatten) onSuccess {
|
//} map (_.flatten) onSuccess {
|
||||||
case xs ⇒ (env.user.usernameMemo putAll xs).unsafePerformIO
|
//case xs ⇒ (env.user.usernameMemo putAll xs).unsafePerformIO
|
||||||
}
|
//}
|
||||||
}
|
//}
|
||||||
|
|
||||||
effect(4.1 hours) {
|
//effect(4.1 hours) {
|
||||||
env.game.gameRepo.cleanupUnplayed flatMap { _ ⇒
|
//env.game.gameRepo.cleanupUnplayed flatMap { _ ⇒
|
||||||
env.gameCleanNextCommand.apply
|
//env.gameCleanNextCommand.apply
|
||||||
}
|
//}
|
||||||
}
|
//}
|
||||||
|
|
||||||
effect(1 hour) {
|
//effect(1 hour) {
|
||||||
env.gameFinishCommand.apply
|
//env.gameFinishCommand.apply
|
||||||
}
|
//}
|
||||||
|
|
||||||
effect(1 minute) {
|
//effect(1 minute) {
|
||||||
env.ai.remoteAi.diagnose
|
//env.ai.remoteAi.diagnose
|
||||||
}
|
//}
|
||||||
env.ai.remoteAi.diagnose.unsafePerformIO
|
//env.ai.remoteAi.diagnose.unsafePerformIO
|
||||||
|
|
||||||
lazy val hubs: List[ActorRef] =
|
lazy val hubs: List[ActorRef] =
|
||||||
List(env.site.hub, env.lobby.hub, env.round.hubMaster)
|
List(env.site.hub, env.lobby.hub, env.round.hubMaster)
|
||||||
|
|
|
@ -15,11 +15,12 @@ object Global extends GlobalSettings {
|
||||||
|
|
||||||
coreEnv = CoreEnv(app)
|
coreEnv = CoreEnv(app)
|
||||||
|
|
||||||
//if (env.ai.isServer) println("Running as AI server")
|
if (env.ai.isServer) println("Running as AI server")
|
||||||
//else core.Cron start env
|
else core.Cron start env
|
||||||
}
|
}
|
||||||
|
|
||||||
override def onRouteRequest(req: RequestHeader): Option[Handler] = {
|
override def onRouteRequest(req: RequestHeader): Option[Handler] = {
|
||||||
|
println(req)
|
||||||
env.monitor.rpsProvider.countRequest()
|
env.monitor.rpsProvider.countRequest()
|
||||||
env.i18n.requestHandler(req) orElse super.onRouteRequest(req)
|
env.i18n.requestHandler(req) orElse super.onRouteRequest(req)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ package elo
|
||||||
|
|
||||||
case class EloRange(min: Int, max: Int) {
|
case class EloRange(min: Int, max: Int) {
|
||||||
|
|
||||||
|
def contains(elo: Int) = elo >= min && elo <= max
|
||||||
|
|
||||||
override def toString = "%d-%d".format(min, max)
|
override def toString = "%d-%d".format(min, max)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +13,8 @@ object EloRange {
|
||||||
val min = 800
|
val min = 800
|
||||||
val max = 2200
|
val max = 2200
|
||||||
|
|
||||||
val default = EloRange(min, max)
|
val broad = EloRange(min, max)
|
||||||
|
val default = broad
|
||||||
|
|
||||||
// ^\d{3,4}\-\d{3,4}$
|
// ^\d{3,4}\-\d{3,4}$
|
||||||
def apply(from: String): Option[EloRange] = for {
|
def apply(from: String): Option[EloRange] = for {
|
||||||
|
@ -28,5 +31,5 @@ object EloRange {
|
||||||
|
|
||||||
def valid(from: String) = apply(from).isDefined
|
def valid(from: String) = apply(from).isDefined
|
||||||
|
|
||||||
private def acceptable(v: Int) = v >= min && v <= max
|
private def acceptable(elo: Int) = broad contains elo
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ final class I18nRequestHandler(pool: I18nPool) {
|
||||||
else pool.domainLang(req).isDefined.fold(
|
else pool.domainLang(req).isDefined.fold(
|
||||||
None,
|
None,
|
||||||
Action {
|
Action {
|
||||||
Redirect(redirectUrl(req).pp)
|
Redirect(redirectUrl(req))
|
||||||
} some
|
} some
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ final class Fisherman(
|
||||||
def bite(hook: Hook, game: DbGame): IO[Unit] = for {
|
def bite(hook: Hook, game: DbGame): IO[Unit] = for {
|
||||||
_ ← socket removeHook hook
|
_ ← socket removeHook hook
|
||||||
_ ← socket.biteHook(hook, game)
|
_ ← socket.biteHook(hook, game)
|
||||||
|
_ ← hookRepo.setGame(hook, game)
|
||||||
} yield ()
|
} yield ()
|
||||||
|
|
||||||
// mark the hook as active, once
|
// mark the hook as active, once
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
package lila
|
package lila
|
||||||
package lobby
|
package lobby
|
||||||
|
|
||||||
import chess.{ Variant, Mode, Color, Clock }
|
import chess.{ Variant, Mode, Clock }
|
||||||
|
import setup.Color
|
||||||
import elo.EloRange
|
import elo.EloRange
|
||||||
import user.User
|
import user.User
|
||||||
|
|
||||||
|
@ -18,6 +19,7 @@ case class Hook(
|
||||||
increment: Option[Int],
|
increment: Option[Int],
|
||||||
mode: Int,
|
mode: Int,
|
||||||
color: String,
|
color: String,
|
||||||
|
userId: Option[String],
|
||||||
username: String,
|
username: String,
|
||||||
elo: Option[Int],
|
elo: Option[Int],
|
||||||
eloRange: String,
|
eloRange: String,
|
||||||
|
@ -25,6 +27,8 @@ case class Hook(
|
||||||
`match`: Boolean = false,
|
`match`: Boolean = false,
|
||||||
game: Option[DBRef] = None) {
|
game: Option[DBRef] = None) {
|
||||||
|
|
||||||
|
def realColor = Color orDefault color
|
||||||
|
|
||||||
def gameId: Option[String] = game map (_.getId.toString)
|
def gameId: Option[String] = game map (_.getId.toString)
|
||||||
|
|
||||||
def realVariant = Variant orDefault variant
|
def realVariant = Variant orDefault variant
|
||||||
|
@ -71,6 +75,7 @@ object Hook {
|
||||||
increment = clock map (_.increment),
|
increment = clock map (_.increment),
|
||||||
mode = mode.id,
|
mode = mode.id,
|
||||||
color = color,
|
color = color,
|
||||||
|
userId = user map (_.idString),
|
||||||
username = user.fold(_.username, User.anonymous),
|
username = user.fold(_.username, User.anonymous),
|
||||||
elo = user map (_.elo),
|
elo = user map (_.elo),
|
||||||
eloRange = eloRange.toString,
|
eloRange = eloRange.toString,
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package lila
|
package lila
|
||||||
package lobby
|
package lobby
|
||||||
|
|
||||||
|
import game.DbGame
|
||||||
|
|
||||||
import com.novus.salat._
|
import com.novus.salat._
|
||||||
import com.novus.salat.dao._
|
import com.novus.salat.dao._
|
||||||
import com.mongodb.casbah.MongoCollection
|
import com.mongodb.casbah.MongoCollection
|
||||||
|
@ -33,8 +35,12 @@ class HookRepo(collection: MongoCollection)
|
||||||
find(query) sort DBObject("createdAt" -> 1) toList
|
find(query) sort DBObject("createdAt" -> 1) toList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def setGame(hook: Hook, game: DbGame) = io {
|
||||||
|
update(idSelector(hook), $set("match" -> true) ++ $set("gameId" -> game.id))
|
||||||
|
}
|
||||||
|
|
||||||
def removeId(id: String): IO[Unit] = io {
|
def removeId(id: String): IO[Unit] = io {
|
||||||
remove(DBObject("_id" -> id))
|
remove(idSelector(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
def removeOwnerId(ownerId: String): IO[Unit] = io {
|
def removeOwnerId(ownerId: String): IO[Unit] = io {
|
||||||
|
@ -50,4 +56,7 @@ class HookRepo(collection: MongoCollection)
|
||||||
def cleanupOld: IO[Unit] = io {
|
def cleanupOld: IO[Unit] = io {
|
||||||
remove("createdAt" $lt (DateTime.now - 1.hour))
|
remove("createdAt" $lt (DateTime.now - 1.hour))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private def idSelector(id: String): DBObject = DBObject("_id" -> id)
|
||||||
|
private def idSelector(hook: Hook): DBObject = idSelector(hook.id)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,18 @@
|
||||||
package lila
|
package lila
|
||||||
package lobby
|
package lobby
|
||||||
|
|
||||||
import com.mongodb.casbah.MongoCollection
|
|
||||||
|
|
||||||
import akka.actor._
|
import akka.actor._
|
||||||
|
|
||||||
import play.api.libs.concurrent._
|
import play.api.libs.concurrent._
|
||||||
import play.api.Application
|
import play.api.Application
|
||||||
import play.api.i18n.Lang
|
import play.api.i18n.Lang
|
||||||
import play.api.i18n.MessagesPlugin
|
import play.api.i18n.MessagesPlugin
|
||||||
|
import scalaz.effects._
|
||||||
|
import com.mongodb.casbah.MongoCollection
|
||||||
|
import com.mongodb.DBRef
|
||||||
|
|
||||||
import user.UserRepo
|
import user.{ User, UserRepo }
|
||||||
import game.GameRepo
|
import game.{ GameRepo, DbGame }
|
||||||
import round.{ Socket ⇒ RoundSocket, Messenger ⇒ RoundMessenger }
|
import round.{ Socket ⇒ RoundSocket, Messenger ⇒ RoundMessenger }
|
||||||
import ai.Ai
|
|
||||||
import core.Settings
|
import core.Settings
|
||||||
|
|
||||||
final class LobbyEnv(
|
final class LobbyEnv(
|
||||||
|
@ -50,14 +49,6 @@ final class LobbyEnv(
|
||||||
collection = mongodb(MongoCollectionMessage),
|
collection = mongodb(MongoCollectionMessage),
|
||||||
max = LobbyMessageMax)
|
max = LobbyMessageMax)
|
||||||
|
|
||||||
//lazy val api = new Api(
|
|
||||||
//hookRepo = hookRepo,
|
|
||||||
//fisherman = fisherman,
|
|
||||||
//gameRepo = gameRepo,
|
|
||||||
//roundSocket = roundSocket,
|
|
||||||
//roundMessenger = roundMessenger,
|
|
||||||
//starter = starter)
|
|
||||||
|
|
||||||
lazy val hookRepo = new HookRepo(mongodb(MongoCollectionHook))
|
lazy val hookRepo = new HookRepo(mongodb(MongoCollectionHook))
|
||||||
|
|
||||||
lazy val hookMemo = new HookMemo(timeout = MemoHookTimeout)
|
lazy val hookMemo = new HookMemo(timeout = MemoHookTimeout)
|
||||||
|
|
|
@ -27,11 +27,13 @@ object Color {
|
||||||
|
|
||||||
def apply(name: String): Option[Color] = all find (_.name == name)
|
def apply(name: String): Option[Color] = all find (_.name == name)
|
||||||
|
|
||||||
|
def orDefault(name: String) = apply(name) | default
|
||||||
|
|
||||||
val all = List(White, Black, Random)
|
val all = List(White, Black, Random)
|
||||||
|
|
||||||
val names = all map (_.name)
|
val names = all map (_.name)
|
||||||
|
|
||||||
val choices = names zip names
|
val choices = names zip names
|
||||||
|
|
||||||
val default = White
|
val default = Random
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package lila
|
package lila
|
||||||
package setup
|
package setup
|
||||||
|
|
||||||
import chess.{ Game, Board, Variant, Mode, Color ⇒ ChessColor }
|
import chess.{ Game, Board, Variant, Mode, PausedClock, Color ⇒ ChessColor }
|
||||||
import elo.EloRange
|
import elo.EloRange
|
||||||
import game.{ DbGame, DbPlayer }
|
import game.{ DbGame, DbPlayer }
|
||||||
|
|
||||||
|
@ -16,7 +16,13 @@ case class FriendConfig(
|
||||||
def >> = (variant.id, clock, time, increment, mode.id, color.name).some
|
def >> = (variant.id, clock, time, increment, mode.id, color.name).some
|
||||||
|
|
||||||
def game = DbGame(
|
def game = DbGame(
|
||||||
game = Game(board = Board(pieces = variant.pieces)),
|
game = Game(
|
||||||
|
board = Board(pieces = variant.pieces),
|
||||||
|
clock = clock option PausedClock(
|
||||||
|
limit = time,
|
||||||
|
increment = increment
|
||||||
|
)
|
||||||
|
),
|
||||||
ai = None,
|
ai = None,
|
||||||
whitePlayer = DbPlayer.white,
|
whitePlayer = DbPlayer.white,
|
||||||
blackPlayer = DbPlayer.black,
|
blackPlayer = DbPlayer.black,
|
||||||
|
|
|
@ -10,19 +10,19 @@ import controllers.routes
|
||||||
import com.mongodb.DBRef
|
import com.mongodb.DBRef
|
||||||
import scalaz.effects._
|
import scalaz.effects._
|
||||||
|
|
||||||
final class Joiner(
|
final class FriendJoiner(
|
||||||
gameRepo: GameRepo,
|
gameRepo: GameRepo,
|
||||||
messenger: Messenger,
|
messenger: Messenger,
|
||||||
timelinePush: DbGame ⇒ IO[Unit],
|
timelinePush: DbGame ⇒ IO[Unit],
|
||||||
dbRef: User ⇒ DBRef) {
|
userDbRef: User ⇒ DBRef) {
|
||||||
|
|
||||||
def apply(game: DbGame, user: Option[User]): Valid[IO[(Pov, List[Event])]] =
|
def apply(game: DbGame, user: Option[User]): Valid[IO[(Pov, List[Event])]] =
|
||||||
game.notStarted option {
|
game.notStarted option {
|
||||||
val color = game.invitedColor
|
val color = game.invitedColor
|
||||||
for {
|
for {
|
||||||
p1 ← user.fold(
|
p1 ← user.fold(
|
||||||
u ⇒ gameRepo.setUser(game.id, color, dbRef(u), u.elo) map { _ ⇒
|
u ⇒ gameRepo.setUser(game.id, color, userDbRef(u), u.elo) map { _ ⇒
|
||||||
Progress(game, game.updatePlayer(color, _.withUser(u, dbRef(u))))
|
Progress(game, game.updatePlayer(color, _.withUser(u, userDbRef(u))))
|
||||||
},
|
},
|
||||||
io(Progress(game)))
|
io(Progress(game)))
|
||||||
p2 = p1 withGame game.start
|
p2 = p1 withGame game.start
|
78
app/setup/HookJoiner.scala
Normal file
78
app/setup/HookJoiner.scala
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
package lila
|
||||||
|
package setup
|
||||||
|
|
||||||
|
import lobby.{ HookRepo, Hook, Fisherman }
|
||||||
|
import user.{ User, UserRepo }
|
||||||
|
import chess.{ Game, Board, Variant, Mode, PausedClock, Color ⇒ ChessColor }
|
||||||
|
import game.{ GameRepo, DbGame, DbPlayer, Pov }
|
||||||
|
import round.{ Messenger, Progress }
|
||||||
|
|
||||||
|
import scalaz.effects._
|
||||||
|
import com.mongodb.DBRef
|
||||||
|
|
||||||
|
final class HookJoiner(
|
||||||
|
hookRepo: HookRepo,
|
||||||
|
fisherman: Fisherman,
|
||||||
|
gameRepo: GameRepo,
|
||||||
|
userRepo: UserRepo,
|
||||||
|
userDbRef: User ⇒ DBRef,
|
||||||
|
timelinePush: DbGame ⇒ IO[Unit],
|
||||||
|
messenger: Messenger) {
|
||||||
|
|
||||||
|
def apply(hookId: String, myHookId: Option[String])(me: Option[User]): IO[Valid[Pov]] =
|
||||||
|
for {
|
||||||
|
hookOption ← hookRepo hook hookId
|
||||||
|
myHookOption ← myHookId.fold(hookRepo.ownedHook, io(none))
|
||||||
|
result ← hookOption.fold(
|
||||||
|
hook ⇒ canJoin(hook, me).fold(
|
||||||
|
join(hook, myHookOption)(me) map success,
|
||||||
|
io(!!("Can not join hook"))
|
||||||
|
),
|
||||||
|
io(!!("No such hook"))
|
||||||
|
)
|
||||||
|
|
||||||
|
} yield result
|
||||||
|
|
||||||
|
private def join(hook: Hook, myHook: Option[Hook])(me: Option[User]): IO[Pov] = for {
|
||||||
|
_ ← myHook.fold(fisherman.delete, io())
|
||||||
|
ownerOption ← hook.userId.fold(userRepo.user, io(none))
|
||||||
|
game = blame(
|
||||||
|
_.invitedColor, me,
|
||||||
|
blame(_.creatorColor, ownerOption, makeGame(hook))
|
||||||
|
).start
|
||||||
|
_ ← gameRepo insert game
|
||||||
|
_ ← game.variant.standard.fold(io(), gameRepo saveInitialFen game)
|
||||||
|
_ ← timelinePush(game)
|
||||||
|
// messenges are not sent to the game socket
|
||||||
|
// as nobody is there to see them yet
|
||||||
|
_ ← messenger init game
|
||||||
|
_ ← fisherman.bite(hook, game)
|
||||||
|
} yield Pov(game, game.invitedColor)
|
||||||
|
|
||||||
|
def blame(color: DbGame ⇒ ChessColor, userOption: Option[User], game: DbGame) =
|
||||||
|
userOption.fold(
|
||||||
|
user ⇒ game.updatePlayer(color(game), _.withUser(user, userDbRef(user))),
|
||||||
|
game)
|
||||||
|
|
||||||
|
def makeGame(hook: Hook) = DbGame(
|
||||||
|
game = Game(
|
||||||
|
board = Board(pieces = hook.realVariant.pieces),
|
||||||
|
clock = hook.hasClock.fold(
|
||||||
|
hook.time |@| hook.increment apply { (limit, inc) ⇒
|
||||||
|
PausedClock(limit = limit, increment = inc)
|
||||||
|
},
|
||||||
|
none)
|
||||||
|
),
|
||||||
|
ai = None,
|
||||||
|
whitePlayer = DbPlayer.white,
|
||||||
|
blackPlayer = DbPlayer.black,
|
||||||
|
creatorColor = hook.realColor.resolve,
|
||||||
|
mode = hook.realMode,
|
||||||
|
variant = hook.realVariant)
|
||||||
|
|
||||||
|
private def canJoin(hook: Hook, me: Option[User]) =
|
||||||
|
hook.realMode.fold(
|
||||||
|
true,
|
||||||
|
me exists { u ⇒ hook.realEloRange.fold(_ contains u.elo, true) }
|
||||||
|
)
|
||||||
|
}
|
|
@ -18,7 +18,7 @@ final class Processor(
|
||||||
fisherman: Fisherman,
|
fisherman: Fisherman,
|
||||||
timelinePush: DbGame ⇒ IO[Unit],
|
timelinePush: DbGame ⇒ IO[Unit],
|
||||||
ai: () ⇒ Ai,
|
ai: () ⇒ Ai,
|
||||||
dbRef: User ⇒ DBRef) {
|
userDbRef: User ⇒ DBRef) {
|
||||||
|
|
||||||
def ai(config: AiConfig)(implicit ctx: Context): IO[Pov] = for {
|
def ai(config: AiConfig)(implicit ctx: Context): IO[Pov] = for {
|
||||||
_ ← ctx.me.fold(
|
_ ← ctx.me.fold(
|
||||||
|
@ -27,7 +27,7 @@ final class Processor(
|
||||||
)
|
)
|
||||||
pov = config.pov
|
pov = config.pov
|
||||||
game = ctx.me.fold(
|
game = ctx.me.fold(
|
||||||
user ⇒ pov.game.updatePlayer(pov.color, _.withUser(user, dbRef(user))),
|
user ⇒ pov.game.updatePlayer(pov.color, _.withUser(user, userDbRef(user))),
|
||||||
pov.game)
|
pov.game)
|
||||||
_ ← gameRepo insert game
|
_ ← gameRepo insert game
|
||||||
_ ← game.variant.standard.fold(io(), gameRepo saveInitialFen game)
|
_ ← game.variant.standard.fold(io(), gameRepo saveInitialFen game)
|
||||||
|
@ -50,7 +50,7 @@ final class Processor(
|
||||||
)
|
)
|
||||||
pov = config.pov
|
pov = config.pov
|
||||||
game = ctx.me.fold(
|
game = ctx.me.fold(
|
||||||
user ⇒ pov.game.updatePlayer(pov.color, _.withUser(user, dbRef(user))),
|
user ⇒ pov.game.updatePlayer(pov.color, _.withUser(user, userDbRef(user))),
|
||||||
pov.game)
|
pov.game)
|
||||||
_ ← gameRepo insert game
|
_ ← gameRepo insert game
|
||||||
_ ← game.variant.standard.fold(io(), gameRepo saveInitialFen game)
|
_ ← game.variant.standard.fold(io(), gameRepo saveInitialFen game)
|
||||||
|
|
|
@ -3,7 +3,7 @@ package setup
|
||||||
|
|
||||||
import core.Settings
|
import core.Settings
|
||||||
import game.{ DbGame, GameRepo }
|
import game.{ DbGame, GameRepo }
|
||||||
import lobby.Fisherman
|
import lobby.{ HookRepo, Fisherman }
|
||||||
import round.Messenger
|
import round.Messenger
|
||||||
import ai.Ai
|
import ai.Ai
|
||||||
import user.{ User, UserRepo }
|
import user.{ User, UserRepo }
|
||||||
|
@ -16,12 +16,13 @@ final class SetupEnv(
|
||||||
settings: Settings,
|
settings: Settings,
|
||||||
mongodb: String ⇒ MongoCollection,
|
mongodb: String ⇒ MongoCollection,
|
||||||
gameRepo: GameRepo,
|
gameRepo: GameRepo,
|
||||||
|
hookRepo: HookRepo,
|
||||||
fisherman: Fisherman,
|
fisherman: Fisherman,
|
||||||
userRepo: UserRepo,
|
userRepo: UserRepo,
|
||||||
timelinePush: DbGame ⇒ IO[Unit],
|
timelinePush: DbGame ⇒ IO[Unit],
|
||||||
roundMessenger: Messenger,
|
roundMessenger: Messenger,
|
||||||
ai: () ⇒ Ai,
|
ai: () ⇒ Ai,
|
||||||
dbRef: User ⇒ DBRef) {
|
userDbRef: User ⇒ DBRef) {
|
||||||
|
|
||||||
import settings._
|
import settings._
|
||||||
|
|
||||||
|
@ -37,7 +38,7 @@ final class SetupEnv(
|
||||||
fisherman = fisherman,
|
fisherman = fisherman,
|
||||||
timelinePush = timelinePush,
|
timelinePush = timelinePush,
|
||||||
ai = ai,
|
ai = ai,
|
||||||
dbRef = dbRef)
|
userDbRef = userDbRef)
|
||||||
|
|
||||||
lazy val friendConfigMemo = new FriendConfigMemo(
|
lazy val friendConfigMemo = new FriendConfigMemo(
|
||||||
ttl = SetupFriendConfigMemoTtl)
|
ttl = SetupFriendConfigMemoTtl)
|
||||||
|
@ -48,9 +49,18 @@ final class SetupEnv(
|
||||||
messenger = roundMessenger,
|
messenger = roundMessenger,
|
||||||
timelinePush = timelinePush)
|
timelinePush = timelinePush)
|
||||||
|
|
||||||
lazy val joiner = new Joiner(
|
lazy val friendJoiner = new FriendJoiner(
|
||||||
gameRepo = gameRepo,
|
gameRepo = gameRepo,
|
||||||
messenger = roundMessenger,
|
messenger = roundMessenger,
|
||||||
timelinePush = timelinePush,
|
timelinePush = timelinePush,
|
||||||
dbRef = dbRef)
|
userDbRef = userDbRef)
|
||||||
|
|
||||||
|
lazy val hookJoiner = new HookJoiner(
|
||||||
|
hookRepo = hookRepo,
|
||||||
|
fisherman = fisherman,
|
||||||
|
gameRepo = gameRepo,
|
||||||
|
userRepo = userRepo,
|
||||||
|
userDbRef = userDbRef,
|
||||||
|
timelinePush = timelinePush,
|
||||||
|
messenger = roundMessenger)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@(preload: String, hookId: Option[String] = None)(implicit ctx: Context)
|
@(preload: String, myHook: Option[lila.lobby.Hook])(implicit ctx: Context)
|
||||||
|
|
||||||
@chat = {
|
@chat = {
|
||||||
@ctx.me.map { m =>
|
@ctx.me.map { m =>
|
||||||
|
@ -25,9 +25,9 @@
|
||||||
@widget.connection()
|
@widget.connection()
|
||||||
<div class="hooks_wrap">
|
<div class="hooks_wrap">
|
||||||
<div class="hooks"
|
<div class="hooks"
|
||||||
data-my-hook="@hookId"
|
data-my-hook="@myHook.map(_.ownerId)"
|
||||||
data-cancel-url="@routes.Lobby.cancel("000000000000")"
|
data-cancel-url="@routes.Lobby.cancel("000000000000")"
|
||||||
data-join-url="@routes.Lobby.join("000000000000")"
|
data-join-url="@routes.Lobby.join("00000000")"
|
||||||
>
|
>
|
||||||
<table></table>
|
<table></table>
|
||||||
<textarea class="hooks_preload" style="display: none">@Html(preload)</textarea>
|
<textarea class="hooks_preload" style="display: none">@Html(preload)</textarea>
|
||||||
|
|
Loading…
Reference in a new issue