Implement rematches (and refactor stuff)
This commit is contained in:
parent
4dbb6ca5fd
commit
8777401a55
|
@ -17,6 +17,7 @@ object Round extends LilaController {
|
|||
private val gameRepo = env.game.gameRepo
|
||||
private val socket = env.round.socket
|
||||
private val hand = env.round.hand
|
||||
private val rematcher = env.setup.rematcher
|
||||
|
||||
def websocketWatcher(gameId: String, color: String) = WebSocket.async[JsValue] { req ⇒
|
||||
implicit val ctx = reqToCtx(req)
|
||||
|
@ -54,8 +55,19 @@ object Round extends LilaController {
|
|||
def drawOffer(fullId: String) = performAndRedirect(fullId, hand.drawOffer)
|
||||
def drawCancel(fullId: String) = performAndRedirect(fullId, hand.drawCancel)
|
||||
def drawDecline(fullId: String) = performAndRedirect(fullId, hand.drawDecline)
|
||||
def rematchOffer(fullId: String) = TODO
|
||||
def rematchAccept(fullId: String) = TODO
|
||||
def rematch(fullId: String) = Action {
|
||||
rematcher offerOrAccept fullId flatMap { validResult ⇒
|
||||
validResult.fold(
|
||||
err ⇒ putFailures(err) map { _ ⇒
|
||||
Redirect(routes.Round.player(fullId))
|
||||
}, {
|
||||
case (nextFullId, events) ⇒ performEvents(fullId)(events) map { _ ⇒
|
||||
Redirect(routes.Round.player(nextFullId))
|
||||
}
|
||||
}
|
||||
)
|
||||
} unsafePerformIO
|
||||
}
|
||||
def rematchCancel(fullId: String) = TODO
|
||||
def rematchDecline(fullId: String) = TODO
|
||||
def takebackAccept(fullId: String) = performAndRedirect(fullId, hand.takebackAccept)
|
||||
|
@ -70,7 +82,7 @@ object Round extends LilaController {
|
|||
def tablePlayer(fullId: String) = Open { implicit ctx ⇒
|
||||
IOption(gameRepo pov fullId) { pov ⇒
|
||||
pov.game.playable.fold(
|
||||
html.round.table.playing(pov),
|
||||
html.round.table.playing(pov),
|
||||
html.round.table.end(pov))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,9 @@ final class CoreEnv private (application: Application, val settings: Settings) {
|
|||
settings = settings,
|
||||
mongodb = mongodb.apply _,
|
||||
gameRepo = game.gameRepo,
|
||||
userRepo = user.userRepo,
|
||||
timelinePush = timeline.push.apply,
|
||||
roundMessenger = round.messenger,
|
||||
ai = ai.ai,
|
||||
dbRef = user.userRepo.dbRef)
|
||||
|
||||
|
@ -81,15 +83,6 @@ final class CoreEnv private (application: Application, val settings: Settings) {
|
|||
messageRepo = lobby.messageRepo,
|
||||
entryRepo = timeline.entryRepo)
|
||||
|
||||
//lazy val appApi = new AppApi(
|
||||
//userRepo = user.userRepo,
|
||||
//gameRepo = game.gameRepo,
|
||||
//roundSocket = round.socket,
|
||||
//messenger = round.messenger,
|
||||
//starter = lobby.starter,
|
||||
//eloUpdater = user.eloUpdater,
|
||||
//gameInfo = analyse.gameInfo)
|
||||
|
||||
lazy val mongodb = MongoConnection(
|
||||
new MongoServer(MongoHost, MongoPort),
|
||||
mongoOptions
|
||||
|
|
|
@ -55,10 +55,12 @@ case class DbGame(
|
|||
def isPlayerFullId(player: DbPlayer, fullId: String): Boolean =
|
||||
(fullId.size == DbGame.fullIdSize) && player.id == (fullId drop 8)
|
||||
|
||||
def opponent(p: DbPlayer): DbPlayer = player(!(p.color))
|
||||
|
||||
def player: DbPlayer = player(turnColor)
|
||||
|
||||
def opponent(p: DbPlayer): DbPlayer = opponent(p.color)
|
||||
|
||||
def opponent(c: Color): DbPlayer = player(!c)
|
||||
|
||||
def turnColor = Color(0 == turns % 2)
|
||||
|
||||
def turnOf(p: DbPlayer) = p == player
|
||||
|
@ -203,7 +205,8 @@ case class DbGame(
|
|||
|
||||
def start = started.fold(this, copy(
|
||||
status = Status.Started,
|
||||
isRated = isRated && (players forall (_.hasUser))
|
||||
isRated = isRated && (players forall (_.hasUser)),
|
||||
updatedAt = DateTime.now.some
|
||||
))
|
||||
|
||||
def recordMoveTimes = !hasAi
|
||||
|
@ -231,16 +234,19 @@ case class DbGame(
|
|||
started && playable &&
|
||||
turns >= 2 &&
|
||||
!player(color).isOfferingDraw &&
|
||||
!(player(!color).isAi) &&
|
||||
!(opponent(color).isAi) &&
|
||||
!(playerHasOfferedDraw(color))
|
||||
|
||||
def playerHasOfferedDraw(color: Color) =
|
||||
player(color).lastDrawOffer some (_ >= turns - 1) none false
|
||||
player(color).lastDrawOffer.fold(_ >= turns - 1, false)
|
||||
|
||||
def playerCanRematch(color: Color) =
|
||||
finishedOrAborted && opponent(color).isHuman
|
||||
|
||||
def playerCanProposeTakeback(color: Color) =
|
||||
started && playable &&
|
||||
turns >= 2 &&
|
||||
!player(color).isProposingTakeback
|
||||
opponent(color).isProposingTakeback
|
||||
|
||||
def abortable = status == Status.Started && turns < 2
|
||||
|
||||
|
@ -286,7 +292,9 @@ case class DbGame(
|
|||
|
||||
def creator = player(creatorColor)
|
||||
|
||||
def invited = player(!creatorColor)
|
||||
def invitedColor = !creatorColor
|
||||
|
||||
def invited = opponent(invitedColor)
|
||||
|
||||
def pgnList = pgn.split(' ').toList
|
||||
|
||||
|
@ -345,8 +353,7 @@ object DbGame {
|
|||
ai: Option[(Color, Int)],
|
||||
creatorColor: Color,
|
||||
isRated: Boolean,
|
||||
variant: Variant,
|
||||
createdAt: DateTime): DbGame = DbGame(
|
||||
variant: Variant): DbGame = DbGame(
|
||||
id = IdGenerator.game,
|
||||
whitePlayer = whitePlayer withEncodedPieces game.allPieces,
|
||||
blackPlayer = blackPlayer withEncodedPieces game.allPieces,
|
||||
|
@ -362,7 +369,7 @@ object DbGame {
|
|||
isRated = isRated,
|
||||
variant = variant,
|
||||
lastMoveTime = None,
|
||||
createdAt = createdAt.some)
|
||||
createdAt = DateTime.now.some)
|
||||
}
|
||||
|
||||
case class RawDbGame(
|
||||
|
|
|
@ -67,6 +67,10 @@ case class DbPlayer(
|
|||
|
||||
def removeDrawOffer = copy(isOfferingDraw = false)
|
||||
|
||||
def offerRematch = copy(isOfferingRematch = true)
|
||||
|
||||
def removeRematchOffer = copy(isOfferingRematch = false)
|
||||
|
||||
def proposeTakeback = copy(isProposingTakeback = true)
|
||||
|
||||
def removeTakebackProposition = copy(isProposingTakeback = false)
|
||||
|
@ -97,6 +101,10 @@ object DbPlayer {
|
|||
id = IdGenerator.player,
|
||||
color = color,
|
||||
aiLevel = aiLevel)
|
||||
|
||||
def white = apply(Color.White, None)
|
||||
|
||||
def black = apply(Color.Black, None)
|
||||
}
|
||||
|
||||
case class RawDbPlayer(
|
||||
|
|
|
@ -25,6 +25,7 @@ final class GameDiff(a: RawDbGame, b: RawDbGame) {
|
|||
d(name + "w", _.players(i).w)
|
||||
d(name + "lastDrawOffer", _.players(i).lastDrawOffer)
|
||||
d(name + "isOfferingDraw", _.players(i).isOfferingDraw)
|
||||
d(name + "isOfferingRematch", _.players(i).isOfferingRematch)
|
||||
d(name + "isProposingTakeback", _.players(i).isProposingTakeback)
|
||||
d(name + "blurs", _.players(i).blurs)
|
||||
d(name + "mts", _.players(i).mts)
|
||||
|
|
|
@ -24,10 +24,9 @@ trait GameHelper { self: I18nHelper with UserHelper ⇒
|
|||
def clockName(clock: Option[Clock])(implicit ctx: Context): String =
|
||||
clock.fold(clockName, trans.unlimited.str())
|
||||
|
||||
def clockName(clock: Clock): String = "%d minutes/side + %d seconds/move".format(
|
||||
clock.limitInMinutes, clock.increment)
|
||||
def clockName(clock: Clock): String = Namer clock clock
|
||||
|
||||
def usernameWithElo(player: DbPlayer) = PlayerNamer(player)(userIdToUsername)
|
||||
def usernameWithElo(player: DbPlayer) = Namer.player(player)(userIdToUsername)
|
||||
|
||||
def playerLink(player: DbPlayer, cssClass: Option[String] = None) = Html {
|
||||
player.userId.fold(
|
||||
|
|
31
app/game/Handler.scala
Normal file
31
app/game/Handler.scala
Normal file
|
@ -0,0 +1,31 @@
|
|||
package lila
|
||||
package game
|
||||
|
||||
import scalaz.effects._
|
||||
|
||||
abstract class Handler(gameRepo: GameRepo) {
|
||||
|
||||
protected def attempt[A](
|
||||
fullId: String,
|
||||
action: Pov ⇒ Valid[IO[A]]): IO[Valid[A]] =
|
||||
fromPov(fullId) { pov ⇒ action(pov).sequence }
|
||||
|
||||
protected def attemptRef[A](
|
||||
ref: PovRef,
|
||||
action: Pov ⇒ Valid[IO[A]]): IO[Valid[A]] =
|
||||
fromPov(ref) { pov ⇒ action(pov).sequence }
|
||||
|
||||
protected def fromPov[A](ref: PovRef)(op: Pov ⇒ IO[Valid[A]]): IO[Valid[A]] =
|
||||
fromPov(gameRepo pov ref)(op)
|
||||
|
||||
protected def fromPov[A](fullId: String)(op: Pov ⇒ IO[Valid[A]]): IO[Valid[A]] =
|
||||
fromPov(gameRepo pov fullId)(op)
|
||||
|
||||
protected def fromPov[A](povIO: IO[Option[Pov]])(op: Pov ⇒ IO[Valid[A]]): IO[Valid[A]] =
|
||||
povIO flatMap { povOption ⇒
|
||||
povOption.fold(
|
||||
pov ⇒ op(pov),
|
||||
io { "No such game".failNel }
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,15 +1,20 @@
|
|||
package lila
|
||||
package game
|
||||
|
||||
object PlayerNamer {
|
||||
import chess.Clock
|
||||
|
||||
object Namer {
|
||||
|
||||
val anonPlayerName = "Anonymous"
|
||||
|
||||
def apply(player: DbPlayer)(getUsername: String ⇒ String) =
|
||||
def player(player: DbPlayer)(getUsername: String ⇒ String) =
|
||||
player.aiLevel.fold(
|
||||
level ⇒ "A.I. level " + level,
|
||||
(player.userId map getUsername).fold(
|
||||
username ⇒ "%s (%s)".format(username, player.elo getOrElse "?"),
|
||||
anonPlayerName)
|
||||
)
|
||||
|
||||
def clock(clock: Clock): String = "%d minutes/side + %d seconds/move".format(
|
||||
clock.limitInMinutes, clock.increment)
|
||||
}
|
|
@ -2,7 +2,7 @@ package lila
|
|||
package round
|
||||
|
||||
import ai.Ai
|
||||
import game.{ GameRepo, Pov, PovRef }
|
||||
import game.{ GameRepo, Pov, PovRef, Handler }
|
||||
import chess.Role
|
||||
import chess.Pos.posAt
|
||||
|
||||
|
@ -20,7 +20,7 @@ final class Hand(
|
|||
ai: () ⇒ Ai,
|
||||
finisher: Finisher,
|
||||
hubMaster: ActorRef,
|
||||
moretimeSeconds: Int) {
|
||||
moretimeSeconds: Int) extends Handler(gameRepo) {
|
||||
|
||||
type IOValidEvents = IO[Valid[List[Event]]]
|
||||
|
||||
|
@ -34,7 +34,7 @@ final class Hand(
|
|||
g2 ← (g1.playable).fold(success(g1), failure("Game not playable" wrapNel))
|
||||
orig ← posAt(origString) toValid "Wrong orig " + origString
|
||||
dest ← posAt(destString) toValid "Wrong dest " + destString
|
||||
promotion = Role promotable promString
|
||||
promotion = Role promotable promString
|
||||
newChessGameAndMove ← g2.toChess(orig, dest, promotion)
|
||||
(newChessGame, move) = newChessGameAndMove
|
||||
} yield g2.update(newChessGame, move, blur)).fold(
|
||||
|
@ -127,6 +127,29 @@ final class Hand(
|
|||
else !!("no draw offer to decline " + fullId)
|
||||
})
|
||||
|
||||
def rematch(fullId: String): IO[Valid[(String, List[Event])]] =
|
||||
attempt(fullId, {
|
||||
case pov @ Pov(game, color) if game playerCanRematch color ⇒
|
||||
if (game.opponent(color).isOfferingRematch) success {
|
||||
game.nextId.fold(
|
||||
nextId ⇒ io(nextId -> Nil),
|
||||
io(fullId -> Nil) // accept
|
||||
)
|
||||
}
|
||||
//$nextOpponent = $this->gameGenerator->createReturnGame($opponent);
|
||||
//$nextPlayer = $nextOpponent->getOpponent();
|
||||
//$nextGame = $nextOpponent->getGame();
|
||||
//$messages = $this->starter->start($nextGame);
|
||||
//$this->objectManager->persist($nextGame);
|
||||
else success {
|
||||
val progress = Progress(game, Event.ReloadTable(!color)) map { g ⇒
|
||||
g.updatePlayer(color, _.offerRematch)
|
||||
}
|
||||
gameRepo save progress map { _ ⇒ fullId -> progress.events }
|
||||
}
|
||||
case _ ⇒ !!("invalid rematch offer " + fullId)
|
||||
})
|
||||
|
||||
def takebackAccept(fullId: String): IOValidEvents = fromPov(fullId) { pov ⇒
|
||||
if (pov.opponent.isProposingTakeback) for {
|
||||
fen ← gameRepo initialFen pov.game.id
|
||||
|
@ -201,28 +224,4 @@ final class Hand(
|
|||
} yield progress2.events
|
||||
} toValid "cannot add moretime"
|
||||
)
|
||||
|
||||
private def attempt[A](
|
||||
fullId: String,
|
||||
action: Pov ⇒ Valid[IO[A]]): IO[Valid[A]] =
|
||||
fromPov(fullId) { pov ⇒ action(pov).sequence }
|
||||
|
||||
private def attemptRef[A](
|
||||
ref: PovRef,
|
||||
action: Pov ⇒ Valid[IO[A]]): IO[Valid[A]] =
|
||||
fromPov(ref) { pov ⇒ action(pov).sequence }
|
||||
|
||||
private def fromPov[A](ref: PovRef)(op: Pov ⇒ IO[Valid[A]]): IO[Valid[A]] =
|
||||
fromPov(gameRepo pov ref)(op)
|
||||
|
||||
private def fromPov[A](fullId: String)(op: Pov ⇒ IO[Valid[A]]): IO[Valid[A]] =
|
||||
fromPov(gameRepo pov fullId)(op)
|
||||
|
||||
private def fromPov[A](povIO: IO[Option[Pov]])(op: Pov ⇒ IO[Valid[A]]): IO[Valid[A]] =
|
||||
povIO flatMap { povOption ⇒
|
||||
povOption.fold(
|
||||
pov ⇒ op(pov),
|
||||
io { "No such game".failNel }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,13 +19,15 @@ final class Messenger(roomRepo: RoomRepo) {
|
|||
else io(Nil)
|
||||
|
||||
def systemMessages(game: DbGame, encodedMessages: String): IO[List[Event]] =
|
||||
if (game.invited.isHuman) {
|
||||
val messages = (encodedMessages split '$').toList
|
||||
systemMessages(game, (encodedMessages split '$').toList)
|
||||
|
||||
def systemMessages(game: DbGame, messages: List[String]): IO[List[Event]] =
|
||||
game.invited.isHuman.fold(
|
||||
roomRepo.addSystemMessages(game.id, messages) map { _ ⇒
|
||||
messages map { Message("system", _) }
|
||||
}
|
||||
}
|
||||
else io(Nil)
|
||||
},
|
||||
io(Nil)
|
||||
)
|
||||
|
||||
def systemMessage(game: DbGame, message: String): IO[List[Event]] =
|
||||
if (game.invited.isHuman)
|
||||
|
|
|
@ -26,4 +26,7 @@ object Progress {
|
|||
|
||||
def apply(game: DbGame, events: List[Event]): Progress =
|
||||
new Progress(game, game, events)
|
||||
|
||||
def apply(game: DbGame, events: Event): Progress =
|
||||
new Progress(game, game, events :: Nil)
|
||||
}
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
package lila
|
||||
package round
|
||||
|
||||
import scalaz.effects._
|
||||
import com.mongodb.casbah.MongoCollection
|
||||
|
||||
import akka.actor._
|
||||
|
||||
import akka.actor.Props
|
||||
import play.api.libs.concurrent._
|
||||
import play.api.Application
|
||||
|
||||
import game.{ GameRepo }
|
||||
import game.{ GameRepo, DbGame }
|
||||
import user.{ UserRepo, EloUpdater }
|
||||
import ai.Ai
|
||||
import core.Settings
|
||||
|
@ -20,7 +19,7 @@ final class RoundEnv(
|
|||
gameRepo: GameRepo,
|
||||
userRepo: UserRepo,
|
||||
eloUpdater: EloUpdater,
|
||||
ai: () => Ai) {
|
||||
ai: () ⇒ Ai) {
|
||||
|
||||
implicit val ctx = app
|
||||
import settings._
|
||||
|
@ -63,7 +62,7 @@ final class RoundEnv(
|
|||
lazy val finisherLock = new FinisherLock(timeout = FinisherLockTimeout)
|
||||
|
||||
lazy val takeback = new Takeback(
|
||||
gameRepo = gameRepo,
|
||||
gameRepo = gameRepo,
|
||||
messenger = messenger)
|
||||
|
||||
lazy val messenger = new Messenger(roomRepo = roomRepo)
|
||||
|
|
|
@ -5,8 +5,6 @@ import chess.{ Game, Board, Variant, Color ⇒ ChessColor }
|
|||
import elo.EloRange
|
||||
import game.{ DbGame, DbPlayer }
|
||||
|
||||
import org.joda.time.DateTime
|
||||
|
||||
case class AiConfig(
|
||||
variant: Variant,
|
||||
level: Int,
|
||||
|
@ -25,8 +23,7 @@ case class AiConfig(
|
|||
aiLevel = creatorColor.white option level),
|
||||
creatorColor = creatorColor,
|
||||
isRated = false,
|
||||
variant = variant,
|
||||
createdAt = DateTime.now).start
|
||||
variant = variant).start
|
||||
|
||||
def encode = RawAiConfig(
|
||||
v = variant.id,
|
||||
|
|
93
app/setup/Rematcher.scala
Normal file
93
app/setup/Rematcher.scala
Normal file
|
@ -0,0 +1,93 @@
|
|||
package lila
|
||||
package setup
|
||||
|
||||
import chess.{ Game, Board, Clock, Color ⇒ ChessColor }
|
||||
import ChessColor.{ White, Black }
|
||||
import chess.format.Forsyth
|
||||
import game.{ GameRepo, DbGame, DbPlayer, Pov, Handler, Namer }
|
||||
import round.{ Event, Progress, Messenger }
|
||||
import user.UserRepo
|
||||
import controllers.routes
|
||||
|
||||
import scalaz.effects._
|
||||
|
||||
final class Rematcher(
|
||||
gameRepo: GameRepo,
|
||||
userRepo: UserRepo,
|
||||
messenger: Messenger,
|
||||
timelinePush: DbGame ⇒ IO[Unit]) extends Handler(gameRepo) {
|
||||
|
||||
def offerOrAccept(fullId: String): IO[Valid[(String, List[Event])]] =
|
||||
attempt(fullId, {
|
||||
case pov @ Pov(game, color) if game playerCanRematch color ⇒
|
||||
if (game.opponent(color).isOfferingRematch) success {
|
||||
game.nextId.fold(
|
||||
nextId ⇒ io(nextId -> Nil),
|
||||
for {
|
||||
nextGame ← returnGame(pov) map (_.start)
|
||||
_ ← gameRepo insert nextGame
|
||||
nextId = nextGame.id
|
||||
_ ← game.variant.standard.fold(io(), gameRepo saveInitialFen game)
|
||||
_ ← timelinePush(game)
|
||||
// messenges are not sent to the next game socket
|
||||
// as nobody is there to see them yet
|
||||
_ ← messenger.systemMessages(nextGame, List(
|
||||
Some(nextGame.creatorColor + " creates the game"),
|
||||
Some(nextGame.invitedColor + " joins the game"),
|
||||
nextGame.clock map Namer.clock,
|
||||
nextGame.isRated option "This game is rated").flatten)
|
||||
} yield nextId -> List(
|
||||
Event.RedirectOwner(White, playerUrl(nextGame, White)),
|
||||
Event.RedirectOwner(Black, playerUrl(nextGame, Black)),
|
||||
// tell spectators to reload the table
|
||||
Event.ReloadTable(White),
|
||||
Event.ReloadTable(Black))
|
||||
)
|
||||
}
|
||||
else success {
|
||||
val progress = Progress(game, Event.ReloadTable(!color)) map { g ⇒
|
||||
g.updatePlayer(color, _.offerRematch)
|
||||
}
|
||||
gameRepo save progress map { _ ⇒ fullId -> progress.events }
|
||||
}
|
||||
case _ ⇒ !!("invalid rematch offer " + fullId)
|
||||
})
|
||||
|
||||
private def returnGame(pov: Pov): IO[DbGame] = for {
|
||||
board ← pov.game.variant.standard.fold(
|
||||
io(pov.game.variant.pieces),
|
||||
gameRepo initialFen pov.game.id map { fenOption ⇒
|
||||
(fenOption flatMap Forsyth.<< map { situation ⇒
|
||||
situation.board.pieces
|
||||
}) | pov.game.variant.pieces
|
||||
})
|
||||
whitePlayer ← returnPlayer(pov.game, White)
|
||||
blackPlayer ← returnPlayer(pov.game, Black)
|
||||
} yield DbGame(
|
||||
game = Game(
|
||||
board = Board(board),
|
||||
clock = pov.game.clock map (_.reset)),
|
||||
whitePlayer = whitePlayer,
|
||||
blackPlayer = blackPlayer,
|
||||
ai = None,
|
||||
creatorColor = !pov.color,
|
||||
isRated = pov.game.isRated,
|
||||
variant = pov.game.variant)
|
||||
|
||||
private def returnPlayer(game: DbGame, color: ChessColor): IO[DbPlayer] =
|
||||
DbPlayer(color = color, aiLevel = None) |> { player ⇒
|
||||
game.player(color).userId.fold(
|
||||
userId ⇒ userRepo user userId map { userOption ⇒
|
||||
userOption.fold(
|
||||
user ⇒ player.withUser(user)(userRepo.dbRef),
|
||||
player)
|
||||
},
|
||||
io(player))
|
||||
}
|
||||
|
||||
private def clockName(clock: Option[Clock]): String =
|
||||
clock.fold(Namer.clock, "Unlimited")
|
||||
|
||||
private def playerUrl(game: DbGame, color: ChessColor): String =
|
||||
routes.Round.player(game fullIdOf color).url
|
||||
}
|
|
@ -3,8 +3,9 @@ package setup
|
|||
|
||||
import core.Settings
|
||||
import game.{ DbGame, GameRepo }
|
||||
import round.Messenger
|
||||
import ai.Ai
|
||||
import user.User
|
||||
import user.{ User, UserRepo }
|
||||
|
||||
import com.mongodb.casbah.MongoCollection
|
||||
import scalaz.effects._
|
||||
|
@ -14,7 +15,9 @@ final class SetupEnv(
|
|||
settings: Settings,
|
||||
mongodb: String ⇒ MongoCollection,
|
||||
gameRepo: GameRepo,
|
||||
userRepo: UserRepo,
|
||||
timelinePush: DbGame ⇒ IO[Unit],
|
||||
roundMessenger: Messenger,
|
||||
ai: () ⇒ Ai,
|
||||
dbRef: User ⇒ DBRef) {
|
||||
|
||||
|
@ -31,4 +34,10 @@ final class SetupEnv(
|
|||
timelinePush = timelinePush,
|
||||
ai = ai,
|
||||
dbRef = dbRef)
|
||||
|
||||
lazy val rematcher = new Rematcher(
|
||||
gameRepo = gameRepo,
|
||||
userRepo = userRepo,
|
||||
messenger = roundMessenger,
|
||||
timelinePush = timelinePush)
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ package lila
|
|||
package timeline
|
||||
|
||||
import chess.Color
|
||||
import game.{ DbGame, PlayerNamer }
|
||||
import game.{ DbGame, Namer }
|
||||
|
||||
import scalaz.effects._
|
||||
|
||||
|
@ -32,5 +32,5 @@ final class Push(
|
|||
(game player color).userId
|
||||
|
||||
private def usernameElo(game: DbGame, color: Color): String =
|
||||
PlayerNamer(game player color)(getUsername)
|
||||
Namer.player(game player color)(getUsername)
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ final class TimelineEnv(
|
|||
settings: Settings,
|
||||
mongodb: String ⇒ MongoCollection,
|
||||
lobbyNotify: Entry ⇒ IO[Unit],
|
||||
getUsername: String => String) {
|
||||
getUsername: String ⇒ String) {
|
||||
|
||||
import settings._
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
@if(opponent.isOfferingRematch) {
|
||||
<div class="lichess_play_again_join rematch_alert">
|
||||
@trans.yourOpponentWantsToPlayANewGameWithYou().
|
||||
<a class="lichess_play_again lichess_rematch" title="@trans.playWithTheSameOpponentAgain()" href="@routes.Round.rematchAccept(fullId)">@trans.joinTheGame()</a><br />
|
||||
<a class="lichess_play_again lichess_rematch" title="@trans.playWithTheSameOpponentAgain()" href="@routes.Round.rematch(fullId)">@trans.joinTheGame()</a><br />
|
||||
<a class="lichess_rematch_decline" href="@routes.Round.rematchDecline(fullId)">@trans.declineInvitation()</a>
|
||||
</div>
|
||||
} else {
|
||||
|
@ -22,7 +22,7 @@
|
|||
<a class="lichess_rematch_cancel" href="@routes.Round.rematchCancel(fullId)">@trans.cancelRematchOffer()</a>
|
||||
</div>
|
||||
} else {
|
||||
<a class="lichess_rematch button" title="@trans.playWithTheSameOpponentAgain()" href="@routes.Round.rematchOffer(fullId)">@trans.rematch()</a>
|
||||
<a class="lichess_rematch button" title="@trans.playWithTheSameOpponentAgain()" href="@routes.Round.rematch(fullId)">@trans.rematch()</a>
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -18,8 +18,7 @@ GET /$fullId<[\w\-]{12}>/draw/accept controllers.Round.drawAccep
|
|||
GET /$fullId<[\w\-]{12}>/draw/offer controllers.Round.drawOffer(fullId: String)
|
||||
GET /$fullId<[\w\-]{12}>/draw/cancel controllers.Round.drawCancel(fullId: String)
|
||||
GET /$fullId<[\w\-]{12}>/draw/decline controllers.Round.drawDecline(fullId: String)
|
||||
GET /$fullId<[\w\-]{12}>/rematch/offer controllers.Round.rematchOffer(fullId: String)
|
||||
GET /$fullId<[\w\-]{12}>/rematch/accept controllers.Round.rematchAccept(fullId: String)
|
||||
GET /$fullId<[\w\-]{12}>/rematch controllers.Round.rematch(fullId: String)
|
||||
GET /$fullId<[\w\-]{12}>/rematch/cancel controllers.Round.rematchCancel(fullId: String)
|
||||
GET /$fullId<[\w\-]{12}>/rematch/decline controllers.Round.rematchDecline(fullId: String)
|
||||
GET /$fullId<[\w\-]{12}>/takeback/accept controllers.Round.takebackAccept(fullId: String)
|
||||
|
|
|
@ -12,7 +12,7 @@ trait Resolvers {
|
|||
}
|
||||
|
||||
trait Dependencies {
|
||||
val scalachess = "com.github.ornicar" %% "scalachess" % "1.1"
|
||||
val scalachess = "com.github.ornicar" %% "scalachess" % "1.2"
|
||||
val scalaz = "org.scalaz" %% "scalaz-core" % "6.0.4"
|
||||
val specs2 = "org.specs2" %% "specs2" % "1.8.2"
|
||||
val casbah = "com.mongodb.casbah" %% "casbah" % "2.1.5-1"
|
||||
|
|
Loading…
Reference in a new issue