1.1 --- a/src/main/scala/net/inapt/tilescape/comet/Chat.scala Sun Mar 29 23:16:41 2009 +0300
1.2 +++ b/src/main/scala/net/inapt/tilescape/comet/Chat.scala Wed Apr 01 22:00:38 2009 +0300
1.3 @@ -43,6 +43,9 @@
1.4
1.5 private lazy val infoId = uniqueId + "_info"
1.6
1.7 + private lazy val user = {
1.8 + User.currentUser.open_!
1.9 + }
1.10 private lazy val server = {
1.11 val ret = ChatServer
1.12 ret ! ChatServerAdd(this)
2.1 --- a/src/main/scala/net/inapt/tilescape/comet/GameActor.scala Sun Mar 29 23:16:41 2009 +0300
2.2 +++ b/src/main/scala/net/inapt/tilescape/comet/GameActor.scala Wed Apr 01 22:00:38 2009 +0300
2.3 @@ -29,8 +29,13 @@
2.4
2.5 private lazy val usersId = uniqueId + "_users"
2.6 private lazy val gamesId = uniqueId + "_games"
2.7 + private lazy val statusId = uniqueId + "_status"
2.8 + private lazy val errorId = "game_errors"
2.9
2.10 - lazy val user = User.currentUser.open_!
2.11 +
2.12 + private var _user : User = _
2.13 +
2.14 + def user = _user
2.15
2.16 private lazy val server = {
2.17 val ret = GameServer
2.18 @@ -46,9 +51,27 @@
2.19 partialUpdate(AppendHtml(usersId, userLine(u)))
2.20 case AnnounceNewGame(g) =>
2.21 partialUpdate(AppendHtml(gamesId, gameLine(g)))
2.22 - Log.info("There is new game "+g)
2.23 + sendChatMessage(g.chatRoom, user.email.is+" created new game '"+g.name+"'")
2.24 + updateStatus
2.25 + case AnnounceNewPlayer(g, user) =>
2.26 + sendChatMessage(g.chatRoom, user.email.is+" joined '"+g.name+"'")
2.27 + updateStatus
2.28 + case AnnounceLeftPlayer(g, user) =>
2.29 + sendChatMessage(g.chatRoom, user.email.is+" left '"+g.name+"'")
2.30 + updateStatus
2.31 + case GameServerError(msg) =>
2.32 + partialUpdate(SetHtml(errorId, <div id="error">{msg}</div>))
2.33 }
2.34
2.35 + private def updateStatus {
2.36 + partialUpdate(SetHtml(statusId, gameStatus))
2.37 + }
2.38 +
2.39 + private def sendChatMessage(name : String, msg: String) {
2.40 + Log.info("Sending message "+msg+" to chat server")
2.41 + ChatServer ! ChatServerMsg(name, msg)
2.42 + }
2.43 +
2.44 private def invocationFunction(s : String) = "tilescapeReceiveServerMessage('"+urlEncode(s)+"')"
2.45
2.46 override lazy val fixedRender: Box[NodeSeq] = {
2.47 @@ -58,14 +81,21 @@
2.48 override def render = {
2.49 bind("userList" -> userList,
2.50 "gameList" -> gameList,
2.51 - "create" -> a(Text("Create game")) {
2.52 - Log.info("Create pressed")
2.53 - server ! CreateGame(this, "Test game")
2.54 - Noop
2.55 - }
2.56 - )
2.57 + "status" -> gameStatus,
2.58 + "create" -> a(Text("Create game")) {
2.59 + server ! CreateGame(this, "Test game")
2.60 + Noop
2.61 + }
2.62 + )
2.63 }
2.64
2.65 + private def gameStatus = {
2.66 + user.currentGame match {
2.67 + case Some(game) =>
2.68 + <span id={statusId}>You are playing {game} {a("(Leave)"){ jsLeaveGame(game) } }</span>
2.69 + case None => <span id={statusId}>You are not currently playing.</span>
2.70 + }
2.71 + }
2.72 private def userList = {
2.73 server !? GetUserList match {
2.74 case g : UserList =>
2.75 @@ -82,20 +112,31 @@
2.76 }
2.77 }
2.78
2.79 - private def gameLine(game : Game) = (<li>{game.name}</li>)
2.80 + private def gameLine(game : Game) = (
2.81 + <li>{a(Text(game.name)) {jsJoinGame(game)}}</li>
2.82 + )
2.83
2.84 override def localSetup() {
2.85 - user.register(this)
2.86 + User.currentUser match {
2.87 + case Full(x) => _user = x
2.88 + case _ =>
2.89 + }
2.90 super.localSetup()
2.91 }
2.92
2.93 override def localShutdown() {
2.94 GameServer ! GameServerRemove(this)
2.95 - user.unregister(this)
2.96 super.localShutdown()
2.97 }
2.98 + private def errorToJS(e : GameServerError) = {
2.99 + AppendHtml(errorId, Text(e.msg))
2.100 + }
2.101
2.102 def jsSendMessage(msg: String) = { sendMessage(msg); Noop }
2.103
2.104 def sendMessage(msg: String) = server ! GameServerMsg(this, msg.trim)
2.105 +
2.106 + def jsJoinGame(game : Game) = { server ! JoinGame(this, game) ; Noop }
2.107 +
2.108 + def jsLeaveGame(game : Game) = { server ! LeaveGame(this, game) ; Noop }
2.109 }
2.110 \ No newline at end of file
3.1 --- a/src/main/scala/net/inapt/tilescape/comet/GameServer.scala Sun Mar 29 23:16:41 2009 +0300
3.2 +++ b/src/main/scala/net/inapt/tilescape/comet/GameServer.scala Wed Apr 01 22:00:38 2009 +0300
3.3 @@ -27,7 +27,6 @@
3.4 val m = GameMessage(sender, msg)
3.5 messages ::= m
3.6 listeners.foreach (_ ! GameServerUpdate(List(m)))
3.7 - Log.info("Passing message "+msg)
3.8
3.9 case GetUserList =>
3.10 reply(UserList(listeners.map(_.user)))
3.11 @@ -36,9 +35,28 @@
3.12 reply(GameList(games))
3.13
3.14 case CreateGame(sender, name) =>
3.15 - val g = new Game(name, new ClientRuleSet, sender.user)
3.16 - games ::= g
3.17 - listeners.foreach (_ ! AnnounceNewGame(g))
3.18 + if (sender.user.isPlaying) {
3.19 + sender ! GameServerError("You are already in game")
3.20 + } else {
3.21 + val g = new Game(name, new ClientRuleSet, sender.user)
3.22 + sender.user.register(g)
3.23 + games ::= g
3.24 + listeners.foreach (_ ! AnnounceNewGame(g))
3.25 + }
3.26 +
3.27 + case JoinGame(sender, game) =>
3.28 + if (sender.user.isPlaying) {
3.29 + sender ! GameServerError("You are already in game")
3.30 + } else {
3.31 + game.join(sender.user)
3.32 + sender.user.register(game)
3.33 + listeners.foreach (_ ! AnnounceNewPlayer(game, sender.user))
3.34 + }
3.35 +
3.36 + case LeaveGame(sender, game) =>
3.37 + game.leave(sender.user)
3.38 + sender.user.unregister(game)
3.39 + listeners.foreach (_ ! AnnounceLeftPlayer(game, sender.user) )
3.40
3.41 case GameServerAdd(me) =>
3.42 me ! GameServerUpdate(messages)
3.43 @@ -55,6 +73,7 @@
3.44 this.start
3.45 }
3.46
3.47 +case class GameServerError(msg: String)
3.48 case class GameMessage(sender : Actor, msg: String)
3.49 case class GameServerMsg(sender: GameActor, msg: String)
3.50 case class GameServerUpdate(msg: List[GameMessage])
3.51 @@ -67,6 +86,8 @@
3.52 case class GetGameList
3.53 case class CreateGame(sender : GameActor, name : String)
3.54 case class AnnounceNewGame(game : Game)
3.55 +case class AnnounceNewPlayer(game : Game, user : User)
3.56 +case class AnnounceLeftPlayer(game : Game, user : User)
3.57 case class JoinGame(sender : GameActor, game: Game)
3.58 case class LeaveGame(sender : GameActor, game: Game)
3.59
4.1 --- a/src/main/scala/net/inapt/tilescape/model/Game.scala Sun Mar 29 23:16:41 2009 +0300
4.2 +++ b/src/main/scala/net/inapt/tilescape/model/Game.scala Wed Apr 01 22:00:38 2009 +0300
4.3 @@ -28,6 +28,7 @@
4.4 class Game (val name : String, val ruleset : RuleSet, var initiator : User) {
4.5 private var players = List[User]()
4.6 private var status = GameStatus.PreGame
4.7 + val chatRoom = "game"
4.8
4.9 def join(player : User) { players ::= player }
4.10
5.1 --- a/src/main/scala/net/inapt/tilescape/model/User.scala Sun Mar 29 23:16:41 2009 +0300
5.2 +++ b/src/main/scala/net/inapt/tilescape/model/User.scala Wed Apr 01 22:00:38 2009 +0300
5.3 @@ -4,6 +4,8 @@
5.4 import _root_.net.liftweb.util._
5.5
5.6 import net.inapt.tilescape.comet.GameActor
5.7 +import net.inapt.tilescape.comet.Chat
5.8 +import net.inapt.tilescape.comet.ChatLine
5.9
5.10 /**
5.11 * The singleton that has methods for accessing the database
5.12 @@ -26,10 +28,20 @@
5.13 class User extends MegaProtoUser[User] {
5.14 def getSingleton = User // what's the "meta" server
5.15
5.16 - private var games = List[GameActor]()
5.17 + private var game : Option[Game] = None
5.18
5.19 - def register(game : GameActor) { games ::= game }
5.20 + private var chats = List[Chat]()
5.21
5.22 - def unregister(game : GameActor) { games -= game }
5.23 + def register(g : Game) {
5.24 + Log.info("Registering "+game+" to "+this)
5.25 + game = Full(g)
5.26 + }
5.27
5.28 -}
5.29 + def currentGame = game
5.30 +
5.31 + def isPlaying = ! game.isEmpty
5.32 +
5.33 + def unregister(g : Game) {
5.34 + game = None
5.35 + }
5.36 +}
5.37 \ No newline at end of file
6.1 --- a/src/main/webapp/game.html Sun Mar 29 23:16:41 2009 +0300
6.2 +++ b/src/main/webapp/game.html Wed Apr 01 22:00:38 2009 +0300
6.3 @@ -1,5 +1,6 @@
6.4 <lift:surround with="default" at="content">
6.5 <body>
6.6 + <div id="game_errors"></div>
6.7 <div class="widget">
6.8 <lift:Util.in>
6.9 <center><b>Chat</b></center><br />
6.10 @@ -12,6 +13,9 @@
6.11 <lift:Util.in>
6.12 <lift:comet type="GameActor">
6.13 <div>
6.14 + <game:status>Here should be game status</game:status>
6.15 + </div>
6.16 + <div>
6.17 <b>Users online</b>
6.18 <game:userList>Here should be userlist</game:userList>
6.19 </div>