Progress on round http
parent
5c1005d1c2
commit
eb781921ab
|
@ -8,8 +8,27 @@ import play.api.mvc._
|
||||||
object Round extends LilaController {
|
object Round extends LilaController {
|
||||||
|
|
||||||
val gameRepo = env.game.gameRepo
|
val gameRepo = env.game.gameRepo
|
||||||
|
val socket = env.round.socket
|
||||||
|
|
||||||
def player(id: String) = Open { implicit ctx ⇒
|
def player(id: String) = Open { implicit ctx ⇒
|
||||||
IOption(gameRepo pov id) { html.round.player(_) }
|
IOption(gameRepo pov id) { pov ⇒
|
||||||
|
html.round.player(pov, socket blockingVersion pov.gameId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def abort(fullId: String) = TODO
|
||||||
|
def resign(fullId: String) = TODO
|
||||||
|
def resignForce(fullId: String) = TODO
|
||||||
|
def drawClaim(fullId: String) = TODO
|
||||||
|
def drawAccept(fullId: String) = TODO
|
||||||
|
def drawOffer(fullId: String) = TODO
|
||||||
|
def drawCancel(fullId: String) = TODO
|
||||||
|
def drawDecline(fullId: String) = TODO
|
||||||
|
def takebackAccept(fullId: String) = TODO
|
||||||
|
def takebackOffer(fullId: String) = TODO
|
||||||
|
def takebackCancel(fullId: String) = TODO
|
||||||
|
def takebackDecline(fullId: String) = TODO
|
||||||
|
|
||||||
|
def table(gameId: String, color: String, fullId: String) = TODO
|
||||||
|
def players(gameId: String) = TODO
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ object Setup extends LilaController {
|
||||||
_ ⇒ Redirect(routes.Lobby.home),
|
_ ⇒ Redirect(routes.Lobby.home),
|
||||||
config ⇒ IORedirect(
|
config ⇒ IORedirect(
|
||||||
processor ai config map { pov ⇒
|
processor ai config map { pov ⇒
|
||||||
routes.Round.player(pov.playerFullId)
|
routes.Round.player(pov.fullId)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -13,6 +13,7 @@ final class Settings(config: Config) {
|
||||||
val GameUidTimeout = millis("game.uid.timeout")
|
val GameUidTimeout = millis("game.uid.timeout")
|
||||||
val GameHubTimeout = millis("game.hub.timeout")
|
val GameHubTimeout = millis("game.hub.timeout")
|
||||||
val GamePlayerTimeout = millis("game.player.timeout")
|
val GamePlayerTimeout = millis("game.player.timeout")
|
||||||
|
val GameAnimationDelay = millis("game.animation.delay")
|
||||||
|
|
||||||
val LobbyEntryMax = getInt("lobby.entry.max")
|
val LobbyEntryMax = getInt("lobby.entry.max")
|
||||||
val LobbyMessageMax = getInt("lobby.message.max")
|
val LobbyMessageMax = getInt("lobby.message.max")
|
||||||
|
|
|
@ -49,7 +49,11 @@ case class DbGame(
|
||||||
|
|
||||||
def opponent(p: DbPlayer): DbPlayer = player(!(p.color))
|
def opponent(p: DbPlayer): DbPlayer = player(!(p.color))
|
||||||
|
|
||||||
def player: DbPlayer = player(if (0 == turns % 2) White else Black)
|
def player: DbPlayer = player(turnColor)
|
||||||
|
|
||||||
|
def turnColor = Color(0 == turns % 2)
|
||||||
|
|
||||||
|
def turnOf(p: DbPlayer) = p == player
|
||||||
|
|
||||||
def fullIdOf(player: DbPlayer): Option[String] =
|
def fullIdOf(player: DbPlayer): Option[String] =
|
||||||
(players contains player) option id + player.id
|
(players contains player) option id + player.id
|
||||||
|
@ -87,7 +91,7 @@ case class DbGame(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
def toChessHistory = ChessHistory(
|
lazy val toChessHistory = ChessHistory(
|
||||||
lastMove = lastMove,
|
lastMove = lastMove,
|
||||||
castles = castles,
|
castles = castles,
|
||||||
positionHashes = positionHashes)
|
positionHashes = positionHashes)
|
||||||
|
@ -189,13 +193,20 @@ case class DbGame(
|
||||||
blackPlayer = f(blackPlayer)
|
blackPlayer = f(blackPlayer)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def start = started.fold(this, copy(
|
||||||
|
status = Status.Started,
|
||||||
|
isRated = isRated && (players forall (_.hasUser))
|
||||||
|
))
|
||||||
|
|
||||||
def recordMoveTimes = !hasAi
|
def recordMoveTimes = !hasAi
|
||||||
|
|
||||||
def hasMoveTimes = players forall (_.hasMoveTimes)
|
def hasMoveTimes = players forall (_.hasMoveTimes)
|
||||||
|
|
||||||
|
def started = status >= Status.Started
|
||||||
|
|
||||||
def playable = status < Status.Aborted
|
def playable = status < Status.Aborted
|
||||||
|
|
||||||
def playableBy(p: DbPlayer) = playable && p == player
|
def playableBy(p: DbPlayer) = playable && turnOf(p)
|
||||||
|
|
||||||
def aiLevel: Option[Int] = players find (_.isAi) flatMap (_.aiLevel)
|
def aiLevel: Option[Int] = players find (_.isAi) flatMap (_.aiLevel)
|
||||||
|
|
||||||
|
@ -207,8 +218,7 @@ case class DbGame(
|
||||||
)
|
)
|
||||||
|
|
||||||
def playerCanOfferDraw(color: Color) =
|
def playerCanOfferDraw(color: Color) =
|
||||||
status >= Status.Started &&
|
started && playable &&
|
||||||
status < Status.Aborted &&
|
|
||||||
turns >= 2 &&
|
turns >= 2 &&
|
||||||
!player(color).isOfferingDraw &&
|
!player(color).isOfferingDraw &&
|
||||||
!(player(!color).isAi) &&
|
!(player(!color).isAi) &&
|
||||||
|
@ -217,6 +227,11 @@ case class DbGame(
|
||||||
def playerHasOfferedDraw(color: Color) =
|
def playerHasOfferedDraw(color: Color) =
|
||||||
player(color).lastDrawOffer some (_ >= turns - 1) none false
|
player(color).lastDrawOffer some (_ >= turns - 1) none false
|
||||||
|
|
||||||
|
def playerCanProposeTakeback(color: Color) =
|
||||||
|
started && playable &&
|
||||||
|
turns >= 2 &&
|
||||||
|
!player(color).isProposingTakeback
|
||||||
|
|
||||||
def abortable = status == Status.Started && turns < 2
|
def abortable = status == Status.Started && turns < 2
|
||||||
|
|
||||||
def resignable = playable && !abortable
|
def resignable = playable && !abortable
|
||||||
|
@ -248,6 +263,11 @@ case class DbGame(
|
||||||
|
|
||||||
def withClock(c: Clock) = Progress(this, copy(clock = Some(c)))
|
def withClock(c: Clock) = Progress(this, copy(clock = Some(c)))
|
||||||
|
|
||||||
|
def estimateTotalTime = clock.fold(
|
||||||
|
c ⇒ c.limit + 30 * c.increment,
|
||||||
|
1200 // default to 20 minutes
|
||||||
|
)
|
||||||
|
|
||||||
def creator = player(creatorColor)
|
def creator = player(creatorColor)
|
||||||
|
|
||||||
def invited = player(!creatorColor)
|
def invited = player(!creatorColor)
|
||||||
|
@ -266,7 +286,7 @@ object DbGame {
|
||||||
def takeGameId(fullId: String) = fullId take gameIdSize
|
def takeGameId(fullId: String) = fullId take gameIdSize
|
||||||
|
|
||||||
def apply(
|
def apply(
|
||||||
game: Game,
|
game: Game,
|
||||||
whitePlayer: DbPlayer,
|
whitePlayer: DbPlayer,
|
||||||
blackPlayer: DbPlayer,
|
blackPlayer: DbPlayer,
|
||||||
ai: Option[(Color, Int)],
|
ai: Option[(Color, Int)],
|
||||||
|
@ -289,5 +309,5 @@ object DbGame {
|
||||||
isRated = isRated,
|
isRated = isRated,
|
||||||
variant = variant,
|
variant = variant,
|
||||||
lastMoveTime = None,
|
lastMoveTime = None,
|
||||||
createdAt = createdAt.some)
|
createdAt = createdAt.some)
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,8 @@ case class DbPlayer(
|
||||||
|
|
||||||
def userId: Option[String] = user map (_.getId.toString)
|
def userId: Option[String] = user map (_.getId.toString)
|
||||||
|
|
||||||
|
def hasUser = user.isDefined
|
||||||
|
|
||||||
def wins = isWinner getOrElse false
|
def wins = isWinner getOrElse false
|
||||||
|
|
||||||
def hasMoveTimes = moveTimes.size > 10
|
def hasMoveTimes = moveTimes.size > 10
|
||||||
|
|
|
@ -9,7 +9,7 @@ case class Pov(game: DbGame, color: Color) {
|
||||||
|
|
||||||
def playerId = player.id
|
def playerId = player.id
|
||||||
|
|
||||||
def playerFullId = game fullIdOf color
|
def fullId = game fullIdOf color
|
||||||
|
|
||||||
def gameId = game.id
|
def gameId = game.id
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ import akka.util.duration._
|
||||||
import akka.util.Timeout
|
import akka.util.Timeout
|
||||||
import akka.pattern.{ ask, pipe }
|
import akka.pattern.{ ask, pipe }
|
||||||
import akka.dispatch.{ Future, Promise }
|
import akka.dispatch.{ Future, Promise }
|
||||||
import akka.event.Logging
|
|
||||||
import play.api.libs.json._
|
import play.api.libs.json._
|
||||||
import play.api.libs.concurrent._
|
import play.api.libs.concurrent._
|
||||||
import play.api.Play.current
|
import play.api.Play.current
|
||||||
|
@ -21,7 +20,6 @@ final class HubMaster(
|
||||||
playerTimeout: Int) extends Actor {
|
playerTimeout: Int) extends Actor {
|
||||||
|
|
||||||
implicit val timeout = Timeout(1 second)
|
implicit val timeout = Timeout(1 second)
|
||||||
val log = Logging(context.system, this)
|
|
||||||
implicit val executor = Akka.system.dispatcher
|
implicit val executor = Akka.system.dispatcher
|
||||||
|
|
||||||
var hubs = Map.empty[String, ActorRef]
|
var hubs = Map.empty[String, ActorRef]
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
package lila
|
||||||
|
package round
|
||||||
|
|
||||||
|
import http.Context
|
||||||
|
import game.Pov
|
||||||
|
import templating.ConfigHelper
|
||||||
|
|
||||||
|
import com.codahale.jerkson.Json
|
||||||
|
import scala.math.{ min, max, round }
|
||||||
|
|
||||||
|
trait RoundHelper { self: ConfigHelper ⇒
|
||||||
|
|
||||||
|
def roundJsData(pov: Pov, version: Int) = Json generate {
|
||||||
|
|
||||||
|
import pov._
|
||||||
|
|
||||||
|
Map(
|
||||||
|
"game" -> Map(
|
||||||
|
"id" -> gameId,
|
||||||
|
"started" -> game.started,
|
||||||
|
"finished" -> game.finished,
|
||||||
|
"clock" -> game.hasClock,
|
||||||
|
"player" -> game.turnColor.name,
|
||||||
|
"turns" -> game.turns,
|
||||||
|
"lastMove" -> game.lastMove
|
||||||
|
),
|
||||||
|
"player" -> Map(
|
||||||
|
"id" -> player.id,
|
||||||
|
"color" -> player.color.name,
|
||||||
|
"version" -> version,
|
||||||
|
"spectator" -> false
|
||||||
|
),
|
||||||
|
"opponent" -> Map(
|
||||||
|
"color" -> opponent.color.name,
|
||||||
|
"ai" -> opponent.isAi
|
||||||
|
),
|
||||||
|
"possible_moves" -> possibleMoves(pov),
|
||||||
|
"animation_delay" -> animationDelay(pov)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private def possibleMoves(pov: Pov) = (pov.game playableBy pov.player) option {
|
||||||
|
pov.game.toChess.situation.destinations map {
|
||||||
|
case (from, dests) ⇒ from.key -> (dests.mkString)
|
||||||
|
} toMap
|
||||||
|
}
|
||||||
|
|
||||||
|
private def animationDelay(pov: Pov) = round {
|
||||||
|
gameAnimationDelay * max(0, min(1.2, ((pov.game.estimateTotalTime - 60) / 60) * 0.2))
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import akka.actor._
|
||||||
import akka.pattern.ask
|
import akka.pattern.ask
|
||||||
import akka.util.duration._
|
import akka.util.duration._
|
||||||
import akka.util.Timeout
|
import akka.util.Timeout
|
||||||
|
import akka.dispatch.Await
|
||||||
|
|
||||||
import play.api.libs.json._
|
import play.api.libs.json._
|
||||||
import play.api.libs.iteratee._
|
import play.api.libs.iteratee._
|
||||||
|
@ -24,7 +25,12 @@ final class Socket(
|
||||||
val hubMaster: ActorRef,
|
val hubMaster: ActorRef,
|
||||||
messenger: Messenger) {
|
messenger: Messenger) {
|
||||||
|
|
||||||
implicit val timeout = Timeout(1 second)
|
private val timeoutDuration = 1 second
|
||||||
|
implicit private val timeout = Timeout(timeoutDuration)
|
||||||
|
|
||||||
|
def blockingVersion(gameId: String): Int = Await.result(
|
||||||
|
hubMaster ? GetGameVersion(gameId) mapTo manifest[Int],
|
||||||
|
timeoutDuration)
|
||||||
|
|
||||||
def send(progress: Progress): IO[Unit] =
|
def send(progress: Progress): IO[Unit] =
|
||||||
send(progress.game.id, progress.events)
|
send(progress.game.id, progress.events)
|
||||||
|
@ -33,7 +39,7 @@ final class Socket(
|
||||||
hubMaster ! GameEvents(gameId, events)
|
hubMaster ! GameEvents(gameId, events)
|
||||||
}
|
}
|
||||||
|
|
||||||
def controller(
|
private def controller(
|
||||||
hub: ActorRef,
|
hub: ActorRef,
|
||||||
uid: String,
|
uid: String,
|
||||||
member: Member,
|
member: Member,
|
||||||
|
|
|
@ -23,7 +23,7 @@ case class AiConfig(variant: Variant, level: Int, color: Color) extends Config {
|
||||||
creatorColor = creatorColor,
|
creatorColor = creatorColor,
|
||||||
isRated = false,
|
isRated = false,
|
||||||
variant = variant,
|
variant = variant,
|
||||||
createdAt = DateTime.now)
|
createdAt = DateTime.now).start
|
||||||
}
|
}
|
||||||
|
|
||||||
object AiConfig extends BaseConfig {
|
object AiConfig extends BaseConfig {
|
||||||
|
|
|
@ -8,4 +8,6 @@ trait ConfigHelper {
|
||||||
protected def env: CoreEnv
|
protected def env: CoreEnv
|
||||||
|
|
||||||
def moretimeSeconds = env.settings.MoretimeSeconds
|
def moretimeSeconds = env.settings.MoretimeSeconds
|
||||||
|
|
||||||
|
def gameAnimationDelay = env.settings.GameAnimationDelay
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,14 @@ package lila
|
||||||
package templating
|
package templating
|
||||||
|
|
||||||
import core.Global.{ env ⇒ coreEnv } // OMG
|
import core.Global.{ env ⇒ coreEnv } // OMG
|
||||||
|
import round.RoundHelper
|
||||||
import http.{ HttpEnvironment, Setting }
|
import http.{ HttpEnvironment, Setting }
|
||||||
|
|
||||||
object Environment
|
object Environment
|
||||||
extends HttpEnvironment
|
extends HttpEnvironment
|
||||||
with scalaz.Identitys
|
with scalaz.Identitys
|
||||||
|
with scalaz.Options
|
||||||
|
with scalaz.Booleans
|
||||||
with StringHelper
|
with StringHelper
|
||||||
with AssetHelper
|
with AssetHelper
|
||||||
with I18nHelper
|
with I18nHelper
|
||||||
|
@ -14,7 +17,8 @@ object Environment
|
||||||
with RequestHelper
|
with RequestHelper
|
||||||
with SettingHelper
|
with SettingHelper
|
||||||
with UserHelper
|
with UserHelper
|
||||||
with ConfigHelper {
|
with ConfigHelper
|
||||||
|
with RoundHelper {
|
||||||
|
|
||||||
protected def env = coreEnv
|
protected def env = coreEnv
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,13 +17,13 @@ object Board {
|
||||||
s.pos.key,
|
s.pos.key,
|
||||||
s.top,
|
s.top,
|
||||||
s.left) ++
|
s.left) ++
|
||||||
"""<div class="lcsi">""" ++ {
|
"""<div class="lcsi"></div>""" ++ {
|
||||||
board(s.pos) map { piece ⇒
|
board(s.pos) map { piece ⇒
|
||||||
"""<div class="lichess_piece %s %s"></div>""".format(
|
"""<div class="lichess_piece %s %s"></div>""".format(
|
||||||
piece.role.name, piece.color.name)
|
piece.role.name, piece.color.name)
|
||||||
} getOrElse ""
|
} getOrElse ""
|
||||||
} ++
|
} ++
|
||||||
"</div></div>"
|
"</div>"
|
||||||
|
|
||||||
} mkString
|
} mkString
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@(pov: Pov)(implicit ctx: Context)
|
@(pov: Pov, version: Int)(implicit ctx: Context)
|
||||||
|
|
||||||
@import pov._
|
@import pov._
|
||||||
|
|
||||||
|
@ -18,7 +18,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@round.layout(title = title, goodies = goodies) {
|
@round.layout(title = title, goodies = goodies) {
|
||||||
<div class="lichess_game clearfix lichess_player_@color not_spectator">
|
<div class="lichess_game clearfix lichess_player_@color not_spectator"
|
||||||
|
data-table-url="@routes.Round.table(gameId, color.name, fullId)"
|
||||||
|
data-players-url="@routes.Round.players(gameId)">
|
||||||
<div class="lichess_board_wrap">
|
<div class="lichess_board_wrap">
|
||||||
@widget.connection()
|
@widget.connection()
|
||||||
<div class="lichess_board grey">@Html(ui.Board.render(pov))</div>
|
<div class="lichess_board grey">@Html(ui.Board.render(pov))</div>
|
||||||
|
@ -55,4 +57,5 @@
|
||||||
@round.cemetery(pov, "bottom")
|
@round.cemetery(pov, "bottom")
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script type="text/javascript">var lichess_data = @Html(roundJsData(pov, version))</script>
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,69 @@
|
||||||
@(pov: Pov)(implicit ctx: Context)
|
@(pov: Pov)(implicit ctx: Context)
|
||||||
|
|
||||||
table
|
@import pov._
|
||||||
|
|
||||||
|
<div class="lichess_current_player">
|
||||||
|
<div class="lichess_player white @game.turnColor.white.fold("", " none")">
|
||||||
|
<div class="lichess_piece king white"></div>
|
||||||
|
<p>@player.color.white.fold(trans.yourTurn(), trans.waiting())</p>
|
||||||
|
</div>
|
||||||
|
<div class="lichess_player black @game.turnColor.black.fold("", " none")">
|
||||||
|
<div class="lichess_piece king black"></div>
|
||||||
|
<p>@player.color.black.fold(trans.yourTurn(), trans.waiting())</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="lichess_control clearfix">
|
||||||
|
@if(game.abortable) {
|
||||||
|
<a href="@routes.Round.abort(fullId)" class="lichess_abort">@trans.abortGame()</a>
|
||||||
|
} else {
|
||||||
|
<a href="@routes.Round.resign(fullId)" class="lichess_resign" title="@trans.giveUp()">@trans.resign()</a>
|
||||||
|
@if(game.playerCanOfferDraw(color)) {
|
||||||
|
<a class="offer_draw" href="@routes.Round.drawOffer(fullId)">@trans.offerDraw()</a>
|
||||||
|
}
|
||||||
|
@if(game.playerCanProposeTakeback(color)) {
|
||||||
|
<a class="propose_takeback" title="@trans.proposeATakeback()"href="@routes.Round.takebackOffer(fullId)">@trans.takeback()</a>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
@if(game.resignable && !game.hasAi) {
|
||||||
|
<div class="force_resign_zone">
|
||||||
|
@trans.theOtherPlayerHasLeftTheGameYouCanForceResignationOrWaitForHim()<br />
|
||||||
|
<a class="force_resign" href="@routes.Round.resignForce(fullId)">@trans.forceResignation()</a>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if(game.turnOf(player) && game.toChessHistory.threefoldRepetition) {
|
||||||
|
<div class="lichess_claim_draw_zone">
|
||||||
|
@trans.threefoldRepetition().
|
||||||
|
<a class="lichess_claim_draw" href="@routes.Round.drawClaim(fullId)">@trans.claimADraw()</a>
|
||||||
|
</div>
|
||||||
|
} else {
|
||||||
|
@if(player.isOfferingDraw) {
|
||||||
|
<div class="offered_draw">
|
||||||
|
@trans.drawOfferSent().
|
||||||
|
<a href="@routes.Round.drawCancel(fullId)">@trans.cancel()</a>
|
||||||
|
</div>
|
||||||
|
} else {
|
||||||
|
@if(opponent.isOfferingDraw) {
|
||||||
|
<div class="offered_draw">
|
||||||
|
@trans.yourOpponentOffersADraw().<br />
|
||||||
|
<a href="@routes.Round.drawAccept(fullId)">@trans.accept()</a>
|
||||||
|
<a href="@routes.Round.drawDecline(fullId)">@trans.decline()</a>
|
||||||
|
</div>
|
||||||
|
} else {
|
||||||
|
@if(player.isProposingTakeback) {
|
||||||
|
<div class="proposed_takeback">
|
||||||
|
@trans.takebackPropositionSent().
|
||||||
|
<a href="@routes.Round.takebackCancel(fullId)">@trans.cancel()</a>
|
||||||
|
</div>
|
||||||
|
} else {
|
||||||
|
@if(opponent.isProposingTakeback) {
|
||||||
|
<div class="offered_draw">
|
||||||
|
@trans.yourOpponentProposesATakeback().<br />
|
||||||
|
<a href="@routes.Round.takebackAccept(fullId)">@trans.accept()</a>
|
||||||
|
<a href="@routes.Round.takebackDecline(fullId)">@trans.decline()</a>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
@(player: DbPlayer)(implicit ctx: Context)
|
@(player: DbPlayer)(implicit ctx: Context)
|
||||||
|
|
||||||
@if(player.isAi) {
|
@ai(level: Int) = {
|
||||||
<div class="username connected">
|
<div class="username connected">
|
||||||
@trans.aiNameLevelAiLevel("Crafty A.I.", player.aiLevel)
|
@trans.aiNameLevelAiLevel("Crafty A.I.", level)
|
||||||
</div>
|
</div>
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
@human = {
|
||||||
<div class="username @player.color.name">
|
<div class="username @player.color.name">
|
||||||
@playerLink(player, "blank_if_play")
|
@playerLink(player, "blank_if_play")
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@player.aiLevel.fold(ai, human)
|
||||||
|
|
|
@ -28,6 +28,7 @@ game {
|
||||||
uid.timeout = 10 seconds
|
uid.timeout = 10 seconds
|
||||||
hub.timeout = 2 minutes
|
hub.timeout = 2 minutes
|
||||||
player.timeout = 1 minute
|
player.timeout = 1 minute
|
||||||
|
animation.delay = 200 ms
|
||||||
}
|
}
|
||||||
site {
|
site {
|
||||||
uid.timeout = 10 seconds
|
uid.timeout = 10 seconds
|
||||||
|
|
38
conf/routes
38
conf/routes
|
@ -2,12 +2,27 @@
|
||||||
GET /games controllers.Game.list
|
GET /games controllers.Game.list
|
||||||
|
|
||||||
# Round
|
# Round
|
||||||
GET /$id<[\w\-]{12}> controllers.Round.player(id: String)
|
GET /$fullId<[\w\-]{12}> controllers.Round.player(fullId: String)
|
||||||
|
GET /abort/$fullId<[\w\-]{12}> controllers.Round.abort(fullId: String)
|
||||||
|
GET /resign/$fullId<[\w\-]{12}> controllers.Round.resign(fullId: String)
|
||||||
|
GET /resign-force/$fullId<[\w\-]{12}> controllers.Round.resignForce(fullId: String)
|
||||||
|
GET /draw-claim/$fullId<[\w\-]{12}> controllers.Round.drawClaim(fullId: String)
|
||||||
|
GET /draw-accept/$fullId<[\w\-]{12}> controllers.Round.drawAccept(fullId: String)
|
||||||
|
GET /draw-offer/$fullId<[\w\-]{12}> controllers.Round.drawOffer(fullId: String)
|
||||||
|
GET /draw-cancel/$fullId<[\w\-]{12}> controllers.Round.drawCancel(fullId: String)
|
||||||
|
GET /draw-decline/$fullId<[\w\-]{12}> controllers.Round.drawDecline(fullId: String)
|
||||||
|
GET /takeback-accept/$fullId<[\w\-]{12}> controllers.Round.takebackAccept(fullId: String)
|
||||||
|
GET /takeback-offer/$fullId<[\w\-]{12}> controllers.Round.takebackOffer(fullId: String)
|
||||||
|
GET /takeback-cancel/$fullId<[\w\-]{12}> controllers.Round.takebackCancel(fullId: String)
|
||||||
|
GET /takeback-decline/$fullId<[\w\-]{12}> controllers.Round.takebackDecline(fullId: String)
|
||||||
|
GET /table/$gameId<[\w\-]{8}>/$color<[white|black]> controllers.Round.table(gameId: String, color: String, fullId: String = "")
|
||||||
|
GET /table/$gameId<[\w\-]{8}>/$color<[white|black]>/$fullId<[\w\-]{12}> controllers.Round.table(gameId: String, color: String, fullId: String)
|
||||||
|
GET /players/$gameId<[\w\-]{8}> controllers.Round.players(gameId: String)
|
||||||
|
|
||||||
# Analyse
|
# Analyse
|
||||||
GET /analyse/$id<[\w\-]{8}> controllers.Analyse.replay(id: String, color: String = "white")
|
GET /analyse/$gameId<[\w\-]{8}> controllers.Analyse.replay(gameId: String, color: String = "white")
|
||||||
GET /analyse/$id<[\w\-]{8}>/$color<[white|black]> controllers.Analyse.replay(id: String, color: String)
|
GET /analyse/$gameId<[\w\-]{8}>/$color<[white|black]> controllers.Analyse.replay(gameId: String, color: String)
|
||||||
GET /$id<[\w\-]{8}>/stats controllers.Analyse.stats(id: String)
|
GET /$gameId<[\w\-]{8}>/stats controllers.Analyse.stats(gameId: String)
|
||||||
|
|
||||||
# Setting
|
# Setting
|
||||||
POST /setting/color controllers.Setting.color
|
POST /setting/color controllers.Setting.color
|
||||||
|
@ -39,25 +54,12 @@ GET /wiki controllers.Wiki.home
|
||||||
# App Public API
|
# App Public API
|
||||||
GET /socket controllers.App.socket
|
GET /socket controllers.App.socket
|
||||||
GET /socket/:gameId/:color controllers.App.gameSocket(gameId: String, color: String)
|
GET /socket/:gameId/:color controllers.App.gameSocket(gameId: String, color: String)
|
||||||
GET /abort/:fullId controllers.App.abort(fullId: String)
|
|
||||||
GET /resign/:fullId controllers.App.resign(fullId: String)
|
|
||||||
GET /resign-force/:fullId controllers.App.resignForce(fullId: String)
|
|
||||||
GET /draw-claim/:fullId controllers.App.drawClaim(fullId: String)
|
|
||||||
GET /draw-accept/:fullId controllers.App.drawAccept(fullId: String)
|
|
||||||
GET /draw-offer/:fullId controllers.App.drawOffer(fullId: String)
|
|
||||||
GET /draw-cancel/:fullId controllers.App.drawCancel(fullId: String)
|
|
||||||
GET /draw-decline/:fullId controllers.App.drawDecline(fullId: String)
|
|
||||||
GET /takeback-accept/:fullId controllers.App.takebackAccept(fullId: String)
|
|
||||||
GET /takeback-offer/:fullId controllers.App.takebackOffer(fullId: String)
|
|
||||||
GET /takeback-cancel/:fullId controllers.App.takebackCancel(fullId: String)
|
|
||||||
GET /takeback-decline/:fullId controllers.App.takebackDecline(fullId: String)
|
|
||||||
|
|
||||||
GET /ai controllers.Ai.run
|
GET /ai controllers.Ai.run
|
||||||
|
|
||||||
# App Private API
|
# App Private API
|
||||||
GET /api/show/:fullId controllers.AppApi.show(fullId: String)
|
|
||||||
POST /api/start/:gameId controllers.AppApi.start(gameId: String)
|
POST /api/start/:gameId controllers.AppApi.start(gameId: String)
|
||||||
POST /api/join/:fullId controllers.AppApi.join(fullId: String)
|
POST /api/join/$fullId<[\w\-]{12}> controllers.AppApi.join(fullId: String)
|
||||||
POST /api/reload-table/:gameId controllers.AppApi.reloadTable(gameId: String)
|
POST /api/reload-table/:gameId controllers.AppApi.reloadTable(gameId: String)
|
||||||
POST /api/adjust/:username controllers.AppApi.adjust(username: String)
|
POST /api/adjust/:username controllers.AppApi.adjust(username: String)
|
||||||
GET /api/activity/:gameId/:color controllers.AppApi.activity(gameId: String, color: String)
|
GET /api/activity/:gameId/:color controllers.AppApi.activity(gameId: String, color: String)
|
||||||
|
|
|
@ -11,6 +11,8 @@ $.widget("lichess.game", {
|
||||||
self.initialTitle = document.title;
|
self.initialTitle = document.title;
|
||||||
self.hasMovedOnce = false;
|
self.hasMovedOnce = false;
|
||||||
self.premove = null;
|
self.premove = null;
|
||||||
|
self.options.tableUrl = self.element.data('table-url');
|
||||||
|
self.options.playersUrl = self.element.data('players-url');
|
||||||
|
|
||||||
if (self.options.game.started) {
|
if (self.options.game.started) {
|
||||||
self.indicateTurn();
|
self.indicateTurn();
|
||||||
|
@ -514,7 +516,7 @@ $.widget("lichess.game", {
|
||||||
},
|
},
|
||||||
reloadTable: function(callback) {
|
reloadTable: function(callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
self.get(self.options.url.table, {
|
self.get(self.options.tableUrl, {
|
||||||
success: function(html) {
|
success: function(html) {
|
||||||
$('body > div.tipsy').remove();
|
$('body > div.tipsy').remove();
|
||||||
self.$tableInner.html(html);
|
self.$tableInner.html(html);
|
||||||
|
@ -526,7 +528,7 @@ $.widget("lichess.game", {
|
||||||
},
|
},
|
||||||
reloadPlayers: function(callback) {
|
reloadPlayers: function(callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
$.getJSON(self.options.url.players, function(data) {
|
$.getJSON(self.options.playersUrl, function(data) {
|
||||||
$(['white', 'black']).each(function() {
|
$(['white', 'black']).each(function() {
|
||||||
if (data[this]) self.$table.find('div.username.' + this).html(data[this]);
|
if (data[this]) self.$table.find('div.username.' + this).html(data[this]);
|
||||||
});
|
});
|
||||||
|
|
|
@ -56,10 +56,11 @@ $.websocket.prototype = {
|
||||||
})
|
})
|
||||||
.bind('message', function(e){
|
.bind('message', function(e){
|
||||||
var m = JSON.parse(e.originalEvent.data);
|
var m = JSON.parse(e.originalEvent.data);
|
||||||
self._debug(m);
|
|
||||||
if (m.t == "n") {
|
if (m.t == "n") {
|
||||||
self.keepAlive();
|
self.keepAlive();
|
||||||
}
|
} else {
|
||||||
|
self._debug(m);
|
||||||
|
}
|
||||||
if (m.t == "batch") {
|
if (m.t == "batch") {
|
||||||
$(m.d || []).each(function() { self._handle(this); });
|
$(m.d || []).each(function() { self._handle(this); });
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue