lila/modules/lobby/src/main/Biter.scala

96 lines
3.4 KiB
Scala
Raw Normal View History

package lila.lobby
2013-04-09 06:36:11 -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 }
private[lobby] object Biter {
2013-04-09 06:36:11 -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")
)
private def join(hook: Hook, uid: String, lobbyUserOption: Option[LobbyUser]): Fu[JoinHook] = for {
userOption lobbyUserOption.map(_.id) ?? UserRepo.byId
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
_ 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
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)
def canJoin(hook: Hook, user: Option[LobbyUser]): Boolean = hook.open &&
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
}