no longer save rematch IDs in DB
parent
2782cfdecc
commit
7e350c56ce
|
@ -2,14 +2,17 @@ package lila.bot
|
|||
|
||||
import akka.actor._
|
||||
|
||||
import lila.game.Game
|
||||
|
||||
final class Env(
|
||||
system: ActorSystem,
|
||||
hub: lila.hub.Env,
|
||||
onlineUserIds: lila.memo.ExpireSetMemo,
|
||||
lightUserApi: lila.user.LightUserApi
|
||||
lightUserApi: lila.user.LightUserApi,
|
||||
rematchOf: Game.ID => Option[Game.ID]
|
||||
) {
|
||||
|
||||
lazy val jsonView = new BotJsonView(lightUserApi)
|
||||
lazy val jsonView = new BotJsonView(lightUserApi, rematchOf)
|
||||
|
||||
lazy val gameStateStream = new GameStateStream(system, jsonView)
|
||||
|
||||
|
@ -24,6 +27,7 @@ object Env {
|
|||
system = lila.common.PlayApp.system,
|
||||
hub = lila.hub.Env.current,
|
||||
onlineUserIds = lila.user.Env.current.onlineUserIdMemo,
|
||||
lightUserApi = lila.user.Env.current.lightUserApi
|
||||
lightUserApi = lila.user.Env.current.lightUserApi,
|
||||
rematchOf = lila.game.Env.current.rematches.getIfPresent
|
||||
)
|
||||
}
|
||||
|
|
|
@ -8,7 +8,8 @@ import lila.game.JsonView._
|
|||
import lila.game.{ Game, Pov, GameRepo }
|
||||
|
||||
final class BotJsonView(
|
||||
lightUserApi: lila.user.LightUserApi
|
||||
lightUserApi: lila.user.LightUserApi,
|
||||
rematchOf: Game.ID => Option[Game.ID]
|
||||
) {
|
||||
|
||||
def gameFull(game: Game): Fu[JsObject] = GameRepo.withInitialFen(game) flatMap gameFull
|
||||
|
@ -53,7 +54,7 @@ final class BotJsonView(
|
|||
"bdraw" -> game.blackPlayer.isOfferingDraw,
|
||||
"wdraw" -> game.whitePlayer.isOfferingDraw
|
||||
)
|
||||
.add("rematch" -> game.next)
|
||||
.add("rematch" -> rematchOf(game.id))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package lila.game
|
||||
|
||||
import akka.actor._
|
||||
import com.github.blemale.scaffeine.{ Cache, Scaffeine }
|
||||
import com.typesafe.config.Config
|
||||
import scala.concurrent.duration._
|
||||
|
||||
final class Env(
|
||||
config: Config,
|
||||
|
@ -78,6 +80,14 @@ final class Env(
|
|||
lazy val gamesByUsersStream = new GamesByUsersStream(system)
|
||||
|
||||
lazy val bestOpponents = new BestOpponents
|
||||
|
||||
lazy val rematches: Cache[Game.ID, Game.ID] = Scaffeine()
|
||||
.expireAfterWrite(3 hour)
|
||||
.build[Game.ID, Game.ID]
|
||||
|
||||
lazy val jsonView = new JsonView(
|
||||
rematchOf = rematches.getIfPresent
|
||||
)
|
||||
}
|
||||
|
||||
object Env {
|
||||
|
|
|
@ -303,13 +303,12 @@ object GameRepo {
|
|||
def setImportCreatedAt(g: Game) =
|
||||
coll.update($id(g.id), $set("pgni.ca" -> g.createdAt)).void
|
||||
|
||||
def saveNext(game: Game, nextId: ID): Funit = coll.update(
|
||||
def unsetRematch(game: Game): Funit = coll.update(
|
||||
$id(game.id),
|
||||
$set(F.next -> nextId) ++
|
||||
$unset(
|
||||
"p0." + Player.BSONFields.isOfferingRematch,
|
||||
"p1." + Player.BSONFields.isOfferingRematch
|
||||
)
|
||||
$unset(
|
||||
"p0." + Player.BSONFields.isOfferingRematch,
|
||||
"p1." + Player.BSONFields.isOfferingRematch
|
||||
)
|
||||
).void
|
||||
|
||||
def initialFen(gameId: ID): Fu[Option[FEN]] =
|
||||
|
|
|
@ -6,9 +6,11 @@ import chess.format.{ FEN, Forsyth }
|
|||
import chess.variant.Crazyhouse
|
||||
import chess.{ Color, Clock }
|
||||
|
||||
object JsonView {
|
||||
final class JsonView(rematchOf: Game.ID => Option[Game.ID]) {
|
||||
|
||||
def gameJson(game: Game, initialFen: Option[FEN]) = Json.obj(
|
||||
import JsonView._
|
||||
|
||||
def apply(game: Game, initialFen: Option[FEN]) = Json.obj(
|
||||
"id" -> game.id,
|
||||
"variant" -> game.variant,
|
||||
"speed" -> game.speed.key,
|
||||
|
@ -28,7 +30,10 @@ object JsonView {
|
|||
.add("winner" -> game.winnerColor)
|
||||
.add("lastMove" -> game.lastMoveKeys)
|
||||
.add("check" -> game.situation.checkSquare.map(_.key))
|
||||
.add("rematch" -> game.next)
|
||||
.add("rematch" -> rematchOf(game.id))
|
||||
}
|
||||
|
||||
object JsonView {
|
||||
|
||||
implicit val statusWrites: OWrites[chess.Status] = OWrites { s =>
|
||||
Json.obj(
|
||||
|
|
|
@ -4,6 +4,7 @@ import akka.actor._
|
|||
import akka.pattern.ask
|
||||
import com.typesafe.config.Config
|
||||
import scala.concurrent.duration._
|
||||
import com.github.blemale.scaffeine.Cache
|
||||
|
||||
import actorApi.{ GetSocketStatus, SocketStatus }
|
||||
|
||||
|
@ -25,10 +26,11 @@ final class Env(
|
|||
playban: lila.playban.PlaybanApi,
|
||||
lightUser: lila.common.LightUser.Getter,
|
||||
userJsonView: lila.user.JsonView,
|
||||
gameJsonView: lila.game.JsonView,
|
||||
rankingApi: lila.user.RankingApi,
|
||||
notifyApi: lila.notify.NotifyApi,
|
||||
uciMemo: lila.game.UciMemo,
|
||||
rematch960Cache: lila.memo.ExpireSetMemo,
|
||||
rematches: Cache[Game.ID, Game.ID],
|
||||
divider: lila.game.Divider,
|
||||
prefApi: lila.pref.PrefApi,
|
||||
historyApi: lila.history.HistoryApi,
|
||||
|
@ -227,7 +229,7 @@ final class Env(
|
|||
private lazy val rematcher = new Rematcher(
|
||||
messenger = messenger,
|
||||
onStart = onStart,
|
||||
rematch960Cache = rematch960Cache,
|
||||
rematches = rematches,
|
||||
bus = bus
|
||||
)
|
||||
|
||||
|
@ -260,6 +262,7 @@ final class Env(
|
|||
lazy val jsonView = new JsonView(
|
||||
noteApi = noteApi,
|
||||
userJsonView = userJsonView,
|
||||
gameJsonView = gameJsonView,
|
||||
getSocketStatus = getSocketStatus,
|
||||
canTakeback = takebacker.isAllowedIn,
|
||||
canMoretime = moretimer.isAllowedIn,
|
||||
|
@ -326,10 +329,11 @@ object Env {
|
|||
playban = lila.playban.Env.current.api,
|
||||
lightUser = lila.user.Env.current.lightUser,
|
||||
userJsonView = lila.user.Env.current.jsonView,
|
||||
gameJsonView = lila.game.Env.current.jsonView,
|
||||
rankingApi = lila.user.Env.current.rankingApi,
|
||||
notifyApi = lila.notify.Env.current.api,
|
||||
uciMemo = lila.game.Env.current.uciMemo,
|
||||
rematch960Cache = lila.game.Env.current.cached.rematch960,
|
||||
rematches = lila.game.Env.current.rematches,
|
||||
divider = lila.game.Env.current.divider,
|
||||
prefApi = lila.pref.Env.current.api,
|
||||
historyApi = lila.history.Env.current.api,
|
||||
|
|
|
@ -19,6 +19,7 @@ import actorApi.SocketStatus
|
|||
final class JsonView(
|
||||
noteApi: NoteApi,
|
||||
userJsonView: lila.user.JsonView,
|
||||
gameJsonView: lila.game.JsonView,
|
||||
getSocketStatus: Game.ID => Fu[SocketStatus],
|
||||
canTakeback: Game => Fu[Boolean],
|
||||
canMoretime: Game => Fu[Boolean],
|
||||
|
@ -64,7 +65,7 @@ final class JsonView(
|
|||
case socket ~ opponentUser ~ takebackable ~ moretimeable =>
|
||||
import pov._
|
||||
Json.obj(
|
||||
"game" -> gameJson(game, initialFen),
|
||||
"game" -> gameJsonView(game, initialFen),
|
||||
"player" -> {
|
||||
commonPlayerJson(game, player, playerUser, withFlags) ++ Json.obj(
|
||||
"id" -> playerId,
|
||||
|
@ -154,7 +155,7 @@ final class JsonView(
|
|||
case (socket, (playerUser, opponentUser)) =>
|
||||
import pov._
|
||||
Json.obj(
|
||||
"game" -> gameJson(game, initialFen)
|
||||
"game" -> gameJsonView(game, initialFen)
|
||||
.add("moveCentis" -> (withFlags.movetimes ?? game.moveTimes.map(_.map(_.centis))))
|
||||
.add("division" -> withFlags.division.option(divider(game, initialFen)))
|
||||
.add("opening" -> game.opening)
|
||||
|
|
|
@ -4,7 +4,7 @@ import chess.format.Forsyth
|
|||
import chess.variant._
|
||||
import chess.{ Game => ChessGame, Board, Color => ChessColor, Castles, Clock, Situation }
|
||||
import ChessColor.{ White, Black }
|
||||
import com.github.blemale.scaffeine.{ Cache, Scaffeine }
|
||||
import com.github.blemale.scaffeine.Cache
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import lila.game.{ GameRepo, Game, Event, Progress, Pov, Source, AnonCookie, PerfPicker }
|
||||
|
@ -13,19 +13,15 @@ import lila.user.{ User, UserRepo }
|
|||
|
||||
private[round] final class Rematcher(
|
||||
messenger: Messenger,
|
||||
onStart: String => Unit,
|
||||
rematch960Cache: ExpireSetMemo,
|
||||
onStart: Game.ID => Unit,
|
||||
rematches: Cache[Game.ID, Game.ID],
|
||||
bus: lila.common.Bus
|
||||
) {
|
||||
|
||||
private val rematchCreated: Cache[Game.ID, Game.ID] = Scaffeine()
|
||||
.expireAfterWrite(1 minute)
|
||||
.build[Game.ID, Game.ID]
|
||||
|
||||
def yes(pov: Pov)(implicit proxy: GameProxy): Fu[Events] = pov match {
|
||||
case Pov(game, color) if game playerCanRematch color =>
|
||||
if (game.opponent(color).isOfferingRematch || game.opponent(color).isAi)
|
||||
game.next.fold(rematchJoin(pov))(rematchExists(pov))
|
||||
rematches.getIfPresent(game.id).fold(rematchJoin(pov))(rematchExists(pov))
|
||||
else rematchCreate(pov)
|
||||
case _ => fuccess(List(Event.ReloadOwner))
|
||||
}
|
||||
|
@ -42,23 +38,20 @@ private[round] final class Rematcher(
|
|||
case _ => fuccess(List(Event.ReloadOwner))
|
||||
}
|
||||
|
||||
private def rematchExists(pov: Pov)(nextId: String): Fu[Events] =
|
||||
private def rematchExists(pov: Pov)(nextId: Game.ID): Fu[Events] =
|
||||
GameRepo game nextId flatMap {
|
||||
_.fold(rematchJoin(pov))(g => fuccess(redirectEvents(g)))
|
||||
}
|
||||
|
||||
private def rematchJoin(pov: Pov): Fu[Events] =
|
||||
rematchCreated.getIfPresent(pov.gameId) match {
|
||||
rematches.getIfPresent(pov.gameId) match {
|
||||
case None => for {
|
||||
nextGame ← returnGame(pov) map (_.start)
|
||||
_ = rematchCreated.put(pov.gameId, nextGame.id)
|
||||
_ ← (GameRepo insertDenormalized nextGame) >>
|
||||
GameRepo.saveNext(pov.game, nextGame.id) >>-
|
||||
messenger.system(pov.game, _.rematchOfferAccepted) >>- {
|
||||
if (pov.game.variant == Chess960 && !rematch960Cache.get(pov.gameId))
|
||||
rematch960Cache.put(nextGame.id)
|
||||
}
|
||||
_ = rematches.put(pov.gameId, nextGame.id)
|
||||
_ ← GameRepo insertDenormalized nextGame
|
||||
_ <- GameRepo unsetRematch pov.game
|
||||
} yield {
|
||||
messenger.system(pov.game, _.rematchOfferAccepted)
|
||||
onStart(nextGame.id)
|
||||
redirectEvents(nextGame)
|
||||
}
|
||||
|
@ -78,7 +71,7 @@ private[round] final class Rematcher(
|
|||
situation = initialFen flatMap { fen => Forsyth <<< fen.value }
|
||||
pieces = pov.game.variant match {
|
||||
case Chess960 =>
|
||||
if (rematch960Cache get pov.gameId) Chess960.pieces
|
||||
if (rematches getIfPresent pov.gameId isDefined) Chess960.pieces
|
||||
else situation.fold(Chess960.pieces)(_.situation.board.pieces)
|
||||
case FromPosition => situation.fold(Standard.pieces)(_.situation.board.pieces)
|
||||
case variant => variant.pieces
|
||||
|
|
|
@ -11,7 +11,8 @@ private[tv] final class ChannelTrouper(
|
|||
channel: Tv.Channel,
|
||||
lightUser: lila.common.LightUser.GetterSync,
|
||||
onSelect: TvTrouper.Selected => Unit,
|
||||
proxyGame: Game.ID => Fu[Option[Game]]
|
||||
proxyGame: Game.ID => Fu[Option[Game]],
|
||||
rematchOf: Game.ID => Option[Game.ID]
|
||||
) extends Trouper {
|
||||
|
||||
import ChannelTrouper._
|
||||
|
@ -66,7 +67,7 @@ private[tv] final class ChannelTrouper(
|
|||
|
||||
private def isWayBetter(g1: Game, g2: Game) = score(g2.resetTurns) > (score(g1.resetTurns) * 1.17)
|
||||
|
||||
private def rematch(game: Game): Fu[Option[Game]] = game.next ?? proxyGame
|
||||
private def rematch(game: Game): Fu[Option[Game]] = rematchOf(game.id) ?? proxyGame
|
||||
|
||||
private def bestOf(candidates: List[Game]) =
|
||||
candidates sortBy { -score(_) } headOption
|
||||
|
|
|
@ -16,7 +16,8 @@ final class Env(
|
|||
lightUser: lila.common.LightUser.GetterSync,
|
||||
proxyGame: Game.ID => Fu[Option[Game]],
|
||||
system: ActorSystem,
|
||||
onSelect: Game => Unit
|
||||
onSelect: Game => Unit,
|
||||
rematchOf: Game.ID => Option[Game.ID]
|
||||
) {
|
||||
|
||||
private val FeaturedSelect = config duration "featured.select"
|
||||
|
@ -30,7 +31,8 @@ final class Env(
|
|||
selectChannel,
|
||||
lightUser,
|
||||
onSelect,
|
||||
proxyGame
|
||||
proxyGame,
|
||||
rematchOf
|
||||
)
|
||||
|
||||
lazy val tv = new Tv(tvTrouper, proxyGame)
|
||||
|
@ -49,6 +51,7 @@ object Env {
|
|||
lightUser = lila.user.Env.current.lightUserSync,
|
||||
proxyGame = lila.round.Env.current.proxy.gameIfPresent _,
|
||||
system = lila.common.PlayApp.system,
|
||||
onSelect = lila.round.Env.current.recentTvGames.put _
|
||||
onSelect = lila.round.Env.current.recentTvGames.put _,
|
||||
rematchOf = lila.game.Env.current.rematches.getIfPresent
|
||||
)
|
||||
}
|
||||
|
|
|
@ -16,7 +16,8 @@ private[tv] final class TvTrouper(
|
|||
selectChannel: lila.socket.Channel,
|
||||
lightUser: LightUser.GetterSync,
|
||||
onSelect: Game => Unit,
|
||||
proxyGame: Game.ID => Fu[Option[Game]]
|
||||
proxyGame: Game.ID => Fu[Option[Game]],
|
||||
rematchOf: Game.ID => Option[Game.ID]
|
||||
) extends Trouper {
|
||||
|
||||
import TvTrouper._
|
||||
|
@ -24,7 +25,7 @@ private[tv] final class TvTrouper(
|
|||
system.lilaBus.subscribe(this, 'startGame)
|
||||
|
||||
private val channelTroupers: Map[Tv.Channel, ChannelTrouper] = Tv.Channel.all.map { c =>
|
||||
c -> new ChannelTrouper(c, lightUser, onSelect = this.!, proxyGame)
|
||||
c -> new ChannelTrouper(c, lightUser, onSelect = this.!, proxyGame, rematchOf)
|
||||
}.toMap
|
||||
|
||||
private var channelChampions = Map[Tv.Channel, Tv.Champion]()
|
||||
|
|
Loading…
Reference in New Issue