diff --git a/app/actors/LobbieActor.scala b/app/actors/LobbieActor.scala index e01a0d0..a67d2f3 100644 --- a/app/actors/LobbieActor.scala +++ b/app/actors/LobbieActor.scala @@ -1,6 +1,6 @@ package actors -import actors.UserActor.{GetName, HostLeaveLobby, LobbyFatal, RefreshLobbyInfo, SecondPlayerLeaveLobby, SetUserAsHost, SetUserAsObs, SetUserAsSecondPlayer} +import actors.UserActor.{BanMapMessage, GetName, HostLeaveLobby, LobbyFatal, Message, RefreshLobbyInfo, SecondPlayerLeaveLobby, SendBanMapMessage, SendMessage, SetUserAsHost, SetUserAsObs, SetUserAsSecondPlayer} import akka.actor.{Actor, ActorLogging, ActorRef} import akka.event.LoggingReceive import com.typesafe.scalalogging.LazyLogging @@ -65,20 +65,35 @@ class LobbieActor(hostUser: LobbyUser) extends Actor with LazyLogging { case BanMap(mapName: String) => // notify watchers logger.info(s"Ban map $mapName by ${sender.path.name}") + if(status == Draft()){ if((playerTurn == 1 && sender == host.actorRef) || (playerTurn == 2 && secondPlayer.exists(_.actorRef == sender))){ - mapsLobby.find(p => p.map == mapName).foreach(_.isBanned = true) - if (playerTurn== 1) playerTurn = 2 else playerTurn = 1 - if(mapsLobby.count(_.isBanned == false) == 1){ - status = Finish() + mapsLobby.find(p => p.map == mapName) match { + case Some(map) => + if(!map.isBanned){ + map.isBanned = true + if (playerTurn== 1) playerTurn = 2 else playerTurn = 1 + if(mapsLobby.count(_.isBanned == false) == 1){ + status = Finish() + } + users.foreach(_ ! RefreshLobbyInfo(getLobbyInfoResponse)) + + val senderName: String = if (sender == host.actorRef) { + host.name + } else secondPlayer.get.name + users.foreach(_ ! SendBanMapMessage(BanMapMessage(senderName, mapName))) + } else { + logger.warn(s"User ban map $mapName, but map already banned") + } + case None => + logger.error(s"Map $mapName not exist") } - users.foreach(_ ! RefreshLobbyInfo(getLobbyInfoResponse)) } else{ logger.warn(s"Player ${sender.path.name} ban map, but turn is $playerTurn") } } else { - logger.warn(s"Player ${sender.path.name} ban map, but it is '$status' status") + logger.warn(s"Player ${sender.path.name} ban map, but lobby status is '$status' status") } case SetReady => // notify watchers @@ -112,6 +127,13 @@ class LobbieActor(hostUser: LobbyUser) extends Actor with LazyLogging { secondPlayer = None users.foreach(_ ! RefreshLobbyInfo(getLobbyInfoResponse)) } + + case MessageForLobby(message) => + if (sender() == host.actorRef) { + users.foreach(_ ! SendMessage(Message(host.name, message))) + }else if (secondPlayer.exists(sp => sp.actorRef == sender())){ + users.foreach(_ ! SendMessage(Message(secondPlayer.get.name, message))) + } case JoinLobbyAsPlayer(sp) => logger.info(s"User ${sender.path.name} join lobby ${self.path.name} as player") if (secondPlayer.isEmpty) { @@ -177,6 +199,8 @@ case object SetReady case object SetNotReady +case class MessageForLobby(message: String) + case object InfoQuery case class UserInfo(name: String, isReady: Boolean) diff --git a/app/actors/UserActor.scala b/app/actors/UserActor.scala index 6ea30a6..194f6fb 100644 --- a/app/actors/UserActor.scala +++ b/app/actors/UserActor.scala @@ -1,6 +1,6 @@ package actors -import actors.UserActor.{GetName, HostLeaveLobby, LobbyFatal, RefreshLobbyInfo, SecondPlayerLeaveLobby, SetUserAsHost, SetUserAsObs, SetUserAsSecondPlayer} +import actors.UserActor.{BanMapMessage, GetName, HostLeaveLobby, LobbyFatal, Message, RefreshLobbyInfo, SecondPlayerLeaveLobby, SendBanMapMessage, SendMessage, SetUserAsHost, SetUserAsObs, SetUserAsSecondPlayer} import akka.actor._ import akka.event.LoggingReceive import akka.pattern.ask @@ -33,6 +33,10 @@ class UserActor(out: ActorRef, implicit val lobbyWrites: OWrites[LobbyInfo] = Json.writes[LobbyInfo] + implicit val messageWrites: OWrites[Message] = Json.writes[Message] + + implicit val messageBanMapWrites: OWrites[BanMapMessage] = Json.writes[BanMapMessage] + implicit val lobbyResponseWrites: Writes[List[LobbyInfo]] = new Writes[List[LobbyInfo]] { override def writes(o: List[LobbyInfo]): JsValue = { @@ -84,6 +88,14 @@ class UserActor(out: ActorRef, logger.trace(s"Refresh lobby info: $lobbyInfo") out ! Json.obj("type" -> "refreshLobby", "lobby" -> lobbyInfo) + case SendMessage(message) => + logger.debug(s"Send message $message") + out ! Json.obj("type" -> "sendMessage", "message" -> message) + + case SendBanMapMessage(mapBanMessage) => + logger.debug(s"Send ban map message $mapBanMessage") + out ! Json.obj("type" -> "sendMapBanMessage", "message" -> mapBanMessage) + case LobbyFatal(message) => // После этого сообщения выход из лобби logger.warn(s"Lobby error: $message") out ! Json.obj("type" -> "lobbyError", "error" -> message) @@ -119,6 +131,10 @@ class UserActor(out: ActorRef, case Some("setNotReady") => lobbieActor.foreach(lobby => lobby ! SetNotReady) + case Some("sendMessage") => + val message = (json \ "message").as[String] + lobbieActor.foreach(lobby => lobby ! MessageForLobby(message)) + case Some("kickSecondPlayer") => lobbieActor.foreach(lobby => lobby ! KickSecondPlayer) @@ -186,6 +202,12 @@ object UserActor { case object GetName + case class Message(userName: String, message: String) + case class SendMessage(message: Message) + + case class BanMapMessage(user: String, mapTechName: String) + case class SendBanMapMessage(message: BanMapMessage) + case class RefreshLobbyInfo(lobbyInfo: LobbyInfo) case class SetUserAsHost(lobbyInfo: LobbyInfo) diff --git a/app/assets/javascripts/index.js b/app/assets/javascripts/index.js index 84323e4..cf7d230 100644 --- a/app/assets/javascripts/index.js +++ b/app/assets/javascripts/index.js @@ -88,12 +88,15 @@ window.onload = function() { })); }); - $("#getAllUsers").click(function(event) { - event.preventDefault(); - ws.send(JSON.stringify({ - type: "getLobbies" - })); + $("#submitmsg").click(function(event) { + sendMessage(); }); + $("#usermsg").on('keyup', function (e) { + if (e.key === 'Enter' || e.keyCode === 13) { + sendMessage() + } + }); + $("#exit").click(function(event) { event.preventDefault(); @@ -129,13 +132,23 @@ window.onload = function() { switchToLobby(message.lobby.maps); renderPlayersAndStats(message.lobby); break; + case "sendMessage": + console.log(message); + addMessageToChat(message.message); + break; + case "sendMapBanMessage": + console.log(message); + addBanMapMessageToChat(message.message); + break; case "lobbyError": console.log(message); disconnectLobby(message.error); + break; case "lobbies": lobbyList.lobbies = message.lobbies; lobbyList.render(); return console.log(message); + break; default: } }; @@ -173,11 +186,14 @@ function switchToLobby(maps) { console.log(maps); renderMaps(maps); $("#lobbies").hide(); + $(".navbar").hide(); $("#decider").show(); + $("#chatbox").html(""); } function disconnectLobby(error) { $("#decider").hide(); + $(".navbar").show(); $("#lobbies").show(); alert(error); } @@ -241,23 +257,29 @@ function renderPlayersAndStats(lobby) { } } + if (lobby.user1Info.name === userName || lobby.user2Info.name === userName) { + $("#inputMsg").show(); + } else { + $("#inputMsg").hide(); + } + switch (lobby.status){ case "NotStarted()": - resHtml = "
" + lobby.user1Info.name + ": " + player1ReadyBtn +"
" + resHtml = "
" + lobby.user1Info.name + ": " + player1ReadyBtn +"

" if(lobby.user2Info.name !== ""){ var kickBtn = "" if(lobby.user1Info.name === userName){ - kickBtn = ""; + kickBtn = " - "; } - resHtml += "
" + lobby.user2Info.name + ": " + player2ReadyBtn + "
" + kickBtn + "
" + resHtml += "
" + lobby.user2Info.name + ": " + player2ReadyBtn + kickBtn + "
" }else{ - resHtml += "
waiting 2-nd player...
" + resHtml += "
waiting 2-nd player...
" } break; case "Draft()": console.log(lobby.turn); var playerTurn = (lobby.playerTurn === 1) ? lobby.user1Info.name : lobby.user2Info.name - resHtml = "
"+lobby.user1Info.name + " vs " + lobby.user2Info.name +"
" + playerTurn +" turn
"; + resHtml = "
"+lobby.user1Info.name + " vs " + lobby.user2Info.name +"
" + playerTurn +" turn
"; break; case "Finish()": var lastMap = _.find(lobby.maps, function (map){ @@ -271,6 +293,20 @@ function renderPlayersAndStats(lobby) { $("#playersStatsList").html(resHtml); } +function addMessageToChat(message){ + var messageHtml = "
" + message.userName + ": " + message.message + "
"; + var chatBox = $("#chatbox"); + chatBox.append(messageHtml); + chatBox.scrollTop(40000); +} + +function addBanMapMessageToChat(message){ + var messageHtml = "
" + convertMapName(message.mapTechName) + " banned by " + message.user + "
"; + var chatBox = $("#chatbox"); + chatBox.append(messageHtml); + chatBox.scrollTop(40000); +} + function banMap(map){ ws.send(JSON.stringify({ type: "banMap", @@ -304,6 +340,18 @@ function observerDecider(actorName){ })); } +function sendMessage(){ + var userInput = $("#usermsg"); + var message = userInput.val(); + userInput.val(""); + if(message !== ""){ + ws.send(JSON.stringify({ + type: "sendMessage", + message: message + })); + } +} + function kickSecondPlayer(){ ws.send(JSON.stringify({ type: "kickSecondPlayer" diff --git a/app/assets/stylesheets/main.less b/app/assets/stylesheets/main.less index 6ee35d2..ff9ca46 100644 --- a/app/assets/stylesheets/main.less +++ b/app/assets/stylesheets/main.less @@ -17,7 +17,7 @@ } -body { +#lobbies { margin-top: 50px; } @@ -89,10 +89,10 @@ body { } .mapSelect{ - margin: 10px; + margin: 4px; position:relative; width: 175px; - height: 175px; + height: 155px; white-space: nowrap; overflow: hidden; } @@ -112,58 +112,34 @@ body { animation: glowing 1300ms infinite; } -.chart-holder, .details-holder { - position: absolute; +#chat{ + width: 354px; + float: right; +} + +#chatbox { + text-align:left; + margin:0 auto; + margin-bottom:3px; + padding:10px; + background:#fff; + height:200px; + width:352px; + border:1px solid #ACD8F0; + overflow:auto; } + +.inputMsg{ width: 100%; - height: 250px; - top: 0px; - left: 0px; - - -webkit-backface-visibility: hidden; - -moz-backface-visibility: hidden; - backface-visibility: hidden; } -.chart-holder { - z-index: 2; - & p { - position: absolute; - bottom: 7px; - right: 20px; - font-size: 10px; - color: #aaaaaa; - font-style: italic; - } +#usermsg { + border: 1px solid #ACD8F0; + width: 300px; } -.details-holder { - .transform(180deg); - text-align: center; - z-index: 1; - & h4 { - padding: 20px; - } - & .progress { - padding: 20px; - background: none; - border: none; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; - } - & img { - height: 128px; - width: 128px; - } -} +#submit { width: 60px; } -.chart { - position: relative; - width: 920px; - height: 210px; - margin-top: 30px; - margin-bottom: 10px; - margin-left: 10px; - margin-right: 10px; -} \ No newline at end of file +.error { color: #ff0000; } + +#menu { padding:12.5px 25px 12.5px 25px; } diff --git a/app/views/index.scala.html b/app/views/index.scala.html index 6de79d7..1e82942 100644 --- a/app/views/index.scala.html +++ b/app/views/index.scala.html @@ -38,6 +38,16 @@
+
+
+
+ +
+ + +
+
+