archive seeks and restore seeks of aborted correspondence games
parent
e26a8381c0
commit
610737d2a2
|
@ -10,10 +10,11 @@ case class StartGame(game: Game)
|
|||
case class UserStartGame(userId: String, game: Game)
|
||||
|
||||
case class FinishGame(game: Game, white: Option[User], black: Option[User]) {
|
||||
|
||||
def isVsSelf = white.isDefined && white == black
|
||||
}
|
||||
|
||||
case class InsertGame(game: Game)
|
||||
|
||||
case class AbortedBy(pov: Pov)
|
||||
|
||||
private[game] case object NewCaptcha
|
||||
|
|
|
@ -169,6 +169,7 @@ case class MoveEvent(
|
|||
opponentUserId: Option[String],
|
||||
simulId: Option[String])
|
||||
case class NbRounds(nb: Int)
|
||||
case class Abort(gameId: String, byColor: String)
|
||||
}
|
||||
|
||||
package evaluation {
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package lila.lobby
|
||||
|
||||
import org.joda.time.DateTime
|
||||
|
||||
import lila.game.Pov
|
||||
|
||||
private[lobby] final class AbortListener(seekApi: SeekApi) {
|
||||
|
||||
def recreateSeek(pov: Pov): Funit = pov.player.userId ?? { aborterId =>
|
||||
seekApi.findArchived(pov.game.id) flatMap {
|
||||
_ ?? { seek =>
|
||||
(seek.user.id != aborterId) ?? seekApi.insert(Seek renew seek)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -25,6 +25,7 @@ final class Env(
|
|||
val BroomPeriod = config duration "broom_period"
|
||||
val ResyncIdsPeriod = config duration "resync_ids_period"
|
||||
val CollectionSeek = config getString "collection.seek"
|
||||
val CollectionSeekArchive = config getString "collection.seek_archive"
|
||||
val SeekMaxPerPage = config getInt "seek.max_per_page"
|
||||
val SeekMaxPerUser = config getInt "seek.max_per_user"
|
||||
}
|
||||
|
@ -38,6 +39,7 @@ final class Env(
|
|||
|
||||
lazy val seekApi = new SeekApi(
|
||||
coll = db(CollectionSeek),
|
||||
archiveColl = db(CollectionSeekArchive),
|
||||
blocking = blocking,
|
||||
maxPerPage = SeekMaxPerPage,
|
||||
maxPerUser = SeekMaxPerUser)
|
||||
|
@ -57,6 +59,16 @@ final class Env(
|
|||
|
||||
lazy val history = new History[actorApi.Messadata](ttl = MessageTtl)
|
||||
|
||||
private val abortListener = new AbortListener(seekApi = seekApi)
|
||||
|
||||
system.actorOf(Props(new Actor {
|
||||
system.lilaBus.subscribe(self, 'abortGame)
|
||||
def receive = {
|
||||
case lila.game.actorApi.AbortedBy(pov) if pov.game.isCorrespondence =>
|
||||
abortListener recreateSeek pov
|
||||
}
|
||||
}))
|
||||
|
||||
{
|
||||
import scala.concurrent.duration._
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ private[lobby] final class Lobby(
|
|||
case msg@JoinSeek(_, seek, game, _) =>
|
||||
onStart(game.id)
|
||||
socket ! msg
|
||||
(seekApi remove seek) >>- {
|
||||
seekApi.archive(seek, game.id) >>- {
|
||||
socket ! RemoveSeek(seek.id)
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ case class Seek(
|
|||
|
||||
def compatibleWith(h: Seek) =
|
||||
user.id != h.user.id &&
|
||||
compatibilityProperties == h.compatibilityProperties &&
|
||||
compatibilityProperties == h.compatibilityProperties &&
|
||||
(realColor compatibleWith h.realColor) &&
|
||||
ratingRangeCompatibleWith(h) && h.ratingRangeCompatibleWith(this)
|
||||
|
||||
|
@ -85,6 +85,16 @@ object Seek {
|
|||
ratingRange = ratingRange.toString,
|
||||
createdAt = DateTime.now)
|
||||
|
||||
def renew(seek: Seek) = new Seek(
|
||||
_id = Random nextStringUppercase idSize,
|
||||
variant = seek.variant,
|
||||
daysPerTurn = seek.daysPerTurn,
|
||||
mode = seek.mode,
|
||||
color = seek.color,
|
||||
user = seek.user,
|
||||
ratingRange = seek.ratingRange,
|
||||
createdAt = DateTime.now)
|
||||
|
||||
import reactivemongo.bson.Macros
|
||||
import lila.db.BSON.MapValue.MapHandler
|
||||
import lila.db.BSON.BSONJodaDateTimeHandler
|
||||
|
|
|
@ -6,12 +6,14 @@ import reactivemongo.core.commands._
|
|||
import scala.concurrent.duration._
|
||||
|
||||
import actorApi.LobbyUser
|
||||
import lila.db.BSON.BSONJodaDateTimeHandler
|
||||
import lila.db.Types.Coll
|
||||
import lila.memo.AsyncCache
|
||||
import lila.user.{ User, UserRepo }
|
||||
|
||||
final class SeekApi(
|
||||
coll: Coll,
|
||||
archiveColl: Coll,
|
||||
blocking: String => Fu[Set[String]],
|
||||
maxPerPage: Int,
|
||||
maxPerUser: Int) {
|
||||
|
@ -30,7 +32,7 @@ final class SeekApi(
|
|||
case ForAnon => allCursor.collect[List](maxPerPage)
|
||||
case ForUser => allCursor.collect[List]()
|
||||
},
|
||||
timeToLive = 5.seconds)
|
||||
timeToLive = 3.seconds)
|
||||
|
||||
def forAnon = cache(ForAnon)
|
||||
|
||||
|
@ -62,6 +64,18 @@ final class SeekApi(
|
|||
def remove(seek: Seek) =
|
||||
coll.remove(BSONDocument("_id" -> seek.id)).void >> cache.clear
|
||||
|
||||
def archive(seek: Seek, gameId: String) = {
|
||||
val archiveDoc = Seek.seekBSONHandler.write(seek) ++ BSONDocument(
|
||||
"gameId" -> gameId,
|
||||
"archivedAt" -> DateTime.now)
|
||||
coll.remove(BSONDocument("_id" -> seek.id)).void >>
|
||||
cache.clear >>
|
||||
archiveColl.insert(archiveDoc)
|
||||
}
|
||||
|
||||
def findArchived(gameId: String): Fu[Option[Seek]] =
|
||||
archiveColl.find(BSONDocument("gameId" -> gameId)).one[Seek]
|
||||
|
||||
def removeBy(seekId: String, userId: String) =
|
||||
coll.remove(BSONDocument(
|
||||
"_id" -> seekId,
|
||||
|
|
|
@ -5,7 +5,7 @@ import chess.Status._
|
|||
import chess.{ Status, Color, Speed }
|
||||
|
||||
import lila.db.api._
|
||||
import lila.game.actorApi.FinishGame
|
||||
import lila.game.actorApi.{ FinishGame, AbortedBy }
|
||||
import lila.game.tube.gameTube
|
||||
import lila.game.{ GameRepo, Game, Pov, Event }
|
||||
import lila.i18n.I18nKey.{ Select => SelectI18nKey }
|
||||
|
@ -21,6 +21,10 @@ private[round] final class Finisher(
|
|||
timeline: akka.actor.ActorSelection,
|
||||
casualOnly: Boolean) {
|
||||
|
||||
def abort(pov: Pov): Fu[Events] = apply(pov.game, _.Aborted) addEffect { _ =>
|
||||
bus.publish(AbortedBy(pov), 'abortGame)
|
||||
}
|
||||
|
||||
def apply(
|
||||
game: Game,
|
||||
status: Status.type => Status,
|
||||
|
|
|
@ -52,7 +52,7 @@ private[round] final class Round(
|
|||
}
|
||||
|
||||
case Abort(playerId) => handle(playerId) { pov =>
|
||||
pov.game.abortable ?? finisher(pov.game, _.Aborted)
|
||||
pov.game.abortable ?? finisher.abort(pov)
|
||||
}
|
||||
|
||||
case Resign(playerId) => handle(playerId) { pov =>
|
||||
|
|
|
@ -4,7 +4,7 @@ import akka.actor._
|
|||
import com.typesafe.config.{ Config => AppConfig }
|
||||
|
||||
import lila.common.PimpedConfig._
|
||||
import lila.game.{ Game, Progress }
|
||||
import lila.game.{ Game, Pov, Progress }
|
||||
import lila.user.UserContext
|
||||
|
||||
final class Env(
|
||||
|
|
Loading…
Reference in New Issue