2013-05-18 19:18:41 -06:00
|
|
|
package lila.lobby
|
2013-04-09 06:36:11 -06:00
|
|
|
|
2013-07-19 16:17:00 -06:00
|
|
|
import akka.actor.ActorRef
|
2014-02-17 02:12:19 -07:00
|
|
|
import chess.{ Game => ChessGame, Board, Variant, Mode, Clock, Color => ChessColor }
|
2013-12-26 16:31:09 -07:00
|
|
|
import org.joda.time.DateTime
|
2013-12-20 12:55:27 -07:00
|
|
|
|
2014-12-16 17:09:30 -07:00
|
|
|
import actorApi.{ RemoveHook, BiteHook, BiteSeek, JoinHook, JoinSeek, LobbyUser }
|
2014-07-26 08:06:32 -06:00
|
|
|
import lila.game.{ GameRepo, Game, Player, Pov, Progress, PerfPicker }
|
2013-05-24 11:04:49 -06:00
|
|
|
import lila.user.{ User, UserRepo }
|
2013-05-18 19:18:41 -06:00
|
|
|
|
2014-08-02 06:37:08 -06:00
|
|
|
private[lobby] object Biter {
|
2013-04-09 06:36:11 -06:00
|
|
|
|
2014-08-02 06:37:08 -06:00
|
|
|
def apply(hook: Hook, uid: String, user: Option[LobbyUser]): Fu[JoinHook] =
|
|
|
|
canJoin(hook, user).fold(
|
|
|
|
join(hook, uid, user),
|
|
|
|
fufail(s"$user cannot bite hook $hook")
|
|
|
|
)
|
2013-04-09 06:36:11 -06:00
|
|
|
|
2014-12-16 17:09:30 -07:00
|
|
|
def apply(seek: Seek, user: LobbyUser): Fu[JoinSeek] =
|
|
|
|
canJoin(seek, user).fold(
|
|
|
|
join(seek, user),
|
|
|
|
fufail(s"$user cannot join seek $seek")
|
|
|
|
)
|
|
|
|
|
2014-08-02 06:37:08 -06:00
|
|
|
private def join(hook: Hook, uid: String, lobbyUserOption: Option[LobbyUser]): Fu[JoinHook] = for {
|
|
|
|
userOption ← lobbyUserOption.map(_.id) ?? UserRepo.byId
|
2013-05-18 19:18:41 -06:00
|
|
|
ownerOption ← hook.userId ?? UserRepo.byId
|
2013-12-05 14:47:10 -07:00
|
|
|
creatorColor = hook.realColor.resolve
|
2013-04-09 06:36:11 -06:00
|
|
|
game = blame(
|
2013-12-05 14:47:10 -07:00
|
|
|
!creatorColor, userOption,
|
|
|
|
blame(creatorColor, ownerOption, makeGame(hook))
|
2013-04-09 06:36:11 -06:00
|
|
|
).start
|
2014-05-06 15:07:51 -06:00
|
|
|
_ ← GameRepo insertDenormalized game
|
2013-12-26 16:31:09 -07:00
|
|
|
} yield JoinHook(uid, hook, game, creatorColor)
|
2013-04-09 06:36:11 -06:00
|
|
|
|
2014-12-16 17:09:30 -07:00
|
|
|
private def join(seek: Seek, lobbyUser: LobbyUser): Fu[JoinSeek] = for {
|
|
|
|
user ← UserRepo byId lobbyUser.id flatten s"No such user: ${lobbyUser.id}"
|
|
|
|
owner ← UserRepo byId seek.user.id flatten s"No such user: ${seek.user.id}"
|
|
|
|
creatorColor = seek.realColor.resolve
|
|
|
|
game = blame(
|
|
|
|
!creatorColor, user.some,
|
|
|
|
blame(creatorColor, owner.some, makeGame(seek))
|
|
|
|
).start
|
|
|
|
_ ← GameRepo insertDenormalized game
|
2014-12-17 16:22:41 -07:00
|
|
|
} yield JoinSeek(user.id, seek, game, creatorColor)
|
2014-12-16 17:09:30 -07:00
|
|
|
|
2014-08-02 06:37:08 -06:00
|
|
|
private def blame(color: ChessColor, userOption: Option[User], game: Game) =
|
2014-07-26 08:06:32 -06:00
|
|
|
userOption.fold(game) { user =>
|
|
|
|
game.updatePlayer(color, _.withUser(user.id, PerfPicker.mainOrDefault(game)(user.perfs)))
|
|
|
|
}
|
2013-04-09 06:36:11 -06:00
|
|
|
|
|
|
|
private def makeGame(hook: Hook) = Game.make(
|
|
|
|
game = ChessGame(
|
|
|
|
board = Board init hook.realVariant,
|
2014-12-17 16:40:25 -07:00
|
|
|
clock = hook.clock.some),
|
2013-04-09 06:36:11 -06:00
|
|
|
whitePlayer = Player.white,
|
|
|
|
blackPlayer = Player.black,
|
|
|
|
mode = hook.realMode,
|
|
|
|
variant = hook.realVariant,
|
|
|
|
source = lila.game.Source.Lobby,
|
2014-12-16 17:09:30 -07:00
|
|
|
pgnImport = None)
|
|
|
|
|
|
|
|
private def makeGame(seek: Seek) = Game.make(
|
|
|
|
game = ChessGame(
|
|
|
|
board = Board init seek.realVariant,
|
|
|
|
clock = none),
|
|
|
|
whitePlayer = Player.white,
|
|
|
|
blackPlayer = Player.black,
|
|
|
|
mode = seek.realMode,
|
|
|
|
variant = seek.realVariant,
|
|
|
|
source = lila.game.Source.Lobby,
|
|
|
|
daysPerTurn = seek.daysPerTurn,
|
2013-04-09 06:36:11 -06:00
|
|
|
pgnImport = None)
|
|
|
|
|
2014-08-02 06:37:08 -06:00
|
|
|
def canJoin(hook: Hook, user: Option[LobbyUser]): Boolean = hook.open &&
|
2014-08-02 11:51:49 -06:00
|
|
|
hook.realMode.casual.fold(
|
|
|
|
user.isDefined || hook.allowAnon,
|
|
|
|
user ?? { _.engine == hook.engine }
|
|
|
|
) &&
|
|
|
|
!(hook.userId ?? (user ?? (_.blocking)).contains) &&
|
|
|
|
!((user map (_.id)) ?? (hook.user ?? (_.blocking)).contains) &&
|
|
|
|
hook.realRatingRange.fold(true) { range =>
|
|
|
|
user ?? { u =>
|
|
|
|
(hook.perfType map (_.key) flatMap u.ratingMap.get) ?? range.contains
|
|
|
|
}
|
2013-12-26 16:31:09 -07:00
|
|
|
}
|
2014-12-16 17:09:30 -07:00
|
|
|
|
|
|
|
def canJoin(seek: Seek, user: LobbyUser): Boolean =
|
|
|
|
(seek.realMode.casual || user.engine == seek.user.engine) &&
|
|
|
|
!(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
|
|
|
|
}
|
2013-04-09 06:36:11 -06:00
|
|
|
}
|