This commit is contained in:
Anibus 2020-11-29 03:13:10 +03:00
parent ec519889dc
commit 460e95c824
5 changed files with 149 additions and 69 deletions

View File

@ -1,6 +1,6 @@
package actors 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.actor.{Actor, ActorLogging, ActorRef}
import akka.event.LoggingReceive import akka.event.LoggingReceive
import com.typesafe.scalalogging.LazyLogging import com.typesafe.scalalogging.LazyLogging
@ -65,20 +65,35 @@ class LobbieActor(hostUser: LobbyUser) extends Actor with LazyLogging {
case BanMap(mapName: String) => case BanMap(mapName: String) =>
// notify watchers // notify watchers
logger.info(s"Ban map $mapName by ${sender.path.name}") logger.info(s"Ban map $mapName by ${sender.path.name}")
if(status == Draft()){ if(status == Draft()){
if((playerTurn == 1 && sender == host.actorRef) || if((playerTurn == 1 && sender == host.actorRef) ||
(playerTurn == 2 && secondPlayer.exists(_.actorRef == sender))){ (playerTurn == 2 && secondPlayer.exists(_.actorRef == sender))){
mapsLobby.find(p => p.map == mapName).foreach(_.isBanned = true) mapsLobby.find(p => p.map == mapName) match {
if (playerTurn== 1) playerTurn = 2 else playerTurn = 1 case Some(map) =>
if(mapsLobby.count(_.isBanned == false) == 1){ if(!map.isBanned){
status = Finish() 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{ } else{
logger.warn(s"Player ${sender.path.name} ban map, but turn is $playerTurn") logger.warn(s"Player ${sender.path.name} ban map, but turn is $playerTurn")
} }
} else { } 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 => case SetReady =>
// notify watchers // notify watchers
@ -112,6 +127,13 @@ class LobbieActor(hostUser: LobbyUser) extends Actor with LazyLogging {
secondPlayer = None secondPlayer = None
users.foreach(_ ! RefreshLobbyInfo(getLobbyInfoResponse)) 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) => case JoinLobbyAsPlayer(sp) =>
logger.info(s"User ${sender.path.name} join lobby ${self.path.name} as player") logger.info(s"User ${sender.path.name} join lobby ${self.path.name} as player")
if (secondPlayer.isEmpty) { if (secondPlayer.isEmpty) {
@ -177,6 +199,8 @@ case object SetReady
case object SetNotReady case object SetNotReady
case class MessageForLobby(message: String)
case object InfoQuery case object InfoQuery
case class UserInfo(name: String, isReady: Boolean) case class UserInfo(name: String, isReady: Boolean)

View File

@ -1,6 +1,6 @@
package actors 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.actor._
import akka.event.LoggingReceive import akka.event.LoggingReceive
import akka.pattern.ask import akka.pattern.ask
@ -33,6 +33,10 @@ class UserActor(out: ActorRef,
implicit val lobbyWrites: OWrites[LobbyInfo] = Json.writes[LobbyInfo] 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]] { implicit val lobbyResponseWrites: Writes[List[LobbyInfo]] = new Writes[List[LobbyInfo]] {
override def writes(o: List[LobbyInfo]): JsValue = { override def writes(o: List[LobbyInfo]): JsValue = {
@ -84,6 +88,14 @@ class UserActor(out: ActorRef,
logger.trace(s"Refresh lobby info: $lobbyInfo") logger.trace(s"Refresh lobby info: $lobbyInfo")
out ! Json.obj("type" -> "refreshLobby", "lobby" -> 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) => // После этого сообщения выход из лобби case LobbyFatal(message) => // После этого сообщения выход из лобби
logger.warn(s"Lobby error: $message") logger.warn(s"Lobby error: $message")
out ! Json.obj("type" -> "lobbyError", "error" -> message) out ! Json.obj("type" -> "lobbyError", "error" -> message)
@ -119,6 +131,10 @@ class UserActor(out: ActorRef,
case Some("setNotReady") => case Some("setNotReady") =>
lobbieActor.foreach(lobby => lobby ! SetNotReady) lobbieActor.foreach(lobby => lobby ! SetNotReady)
case Some("sendMessage") =>
val message = (json \ "message").as[String]
lobbieActor.foreach(lobby => lobby ! MessageForLobby(message))
case Some("kickSecondPlayer") => case Some("kickSecondPlayer") =>
lobbieActor.foreach(lobby => lobby ! KickSecondPlayer) lobbieActor.foreach(lobby => lobby ! KickSecondPlayer)
@ -186,6 +202,12 @@ object UserActor {
case object GetName 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 RefreshLobbyInfo(lobbyInfo: LobbyInfo)
case class SetUserAsHost(lobbyInfo: LobbyInfo) case class SetUserAsHost(lobbyInfo: LobbyInfo)

View File

@ -88,12 +88,15 @@ window.onload = function() {
})); }));
}); });
$("#getAllUsers").click(function(event) { $("#submitmsg").click(function(event) {
event.preventDefault(); sendMessage();
ws.send(JSON.stringify({
type: "getLobbies"
}));
}); });
$("#usermsg").on('keyup', function (e) {
if (e.key === 'Enter' || e.keyCode === 13) {
sendMessage()
}
});
$("#exit").click(function(event) { $("#exit").click(function(event) {
event.preventDefault(); event.preventDefault();
@ -129,13 +132,23 @@ window.onload = function() {
switchToLobby(message.lobby.maps); switchToLobby(message.lobby.maps);
renderPlayersAndStats(message.lobby); renderPlayersAndStats(message.lobby);
break; break;
case "sendMessage":
console.log(message);
addMessageToChat(message.message);
break;
case "sendMapBanMessage":
console.log(message);
addBanMapMessageToChat(message.message);
break;
case "lobbyError": case "lobbyError":
console.log(message); console.log(message);
disconnectLobby(message.error); disconnectLobby(message.error);
break;
case "lobbies": case "lobbies":
lobbyList.lobbies = message.lobbies; lobbyList.lobbies = message.lobbies;
lobbyList.render(); lobbyList.render();
return console.log(message); return console.log(message);
break;
default: default:
} }
}; };
@ -173,11 +186,14 @@ function switchToLobby(maps) {
console.log(maps); console.log(maps);
renderMaps(maps); renderMaps(maps);
$("#lobbies").hide(); $("#lobbies").hide();
$(".navbar").hide();
$("#decider").show(); $("#decider").show();
$("#chatbox").html("");
} }
function disconnectLobby(error) { function disconnectLobby(error) {
$("#decider").hide(); $("#decider").hide();
$(".navbar").show();
$("#lobbies").show(); $("#lobbies").show();
alert(error); 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){ switch (lobby.status){
case "NotStarted()": case "NotStarted()":
resHtml = "<div style='float: left'>" + lobby.user1Info.name + ": " + player1ReadyBtn +"</div>" resHtml = "<div style='float: left; padding-top: 10px;'> <div>" + lobby.user1Info.name + ": " + player1ReadyBtn +"</div><br/>"
if(lobby.user2Info.name !== ""){ if(lobby.user2Info.name !== ""){
var kickBtn = "" var kickBtn = ""
if(lobby.user1Info.name === userName){ if(lobby.user1Info.name === userName){
kickBtn = "<button class='btn btn-danger' onclick='kickSecondPlayer()'>Kick</button>"; kickBtn = " - <button class='btn btn-danger' onclick='kickSecondPlayer()'>Kick</button>";
} }
resHtml += "<div style='float: right'>" + lobby.user2Info.name + ": " + player2ReadyBtn + "<br/>" + kickBtn + "</div>" resHtml += "<div>" + lobby.user2Info.name + ": " + player2ReadyBtn + kickBtn + "</div>"
}else{ }else{
resHtml += "<div style='float: right'>waiting 2-nd player...</div>" resHtml += "<div>waiting 2-nd player...</div></div>"
} }
break; break;
case "Draft()": case "Draft()":
console.log(lobby.turn); console.log(lobby.turn);
var playerTurn = (lobby.playerTurn === 1) ? lobby.user1Info.name : lobby.user2Info.name var playerTurn = (lobby.playerTurn === 1) ? lobby.user1Info.name : lobby.user2Info.name
resHtml = "<center><b>"+lobby.user1Info.name + " vs " + lobby.user2Info.name +"</b><br/>" + playerTurn +" turn</center>"; resHtml = "<center>"+lobby.user1Info.name + " vs " + lobby.user2Info.name +"<br/><b>" + playerTurn +"</b> turn</center>";
break; break;
case "Finish()": case "Finish()":
var lastMap = _.find(lobby.maps, function (map){ var lastMap = _.find(lobby.maps, function (map){
@ -271,6 +293,20 @@ function renderPlayersAndStats(lobby) {
$("#playersStatsList").html(resHtml); $("#playersStatsList").html(resHtml);
} }
function addMessageToChat(message){
var messageHtml = "<div class='msgln'> <b>" + message.userName + "</b>: " + message.message + "<br></div>";
var chatBox = $("#chatbox");
chatBox.append(messageHtml);
chatBox.scrollTop(40000);
}
function addBanMapMessageToChat(message){
var messageHtml = "<div class='msgln'><span style='color: #2C3D9B'>" + convertMapName(message.mapTechName) + "</span> banned by " + message.user + "<br></div>";
var chatBox = $("#chatbox");
chatBox.append(messageHtml);
chatBox.scrollTop(40000);
}
function banMap(map){ function banMap(map){
ws.send(JSON.stringify({ ws.send(JSON.stringify({
type: "banMap", 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(){ function kickSecondPlayer(){
ws.send(JSON.stringify({ ws.send(JSON.stringify({
type: "kickSecondPlayer" type: "kickSecondPlayer"

View File

@ -17,7 +17,7 @@
} }
body { #lobbies {
margin-top: 50px; margin-top: 50px;
} }
@ -89,10 +89,10 @@ body {
} }
.mapSelect{ .mapSelect{
margin: 10px; margin: 4px;
position:relative; position:relative;
width: 175px; width: 175px;
height: 175px; height: 155px;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
} }
@ -112,58 +112,34 @@ body {
animation: glowing 1300ms infinite; animation: glowing 1300ms infinite;
} }
.chart-holder, .details-holder { #chat{
position: absolute; 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%; width: 100%;
height: 250px;
top: 0px;
left: 0px;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
backface-visibility: hidden;
} }
.chart-holder { #usermsg {
z-index: 2; border: 1px solid #ACD8F0;
& p { width: 300px;
position: absolute;
bottom: 7px;
right: 20px;
font-size: 10px;
color: #aaaaaa;
font-style: italic;
}
} }
.details-holder {
.transform(180deg);
text-align: center;
z-index: 1;
& h4 {
padding: 20px;
}
& .progress {
padding: 20px;
background: none;
border: none;
-webkit-box-shadow: none; #submit { width: 60px; }
-moz-box-shadow: none;
box-shadow: none;
}
& img {
height: 128px;
width: 128px;
}
}
.chart { .error { color: #ff0000; }
position: relative;
width: 920px; #menu { padding:12.5px 25px 12.5px 25px; }
height: 210px;
margin-top: 30px;
margin-bottom: 10px;
margin-left: 10px;
margin-right: 10px;
}

View File

@ -38,6 +38,16 @@
<div id = "mapList"></div> <div id = "mapList"></div>
<div style="clear: both"></div> <div style="clear: both"></div>
<div id = "playersStatsList"></div> <div id = "playersStatsList"></div>
<div id="chat">
<div id="chatbox">
</div>
<div id = "inputMsg">
<input autocomplete="off" type="text" id="usermsg" />
<button type="submit" id="submitmsg" >Send</button>
</div>
</div>
</div> </div>
</div> </div>