Immense refactoring

This commit is contained in:
Thibault Duplessis 2012-05-14 19:20:57 +02:00
parent f519736f51
commit 04bd07fa5b
90 changed files with 437 additions and 309 deletions

View file

@ -1,11 +1,11 @@
package lila
import model._
import memo._
import game._
import user._
import db.{ GameRepo, RoomRepo }
import game.{ GameRepo, RoomRepo }
import chess.{ Color, White, Black }
import game.{ IsConnectedOnGame, GetGameVersion }
import analyse.GameInfo
import scalaz.effects._
import akka.actor._

View file

@ -11,6 +11,8 @@ import play.api.libs.concurrent._
import play.api.Play.current
import scalaz.effects._
import implicits.RichDuration._
object Cron {
def start(env: SystemEnv) {
@ -20,13 +22,13 @@ object Cron {
implicit val executor = Akka.system.dispatcher
unsafe(5 seconds) {
(env.siteHub :: env.lobby.hub :: env.gameHubMaster :: Nil) foreach { actor
(env.site.hub :: env.lobby.hub :: env.game.hubMaster :: Nil) foreach { actor
actor ! socket.Broom
}
}
message(5 seconds) {
env.reporting -> report.Update(env)
env.site.reporting -> report.Update(env)
}
message(1 second) {
@ -61,7 +63,7 @@ object Cron {
}
effect(4.1 hours) {
env.gameRepo.cleanupUnplayed flatMap { _
env.game.gameRepo.cleanupUnplayed flatMap { _
env.gameCleanNextCommand.apply
}
}
@ -71,14 +73,12 @@ object Cron {
}
effect(10 seconds) {
env.remoteAi.diagnose
env.ai.remoteAi.diagnose
}
env.remoteAi.diagnose.unsafePerformIO
import RichDuration._
env.ai.remoteAi.diagnose.unsafePerformIO
lazy val hubs: List[ActorRef] =
List(env.siteHub, env.lobby.hub, env.gameHubMaster)
List(env.site.hub, env.lobby.hub, env.game.hubMaster)
def message(freq: Duration)(to: (ActorRef, Any)) {
Akka.system.scheduler.schedule(freq, freq.randomize(), to._1, to._2)

View file

@ -1,6 +1,6 @@
package lila
import lila.model._
import lila.game._
import play.api.data._
import play.api.data.Forms._

View file

@ -20,7 +20,7 @@ object Global extends GlobalSettings {
override def onRouteRequest(request: RequestHeader): Option[Handler] = {
println(request)
env.i18nRequestHandler(request) orElse super.onRouteRequest(request)
env.i18n.requestHandler(request) orElse super.onRouteRequest(request)
}
override def onHandlerNotFound(request: RequestHeader): Result = {

View file

@ -3,146 +3,74 @@ package lila
import com.mongodb.casbah.MongoConnection
import com.mongodb.{ Mongo, MongoOptions, ServerAddress MongoServer }
import com.typesafe.config._
import akka.actor._
import play.api.libs.concurrent._
import play.api.Application
import play.api.i18n.Lang
import play.api.i18n.MessagesPlugin
import db._
import ai._
import memo._
import i18n._
import ui._
import lobby.LobbyEnv
import user.UserEnv
import timeline.TimelineEnv
final class SystemEnv private(app: Application, settings: Settings) {
final class SystemEnv private(application: Application, settings: Settings) {
implicit val ctx = app
implicit val app = application
import settings._
lazy val user = new UserEnv(
settings = settings,
mongodb = mongodb)
lazy val i18n = new lila.i18n.I18nEnv(
app = app,
settings = settings)
lazy val lobby = new LobbyEnv(
lazy val user = new lila.user.UserEnv(
settings = settings,
mongodb = mongodb.apply _)
lazy val lobby = new lila.lobby.LobbyEnv(
app = app,
settings = settings,
mongodb = mongodb,
mongodb = mongodb.apply _,
userRepo = user.userRepo,
gameRepo = gameRepo)
gameRepo = game.gameRepo,
gameSocket = game.socket,
gameMessenger = game.messenger,
entryRepo = timeline.entryRepo,
ai = ai.ai)
lazy val timeline = new TimelineEnv(
lazy val setup = new lila.setup.SetupEnv(
settings = settings,
mongodb = mongodb)
mongodb = mongodb.apply _)
lazy val setupFormFactory = new setup.FormFactory(userConfigRepo)
lazy val timeline = new lila.timeline.TimelineEnv(
settings = settings,
mongodb = mongodb.apply _)
lazy val i18nMessagesApi = app.plugin[MessagesPlugin]
.err("this plugin was not registered or disabled")
.api
lazy val ai = new lila.ai.AiEnv(
settings = settings)
lazy val i18nPool = new I18nPool(
langs = Lang.availables.toSet,
default = Lang("en"))
lazy val game = new lila.game.GameEnv(
app = app,
settings = settings,
mongodb = mongodb.apply _,
userRepo = user.userRepo,
eloUpdater = user.eloUpdater,
ai = ai.ai)
lazy val translator = new Translator(
api = i18nMessagesApi,
pool = i18nPool)
lazy val analyse = new lila.analyse.AnalyseEnv(
settings = settings,
gameRepo = game.gameRepo,
userRepo = user.userRepo)
lazy val i18nKeys = new I18nKeys(translator)
lazy val i18nRequestHandler = new I18nRequestHandler(
pool = i18nPool)
lazy val pgnDump = new PgnDump(userRepo = userRepo, gameRepo = gameRepo)
lazy val gameInfo = GameInfo(pgnDump) _
lazy val reporting = Akka.system.actorOf(
Props(new report.Reporting), name = ActorReporting)
lazy val siteHub = Akka.system.actorOf(
Props(new site.Hub(timeout = SiteUidTimeout)), name = ActorSiteHub)
lazy val siteSocket = new site.Socket(hub = siteHub)
lazy val gameHistory = () new game.History(timeout = GameMessageLifetime)
lazy val gameHubMaster = Akka.system.actorOf(Props(new game.HubMaster(
makeHistory = gameHistory,
uidTimeout = GameUidTimeout,
hubTimeout = GameHubTimeout,
playerTimeout = GamePlayerTimeout
)), name = ActorGameHubMaster)
lazy val gameSocket = new game.Socket(
getGame = gameRepo.game,
hand = hand,
hubMaster = gameHubMaster,
messenger = messenger)
lazy val hand = new Hand(
gameRepo = gameRepo,
messenger = messenger,
ai = ai,
finisher = finisher,
takeback = takeback,
hubMaster = gameHubMaster,
moretimeSeconds = MoretimeSeconds)
lazy val site = new lila.site.SiteEnv(
app = app,
settings = settings,
gameRepo = game.gameRepo)
lazy val appApi = new AppApi(
userRepo = userRepo,
gameRepo = gameRepo,
gameSocket = gameSocket,
messenger = messenger,
starter = lobbyEnv.starter,
eloUpdater = eloUpdater,
gameInfo = gameInfo)
lazy val captcha = new Captcha(gameRepo = gameRepo)
lazy val finisher = new Finisher(
userRepo = userRepo,
gameRepo = gameRepo,
messenger = messenger,
eloUpdater = eloUpdater,
eloCalculator = eloCalculator,
finisherLock = finisherLock)
lazy val eloCalculator = new chess.EloCalculator
lazy val finisherLock = new FinisherLock(timeout = FinisherLockTimeout)
lazy val takeback = new Takeback(gameRepo = gameRepo, messenger = messenger)
lazy val messenger = new Messenger(roomRepo = roomRepo)
val ai: () Ai = AiChoice match {
case AiRemote () remoteAi or craftyAi
case AiCrafty () craftyAi
case _ () stupidAi
}
lazy val remoteAi = new RemoteAi(remoteUrl = AiRemoteUrl)
lazy val craftyAi = new CraftyAi(server = craftyServer)
lazy val craftyServer = new CraftyServer(
execPath = AiCraftyExecPath,
bookPath = AiCraftyBookPath)
lazy val stupidAi = new StupidAi
def isAiServer = AiServerMode
lazy val gameRepo = new GameRepo(mongodb(MongoCollectionGame))
lazy val roomRepo = new RoomRepo(mongodb(MongoCollectionRoom))
userRepo = user.userRepo,
gameRepo = game.gameRepo,
gameSocket = game.socket,
messenger = game.messenger,
starter = lobby.starter,
eloUpdater = user.eloUpdater,
gameInfo = analyse.gameInfo)
lazy val mongodb = MongoConnection(
new MongoServer(MongoHost, MongoPort),
@ -158,10 +86,10 @@ final class SystemEnv private(app: Application, settings: Settings) {
}
lazy val gameFinishCommand = new command.GameFinish(
gameRepo = gameRepo,
finisher = finisher)
gameRepo = game.gameRepo,
finisher = game.finisher)
lazy val gameCleanNextCommand = new command.GameCleanNext(gameRepo = gameRepo)
lazy val gameCleanNextCommand = new command.GameCleanNext(gameRepo = game.gameRepo)
}
object SystemEnv {

View file

@ -1,7 +1,8 @@
package lila
package ai
import chess._
import model._
import chess.{ Game, Move }
import game.DbGame
import scalaz.effects._

28
app/ai/AiEnv.scala Normal file
View file

@ -0,0 +1,28 @@
package lila
package ai
import com.mongodb.casbah.MongoCollection
final class AiEnv(
settings: Settings) {
import settings._
val ai: () Ai = AiChoice match {
case AiRemote () remoteAi or craftyAi
case AiCrafty () craftyAi
case _ () stupidAi
}
lazy val remoteAi = new RemoteAi(remoteUrl = AiRemoteUrl)
lazy val craftyAi = new CraftyAi(server = craftyServer)
lazy val craftyServer = new CraftyServer(
execPath = AiCraftyExecPath,
bookPath = AiCraftyBookPath)
lazy val stupidAi = new StupidAi
def isServer = AiServerMode
}

View file

@ -1,8 +1,8 @@
package lila
package ai
import lila.chess.{ Game, Move }
import model._
import chess.{ Game, Move }
import game.DbGame
import java.io.File
import scala.io.Source

View file

@ -1,8 +1,7 @@
package lila
package ai
import lila.chess.{ Game, Move }
import model._
import chess.{ Game, Move }
import java.io.ByteArrayInputStream
import scala.io.Source

View file

@ -1,9 +1,8 @@
package lila
package ai
import lila.chess.{ Game, Move, ReverseEngineering }
import lila.chess.format.Forsyth
import model._
import chess.{ Game, Move, ReverseEngineering, Variant, Chess960 }
import chess.format.Forsyth
trait FenBased {

View file

@ -2,7 +2,7 @@ package lila
package ai
import lila.chess.{ Game, Move }
import model.DbGame
import game.DbGame
import scalaz.effects._
import dispatch._

View file

@ -2,7 +2,7 @@ package lila
package ai
import chess.{ Game, Move }
import model.DbGame
import game.DbGame
import scalaz.effects._

View file

@ -0,0 +1,21 @@
package lila
package analyse
import com.mongodb.casbah.MongoCollection
import game.GameRepo
import user.UserRepo
final class AnalyseEnv(
settings: Settings,
gameRepo: GameRepo,
userRepo: UserRepo) {
import settings._
lazy val pgnDump = new PgnDump(
userRepo = userRepo,
gameRepo = gameRepo)
lazy val gameInfo = GameInfo(pgnDump) _
}

View file

@ -1,8 +1,9 @@
package lila
package analyse
import model.DbGame
import chess.Eco
import chess.format.Forsyth
import game.DbGame
import scalaz.effects.IO

View file

@ -1,8 +1,8 @@
package lila
package analyse
import chess.format.Forsyth
import db.{ GameRepo }
import model.{ DbGame, DbPlayer }
import game.{ DbGame, DbPlayer, GameRepo }
import user.{ User, UserRepo }
import org.joda.time.format.DateTimeFormat

View file

@ -1,8 +1,9 @@
package lila
package command
import db.GameRepo
import game.GameRepo
import scalaz.effects._
import com.mongodb.casbah.Imports._
import org.joda.time.DateTime
import org.scala_tools.time.Imports._

View file

@ -1,7 +1,7 @@
package lila
package command
import db.GameRepo
import game._
import scalaz.effects._
final class GameFinish(gameRepo: GameRepo, finisher: Finisher) {

View file

@ -11,7 +11,7 @@ import play.api.Play.current
object Ai extends LilaController {
private val craftyServer = env.craftyServer
private val craftyServer = env.ai.craftyServer
def run = Action { implicit req
implicit val ctx = Context(req, None)

View file

@ -4,7 +4,7 @@ import lila._
import http.Context
import DataForm._
import chess.Color
import model.{ Event, DbGame }
import game.{ Event, DbGame }
import play.api._
import mvc._
@ -18,11 +18,11 @@ import scalaz.effects._
object App extends LilaController {
private val hand = env.hand
private val hand = env.game.hand
def socket = WebSocket.async[JsValue] { implicit req
implicit val ctx = Context(req, None)
env.siteSocket.join(
env.site.socket.join(
uidOption = get("uid"),
username = get("username"))
}
@ -30,7 +30,7 @@ object App extends LilaController {
def gameSocket(gameId: String, color: String) =
WebSocket.async[JsValue] { implicit req
implicit val ctx = Context(req, None)
env.gameSocket.join(
env.game.socket.join(
uidOption = get("uid"),
username = get("username"),
gameId = gameId,
@ -77,5 +77,5 @@ object App extends LilaController {
}
private def performEvents(fullId: String)(events: List[Event]): IO[Unit] =
env.gameSocket.send(DbGame takeGameId fullId, events)
env.game.socket.send(DbGame takeGameId fullId, events)
}

View file

@ -63,7 +63,7 @@ object AppApi extends LilaController {
}
def captcha = Action {
env.captcha.create.unsafePerformIO.fold(
env.site.captcha.create.unsafePerformIO.fold(
err BadRequest(err.shows),
data JsonOk(Map(
"id" -> data._1,

View file

@ -6,10 +6,10 @@ import play.api.mvc._
object Captcha extends LilaController {
private val captcha = env.captcha
private val captcha = env.site.captcha
def create = Action {
env.captcha.create.unsafePerformIO.fold(
captcha.create.unsafePerformIO.fold(
err BadRequest(err.shows),
data JsonOk(Map(
"id" -> data._1,
@ -20,7 +20,7 @@ object Captcha extends LilaController {
}
def solve(gameId: String) = Action {
env.captcha.solve(gameId).unsafePerformIO.fold(
captcha.solve(gameId).unsafePerformIO.fold(
err BadRequest(err.shows),
moves JsonOk(moves.list)
)

View file

@ -1,7 +1,7 @@
package controllers
import lila._
import model.{ User => UserModel }
import user.{ User => UserModel }
import security.{ AuthConfigImpl, Anonymous }
import http.{ Context, BodyContext, HttpEnvironment }
@ -29,7 +29,7 @@ trait LilaController
implicit val current = env.app
override implicit def lang(implicit req: RequestHeader) =
env.i18nPool.lang(req)
env.i18n.pool.lang(req)
def toJson(map: Map[String, Any]) = Json generate map

View file

@ -14,8 +14,8 @@ import play.api.libs.iteratee._
object Lobby extends LilaController {
private val api = env.lobbyApi
private val preloader = env.lobbyPreloader
private val api = env.lobby.api
private val preloader = env.lobby.preloader
val home = Open { implicit ctx
preloader(
@ -30,7 +30,7 @@ object Lobby extends LilaController {
def socket = WebSocket.async[JsValue] { implicit req
implicit val ctx = Context(req, None)
env.lobbySocket.join(
env.lobby.socket.join(
uidOption = get("uid"),
username = get("username"),
versionOption = getInt("version"),
@ -56,6 +56,6 @@ object Lobby extends LilaController {
}
def chatBan(username: String) = Action {
IOk(env.lobbyMessenger ban username)
IOk(env.lobby.messenger ban username)
}
}

View file

@ -13,24 +13,24 @@ import report.{ GetStatus, GetNbPlaying }
object Report extends LilaController {
val reporting = env.reporting
val reporting = env.site.reporting
implicit val timeout = Timeout(100 millis)
def status = Action {
Async {
(env.reporting ? GetStatus).mapTo[String].asPromise map { Ok(_) }
(reporting ? GetStatus).mapTo[String].asPromise map { Ok(_) }
}
}
def nbPlayers = Action {
Async {
(env.reporting ? GetNbMembers).mapTo[Int].asPromise map { Ok(_) }
(reporting ? GetNbMembers).mapTo[Int].asPromise map { Ok(_) }
}
}
def nbPlaying = Action {
Async {
(env.reporting ? GetNbPlaying).mapTo[Int].asPromise map { Ok(_) }
(reporting ? GetNbPlaying).mapTo[Int].asPromise map { Ok(_) }
}
}
}

View file

@ -7,11 +7,13 @@ import http.BodyContext
object Setting extends LilaController {
private val userRepo = env.user.userRepo
val color = OpenBody { implicit ctx
implicit val req = ctx.body
FormResult[String](colorForm) { name
Ok("ok") withSession {
http.Setting(ctx).color(name)(env.userRepo).unsafePerformIO(req.session)
http.Setting(ctx).color(name)(userRepo).unsafePerformIO(req.session)
}
}
}
@ -20,7 +22,7 @@ object Setting extends LilaController {
implicit val req = ctx.body
FormResult[String](soundForm) { v
Ok("ok") withSession {
http.Setting(ctx).sound(v)(env.userRepo).unsafePerformIO(req.session)
http.Setting(ctx).sound(v)(userRepo).unsafePerformIO(req.session)
}
}
}

View file

@ -6,7 +6,7 @@ import setup._
object Setup extends LilaController {
def forms = env.setupFormFactory
def forms = env.setup.formFactory
val aiForm = Open { implicit ctx
IOk(forms.aiFilled map { html.setup.ai(_) })

View file

@ -1,5 +1,5 @@
package lila
package model
package elo
trait EloRange {

View file

@ -1,7 +1,7 @@
package lila
package model
package game
import chess.{ Game, Color, White, Black, Move, Pos, Piece, Board, Clock, History, Role }
import chess.{ History ChessHistory, Board, Move, Pos, Game, Clock, Status, Color, White, Black, Piece, Started, Aborted, Mate, Stalemate, Draw, Variant }
import chess.format.{ PgnReader, Fen }
import chess.Pos.{ posAt, piotr }
import chess.Role.forsyth
@ -21,7 +21,7 @@ case class DbGame(
positionHashes: String = "",
castles: String = "KQkq",
isRated: Boolean = false,
variant: Variant = Standard,
variant: Variant = Variant.default,
lastMoveTime: Option[Int] = None,
createdAt: Option[DateTime] = None) {
@ -83,7 +83,7 @@ case class DbGame(
)
}
def toChessHistory = History(
def toChessHistory = ChessHistory(
lastMove = lastMove flatMap {
case MoveString(a, b) for (o posAt(a); d posAt(b)) yield (o, d)
case _ None
@ -92,7 +92,7 @@ case class DbGame(
whiteCastleQueenSide = castles contains 'Q',
blackCastleKingSide = castles contains 'k',
blackCastleQueenSide = castles contains 'q',
positionHashes = positionHashes grouped History.hashSize toList
positionHashes = positionHashes grouped ChessHistory.hashSize toList
)
def update(game: Game, move: Move, blur: Boolean = false): Progress = {

View file

@ -1,5 +1,5 @@
package lila
package model
package game
import chess._

View file

@ -1,5 +1,5 @@
package lila
package model
package game
import play.api.libs.json._

View file

@ -1,10 +1,8 @@
package lila
package game
import db._
import model._
import user._
import memo.{ FinisherLock }
import chess.{ Color, White, Black, EloCalculator }
import user.{ UserRepo, EloUpdater }
import chess.{ EloCalculator, Draw, Timeout, Resign, Outoftime, Aborted, Mate, Stalemate, Status, Color, White, Black }
import scalaz.effects._

View file

@ -1,7 +1,7 @@
package lila
package memo
package game
import model.DbGame
import memo.BooleanExpiryMemo
import scalaz.effects._
final class FinisherLock(timeout: Int) extends BooleanExpiryMemo(timeout) {

View file

@ -1,7 +1,5 @@
package lila
package db
import model._
package game
final class GameDiff(a: RawDbGame, b: RawDbGame) {

72
app/game/GameEnv.scala Normal file
View file

@ -0,0 +1,72 @@
package lila
package game
import com.mongodb.casbah.MongoCollection
import akka.actor._
import play.api.libs.concurrent._
import play.api.Application
import play.api.i18n.Lang
import play.api.i18n.MessagesPlugin
import user.{ UserRepo, EloUpdater }
import ai.Ai
final class GameEnv(
app: Application,
settings: Settings,
mongodb: String MongoCollection,
userRepo: UserRepo,
eloUpdater: EloUpdater,
ai: () => Ai) {
implicit val ctx = app
import settings._
lazy val history = () new History(timeout = GameMessageLifetime)
lazy val hubMaster = Akka.system.actorOf(Props(new HubMaster(
makeHistory = history,
uidTimeout = GameUidTimeout,
hubTimeout = GameHubTimeout,
playerTimeout = GamePlayerTimeout
)), name = ActorGameHubMaster)
lazy val socket = new Socket(
getGame = gameRepo.game,
hand = hand,
hubMaster = hubMaster,
messenger = messenger)
lazy val hand = new Hand(
gameRepo = gameRepo,
messenger = messenger,
ai = ai,
finisher = finisher,
takeback = takeback,
hubMaster = hubMaster,
moretimeSeconds = MoretimeSeconds)
lazy val finisher = new Finisher(
userRepo = userRepo,
gameRepo = gameRepo,
messenger = messenger,
eloUpdater = eloUpdater,
eloCalculator = eloCalculator,
finisherLock = finisherLock)
lazy val eloCalculator = new chess.EloCalculator
lazy val finisherLock = new FinisherLock(timeout = FinisherLockTimeout)
lazy val takeback = new Takeback(
gameRepo = gameRepo,
messenger = messenger)
lazy val messenger = new Messenger(roomRepo = roomRepo)
lazy val gameRepo = new GameRepo(mongodb(MongoCollectionGame))
lazy val roomRepo = new RoomRepo(mongodb(MongoCollectionRoom))
}

View file

@ -1,10 +1,9 @@
package lila
package db
package game
import model._
import DbGame._
import chess.Color
import chess.{ Color, Standard, Mate, Started }
import chess.format.Forsyth
import com.novus.salat._

View file

@ -1,10 +1,10 @@
package lila
package game
import ai.Ai
import chess.Role
import chess.Pos.posAt
import model._
import memo._
import db.{ GameRepo }
import chess._
import Pos.posAt
import scalaz.effects._
import akka.actor._
import akka.dispatch.{ Future, Await }

View file

@ -5,7 +5,6 @@ import play.api.libs.json._
import scalaz.effects._
import chess.Color
import model.Event
import memo.Builder
final class History(timeout: Int) {

View file

@ -1,7 +1,6 @@
package lila
package game
import model._
import socket._
import chess.{ Color, White, Black }

View file

@ -1,7 +1,6 @@
package lila
package game
import model._
import socket.{ Broom, Close, GetNbMembers, GetUsernames, NbMembers }
import akka.actor._

View file

@ -1,8 +1,7 @@
package lila
package game
import chess.Color
import model._
import db.{ RoomRepo }
import scalaz.effects._
final class Messenger(roomRepo: RoomRepo) {

View file

@ -1,5 +1,5 @@
package lila
package model
package game
import chess.Color

View file

@ -1,5 +1,5 @@
package lila
package model
package game
// events are kept in insertion/addition order
case class Progress(origin: DbGame, game: DbGame, events: List[Event] = Nil) {

View file

@ -1,5 +1,5 @@
package lila
package model
package game
import chess._
import scala.math.round

View file

@ -1,5 +1,5 @@
package lila
package model
package game
import com.novus.salat.annotations._

View file

@ -1,5 +1,5 @@
package lila
package model
package game
import chess._

View file

@ -1,5 +1,5 @@
package lila
package model
package game
import com.novus.salat.annotations.Key
import org.apache.commons.lang3.StringEscapeUtils.escapeXml

View file

@ -1,7 +1,5 @@
package lila
package db
import model.Room
package game
import com.novus.salat._
import com.novus.salat.dao._

View file

@ -14,9 +14,8 @@ import play.api.Play.current
import scalaz.effects._
import chess.Color
import model.{ DbGame, Pov, PovRef, Progress, Event }
import socket.{ Util, Ping, Quit }
import RichJs._
import implicits.RichJs._
final class Socket(
getGame: String IO[Option[DbGame]],

View file

@ -1,7 +1,5 @@
package lila
import db.GameRepo
import model.{ DbGame, Event, ReloadEvent, Progress }
package game
import scalaz.effects._

View file

@ -2,7 +2,6 @@ package lila
package game
import chess.Color
import model._
import socket.SocketMember
import akka.actor.ActorRef

8
app/game/package.scala Normal file
View file

@ -0,0 +1,8 @@
package lila
import ornicar.scalalib._
package object game {
type ValidIOEvents = Valid[scalaz.effects.IO[List[Event]]]
}

View file

@ -1,7 +1,7 @@
package lila
package http
import model.User
import user.User
import play.api.mvc.{ Request, RequestHeader }

View file

@ -1,7 +1,7 @@
package lila
package http
import model.User
import user.User
import play.api.mvc.RequestHeader
import play.api.mvc.Session
@ -12,5 +12,5 @@ trait HttpEnvironment {
type Req = RequestHeader
type SessionMap = Session => Session
type SessionMap = Session Session
}

View file

@ -2,7 +2,7 @@ package lila
package http
import ui.Color
import db.UserRepo
import user.UserRepo
import scalaz.effects._

30
app/i18n/I18nEnv.scala Normal file
View file

@ -0,0 +1,30 @@
package lila
package i18n
import play.api.Application
import play.api.i18n.Lang
import play.api.i18n.MessagesPlugin
final class I18nEnv(
app: Application,
settings: Settings) {
implicit val ctx = app
import settings._
lazy val messagesApi = app.plugin[MessagesPlugin]
.err("this plugin was not registered or disabled")
.api
lazy val pool = new I18nPool(
langs = Lang.availables.toSet,
default = Lang("en"))
lazy val translator = new Translator(
api = messagesApi,
pool = pool)
lazy val keys = new I18nKeys(translator = translator)
lazy val requestHandler = new I18nRequestHandler(pool = pool)
}

View file

@ -1,4 +1,5 @@
package lila
package implicits
import akka.util.Duration
import akka.util.duration._
@ -12,6 +13,5 @@ object RichDuration {
def randomize(ratio: Float = 0.1f): Duration =
approximatly(0.1f)(d.toMillis) millis
}
}

View file

@ -1,4 +1,5 @@
package lila
package implicits
import play.api.libs.json._

View file

@ -1,21 +1,18 @@
package lila
package lobby
import lila.{ Messenger GameMessenger }
import model._
import memo._
import db._
import lila.chess.Color
import game.{ GameRepo, Socket GameSocket, Messenger GameMessenger }
import chess.Color
import scalaz.effects._
final class Api(
hookRepo: HookRepo,
fisherman: Fisherman,
gameRepo: GameRepo,
gameSocket: game.Socket,
gameSocket: GameSocket,
gameMessenger: GameMessenger,
starter: Starter,
lobbySocket: lobby.Socket) {
starter: Starter) {
def cancel(ownerId: String): IO[Unit] = for {
hook hookRepo ownedHook ownerId

View file

@ -1,9 +1,7 @@
package lila
package lobby
import db.HookRepo
import memo.HookMemo
import model.{ Hook, DbGame }
import game.DbGame
import scalaz.effects._

View file

@ -1,5 +1,8 @@
package lila
package model
package lobby
import chess.{ Variant, Mode }
import elo.EloRange
import com.novus.salat.annotations.Key
import com.mongodb.DBRef
@ -22,9 +25,9 @@ case class Hook(
def gameId: Option[String] = game map (_.getId.toString)
def realVariant = Variant(variant) | Standard
def realVariant = Variant orDefault variant
def realMode = Mode(mode) | Casual
def realMode = Mode orDefault mode
def render = Map(
"id" -> id,

View file

@ -1,5 +1,7 @@
package lila
package memo
package lobby
import memo.BooleanExpiryMemo
// keys = ownerId
final class HookMemo(timeout: Int) extends BooleanExpiryMemo(timeout)

View file

@ -1,7 +1,5 @@
package lila
package db
import model.Hook
package lobby
import com.novus.salat._
import com.novus.salat.dao._

View file

@ -3,7 +3,6 @@ package lobby
import com.mongodb.casbah.MongoCollection
import com.typesafe.config._
import akka.actor._
import play.api.libs.concurrent._
@ -11,12 +10,21 @@ import play.api.Application
import play.api.i18n.Lang
import play.api.i18n.MessagesPlugin
import user.UserRepo
import game.{ GameRepo, Socket GameSocket, Messenger GameMessenger }
import timeline.EntryRepo
import ai.Ai
final class LobbyEnv(
app: Application,
settings: Settings,
mongodb: String => MongoCollection,
userRepo: UserRepo,
gameRepo: GameRepo)
app: Application,
settings: Settings,
mongodb: String MongoCollection,
userRepo: UserRepo,
gameRepo: GameRepo,
gameSocket: GameSocket,
gameMessenger: GameMessenger,
entryRepo: EntryRepo,
ai: () Ai) {
implicit val ctx = app
import settings._
@ -63,20 +71,10 @@ final class LobbyEnv(
fisherman = fisherman,
gameRepo = gameRepo,
gameSocket = gameSocket,
gameMessenger = messenger,
starter = starter,
lobbySocket = socket)
gameMessenger = gameMessenger,
starter = starter)
lazy val hookRepo = new HookRepo(mongodb(MongoCollectionHook))
lazy val hookMemo = new HookMemo(timeout = MemoHookTimeout)
lazy val userConfigRepo = new setup.UserConfigRepo(
collection = mongodb(MongoCollectionConfig))
lazy val entryRepo = new EntryRepo(
collection = mongodb(MongoCollectionEntry),
max = LobbyEntryMax)
lazy val historyRepo = new HistoryRepo(mongodb(MongoCollectionHistory))
}

View file

@ -1,7 +1,7 @@
package lila
package lobby
import db.CappedRepo
import mongodb.CappedRepo
import com.mongodb.casbah.MongoCollection
import com.mongodb.casbah.Imports._
import scalaz.effects._

View file

@ -1,8 +1,7 @@
package lila
package lobby
import db.UserRepo
import model.User
import user.{ UserRepo, User }
import scalaz.effects._
import org.apache.commons.lang3.StringEscapeUtils.escapeXml

View file

@ -1,9 +1,9 @@
package lila
package lobby
import model._
import memo._
import db._
import timeline.EntryRepo
import game.GameRepo
import scalaz.effects._
final class Preload(

View file

@ -10,8 +10,10 @@ import play.api.libs.iteratee._
import play.api.libs.concurrent._
import scalaz.effects._
import RichJs._
import implicits.RichJs._
import socket.{ Util, Ping, Quit }
import timeline.Entry
import game.DbGame
final class Socket(hub: ActorRef) {
@ -45,19 +47,19 @@ final class Socket(hub: ActorRef) {
promise | Util.connectionFail
}
def addEntry(entry: model.Entry): IO[Unit] = io {
def addEntry(entry: Entry): IO[Unit] = io {
hub ! AddEntry(entry)
}
def removeHook(hook: model.Hook): IO[Unit] = io {
def removeHook(hook: Hook): IO[Unit] = io {
hub ! RemoveHook(hook)
}
def addHook(hook: model.Hook): IO[Unit] = io {
def addHook(hook: Hook): IO[Unit] = io {
hub ! AddHook(hook)
}
def biteHook(hook: model.Hook, game: model.DbGame): IO[Unit] = io {
def biteHook(hook: Hook, game: DbGame): IO[Unit] = io {
hub ! BiteHook(hook, game)
}
}

View file

@ -1,9 +1,11 @@
package lila
package lobby
import model.{ DbGame, Standard, Progress }
import db.{ GameRepo }
import timeline._
import chess.Standard
import timeline.{ EntryRepo, Entry }
import game.{ GameRepo, DbGame, Progress }
import ai.Ai
import scalaz.effects._
final class Starter(

View file

@ -2,6 +2,8 @@ package lila
package lobby
import socket.SocketMember
import timeline.Entry
import game.DbGame
import scalaz.effects.IO
@ -10,14 +12,14 @@ case class Member(
username: Option[String],
hookOwnerId: Option[String]) extends SocketMember {
def ownsHook(hook: model.Hook) = Some(hook.ownerId) == hookOwnerId
def ownsHook(hook: Hook) = Some(hook.ownerId) == hookOwnerId
}
case class WithHooks(op: Iterable[String] => IO[Unit])
case class AddHook(hook: model.Hook)
case class RemoveHook(hook: model.Hook)
case class BiteHook(hook: model.Hook, game: model.DbGame)
case class AddEntry(entry: model.Entry)
case class AddHook(hook: Hook)
case class RemoveHook(hook: Hook)
case class BiteHook(hook: Hook, game: DbGame)
case class AddEntry(entry: Entry)
case class Join(
uid: String,
username: Option[String],

View file

@ -1,5 +1,5 @@
package lila
package db
package mongodb
import com.mongodb.casbah.MongoCollection
import com.mongodb.casbah.Imports._

View file

@ -24,8 +24,6 @@ package object lila
object Tick // standard actor tick
type ValidIOEvents = Valid[scalaz.effects.IO[List[model.Event]]]
// custom salat context
implicit val ctx = new Context {
val name = "Lila System Context"

View file

@ -53,12 +53,12 @@ final class Reporting extends Actor {
case Update(env) {
val before = nowMillis
Future.sequence(List(
(env.siteHub ? GetNbMembers).mapTo[Int],
(env.lobbyHub ? GetNbMembers).mapTo[Int],
(env.gameHubMaster ? GetNbHubs).mapTo[Int],
(env.gameHubMaster ? GetNbMembers).mapTo[Int],
Future(env.gameRepo.countAll.unsafePerformIO),
Future(env.gameRepo.countPlaying.unsafePerformIO)
(env.site.hub ? GetNbMembers).mapTo[Int],
(env.lobby.hub ? GetNbMembers).mapTo[Int],
(env.game.hubMaster ? GetNbHubs).mapTo[Int],
(env.game.hubMaster ? GetNbMembers).mapTo[Int],
Future(env.game.gameRepo.countAll.unsafePerformIO),
Future(env.game.gameRepo.countPlaying.unsafePerformIO)
)) onSuccess {
case List(
siteMembers,
@ -76,7 +76,7 @@ final class Reporting extends Actor {
loadAvg = osStats.getSystemLoadAverage.toFloat
nbThreads = threadStats.getThreadCount
memory = memoryStats.getHeapMemoryUsage.getUsed / 1024 / 1024
remoteAi = env.remoteAi.currentHealth
remoteAi = env.ai.remoteAi.currentHealth
display()
}

View file

@ -23,7 +23,7 @@ trait AuthConfigImpl extends AuthConfig {
type Id = String
type User = model.User
type User = user.User
type Authority = Permission
@ -31,7 +31,7 @@ trait AuthConfigImpl extends AuthConfig {
val sessionTimeoutInSeconds: Int = 3600
def resolveUser(id: Id): Option[User] = (env.userRepo byUsername id).unsafePerformIO
def resolveUser(id: Id): Option[User] = (env.user.userRepo byUsername id).unsafePerformIO
def logoutSucceeded[A](request: Request[A]): PlainResult =
Redirect(routes.Lobby.home)
@ -52,5 +52,5 @@ trait AuthConfigImpl extends AuthConfig {
Permission(user.roles) contains authority
def authenticateUser(username: String, password: String): Option[User] =
env.userRepo.authenticate(username, password).unsafePerformIO
env.user.userRepo.authenticate(username, password).unsafePerformIO
}

View file

@ -1,7 +1,8 @@
package lila
package setup
import model.{ Variant, Standard, Mode, EloRange }
import chess.{ Variant, Standard, Mode }
import elo.EloRange
case class AiConfig(variant: Variant, level: Int, color: Color) extends Config {

View file

@ -1,7 +1,8 @@
package lila
package setup
import model.{ Variant, Standard, Mode, EloRange }
import chess.{ Variant, Standard, Mode }
import elo.EloRange
trait Config {

15
app/setup/SetupEnv.scala Normal file
View file

@ -0,0 +1,15 @@
package lila
package setup
import com.mongodb.casbah.MongoCollection
final class SetupEnv(
settings: Settings,
mongodb: String MongoCollection) {
import settings._
lazy val configRepo = new UserConfigRepo(mongodb(MongoCollectionConfig))
lazy val formFactory = new FormFactory(configRepo)
}

View file

@ -1,7 +1,7 @@
package lila
package setup
import model.User
import user.User
import com.novus.salat.annotations.Key

View file

@ -1,7 +1,7 @@
package lila
package setup
import model.User
import user.User
import com.novus.salat._
import com.novus.salat.dao._

View file

@ -1,7 +1,7 @@
package lila
package site
import db._
import model._
import game._
import chess.{ Game, Color }
import chess.format.{ Forsyth, PgnReader }
import scalaz.effects._

28
app/site/SiteEnv.scala Normal file
View file

@ -0,0 +1,28 @@
package lila
package site
import akka.actor._
import play.api.libs.concurrent._
import play.api.Application
import report.Reporting
import game.GameRepo
final class SiteEnv(
app: Application,
settings: Settings,
gameRepo: GameRepo) {
implicit val ctx = app
import settings._
lazy val reporting = Akka.system.actorOf(
Props(new Reporting), name = ActorReporting)
lazy val hub = Akka.system.actorOf(
Props(new Hub(timeout = SiteUidTimeout)), name = ActorSiteHub)
lazy val socket = new Socket(hub = hub)
lazy val captcha = new Captcha(gameRepo = gameRepo)
}

View file

@ -10,7 +10,7 @@ import play.api.libs.iteratee._
import play.api.libs.concurrent._
import scalaz.effects._
import RichJs._
import implicits.RichJs._
import socket.{ Util, Ping, Quit }
final class Socket(hub: ActorRef) {

View file

@ -12,9 +12,9 @@ import play.api.mvc.RequestHeader
trait I18nHelper {
private val pool = env.i18nPool
private val pool = env.i18n.pool
val trans = env.i18nKeys
val trans = env.i18n.keys
implicit def lang(implicit ctx: Context) = pool lang ctx.req

View file

@ -1,6 +1,8 @@
package lila
package timeline
import game.DbGame
import com.novus.salat.annotations._
import com.mongodb.BasicDBList

View file

@ -1,7 +1,7 @@
package lila
package timeline
import db.CappedRepo
import mongodb.CappedRepo
import com.mongodb.casbah.MongoCollection
import com.mongodb.casbah.Imports._

View file

@ -1,5 +1,4 @@
package lila
package model
package lila.chess
sealed abstract class Mode(val id: Int)
@ -13,4 +12,8 @@ object Mode {
val byId = all map { v (v.id, v) } toMap
def apply(id: Int): Option[Mode] = byId get id
val default = Casual
def orDefault(id: Int): Mode = apply(id) | default
}

View file

@ -1,5 +1,4 @@
package lila
package model
package lila.chess
sealed abstract class Status(val id: Int) extends Ordered[Status] {
@ -8,7 +7,7 @@ sealed abstract class Status(val id: Int) extends Ordered[Status] {
case object Created extends Status(10)
case object Started extends Status(20)
case object Aborted extends Status(25)
case object Aborted extends Status(25) // from this point the game is finished
case object Mate extends Status(30)
case object Resign extends Status(31)
case object Stalemate extends Status(32)

View file

@ -1,5 +1,4 @@
package lila
package model
package lila.chess
sealed abstract class Variant(val id: Int) {
@ -19,7 +18,11 @@ object Variant {
val byId = all map { v (v.id, v) } toMap
val default = Standard
def apply(id: Int): Option[Variant] = byId get id
def orDefault(id: Int): Variant = apply(id) | default
def exists(id: Int): Boolean = byId contains id
}

View file

@ -61,7 +61,8 @@ object ApplicationBuild extends Build with Resolvers with Dependencies {
auth,
plugins),
templatesImport ++= Seq(
"lila.model._",
"lila.game.{ DbGame, DbPlayer }",
"lila.user.User",
"lila.templating.Environment._",
"lila.ui.SiteMenu",
"lila.http.Context"),