2022-10-05 23:22:08 +03:00

260 lines
8.6 KiB
Scala
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package actors
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
import akka.util.Timeout
import com.typesafe.scalalogging.LazyLogging
import play.api.libs.json._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.DurationInt
import scala.util.{Failure, Success}
class UserActor(out: ActorRef,
userParentActor: ActorRef,
ip: String) extends Actor with LazyLogging {
implicit val timeout: Timeout = 3.seconds
val ipAddress: String = ip
var lobbieActor: Option[ActorRef] = None
implicit val mapJson: Writes[DeciderMap] = new Writes[DeciderMap] {
def writes(deciderMap: DeciderMap): JsValue = {
Json.obj(
"map" -> deciderMap.map,
"description" -> deciderMap.description,
"isBanned" -> deciderMap.isBanned
)
}
}
implicit val selectedRacesWrites: OWrites[SelectedRaces] = Json.writes[SelectedRaces]
implicit val userInfoWrites: OWrites[UserInfo] = Json.writes[UserInfo]
implicit val lobbyWrites: Writes[LobbyInfo] = new Writes[LobbyInfo]{
override def writes(lobby: LobbyInfo) = Json.obj(
"user1Info" -> lobby.user1Info,
"user2Info" -> lobby.user2Info,
"lobbyActorName" -> lobby.lobbyActorName,
"deciderName" -> lobby.deciderName,
"status" -> lobby.status,
"playerTurn" -> lobby.playerTurn,
"selectedType" -> lobby.selectedType,
"maps" -> Json.toJson(lobby.maps)
)
}
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 = {
JsArray(o.map(lobby => Json.obj(
"user1Info" -> lobby.user1Info,
"user2Info" -> lobby.user2Info,
"lobbyActorName" -> lobby.lobbyActorName,
"deciderName" -> lobby.deciderName,
"status" -> lobby.status,
"playerTurn" -> lobby.playerTurn,
"selectedType" -> lobby.selectedType,
"maps" -> Json.toJson(lobby.maps)
)))
}
}
var name = ""
override def preStart(): Unit = {
super.preStart()
configureDefaultStocks()
}
def configureDefaultStocks(): Unit = {
logger.info(s"Creating user actor")
}
override def receive: Receive = LoggingReceive {
case GetName =>
sender ! name
case SetUserAsHost(lobbyInfo) =>
val lobbyActor = sender()
logger.info(s"Receive set user ${self.path.name} as host from ${lobbyActor.path.name}")
setUserAsJoinedOrCreatedLobby(lobbyActor, lobbyInfo)
case SetUserAsSecondPlayer(lobbyInfo) =>
val lobbyActor = sender()
logger.info(s"Receive set user ${self.path.name} as second player from ${lobbyActor.path.name}")
setUserAsJoinedOrCreatedLobby(lobbyActor, lobbyInfo)
case SetUserAsObs(lobbyInfo) =>
val lobbyActor = sender()
logger.info(s"Receive set user ${self.path.name} as second player from ${lobbyActor.path.name}")
setUserAsJoinedOrCreatedLobby(lobbyActor, lobbyInfo)
case HostLeaveLobby =>
logger.info(s"Host leave from lobby ${sender.path.name}")
out ! Json.obj("type" -> "lobbyError", "error" -> "Host leave lobby")
case SecondPlayerLeaveLobby =>
logger.info(s"Second player lobby ${sender.path.name}")
out ! Json.obj("type" -> "lobbyError", "error" -> "Second player leave lobby")
case RefreshLobbyInfo(lobbyInfo) =>
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)
case json: JsValue =>
// Обрабатываем запросы с фронта
val comType = (json \ "type").asOpt[String]
comType match {
case Some("userName") =>
name = (json \ "name").as[String]
logger.debug(s"Set user name: $name for actor ${this.self}")
case Some("createDecider") =>
val deciderName = (json \ "deciderName").as[String]
LobbiesActor.actor ! CreateLobby(name, deciderName)
case Some("leaveDecider") =>
lobbieActor.foreach(lobby => lobby ! LeaveLobby)
case Some("setReady") =>
lobbieActor.foreach(lobby => lobby ! SetReady)
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("changeLobbyType") =>
val lobbyType = (json \ "lobbyType").as[String]
lobbieActor.foreach(lobby => lobby ! ChangeLobbyType(lobbyType))
case Some("kickSecondPlayer") =>
lobbieActor.foreach(lobby => lobby ! KickSecondPlayer)
case Some("joinDecider") =>
val lobbyActorName = (json \ "lobbyActorName").as[String]
logger.info(s"Player ${self.path.name} join lobby $lobbyActorName")
LobbiesActor.actor ! JoinLobbyByActorName(lobbyActorName, name)
case Some("observerDecider") =>
val lobbyActorName = (json \ "lobbyActorName").as[String]
logger.info(s"Player ${self.path.name} observe lobby $lobbyActorName")
LobbiesActor.actor ! ObserveLobbyByActorName(lobbyActorName)
case Some("banMap") =>
val map = (json \ "map").as[String]
lobbieActor.foreach(lobby => lobby ! BanMap(map))
case Some("selectRace") =>
val firstRace = (json \ "raceFirst").as[Int]
val secondRace = (json \ "raceSecond").as[Int]
val thirdRace = (json \ "raceThird").as[Int]
lobbieActor.foreach(lobby => lobby ! SelectedRaces(firstRace, secondRace, thirdRace))
case Some("getLobbies") =>
logger.debug("Get all lobby request")
(LobbiesActor.actor ? GetAllLobbies).mapTo[List[RefreshLobbyInfo]] onComplete {
case Success(lobbies) => {
logger.debug(s"Received lobbies: $lobbies")
out ! Json.obj("type" -> "lobbies", "lobbies" -> lobbies.map(res => res.lobbyInfo))
}
case Failure(ex) => logger.error("Received error", ex)
}
case Some(value) =>
logger.error(s"Command '$value' not expected")
case None =>
logger.error(s"Field 'type' should be specified in incoming json'")
}
}
private def setUserAsJoinedOrCreatedLobby(lobbyActor: ActorRef, lobbyInfo: LobbyInfo): Unit = {
this.lobbieActor = Some(lobbyActor)
out ! Json.obj("type" -> "switchToLobby", "lobby" -> lobbyInfo)
}
}
class UserParentActor(actorSystem: ActorSystem) extends Actor with ActorLogging {
import UserParentActor._
override def receive: Receive = LoggingReceive {
case Create(id, ipAddress, out) =>
val child: ActorRef = actorSystem.actorOf(Props(classOf[UserActor], out, self, ipAddress), s"userActor-$id")
sender() ! child
case GetAllUsers =>
System.out.print("12123" + context.children)
sender() ! context.children
}
}
object UserParentActor {
case class Create(id: String, ipAddress: String, out: ActorRef)
case object GetAllUsers
}
object UserActor {
trait Factory {
// Corresponds to the @Assisted parameters defined in the constructor
def apply(out: ActorRef): Actor
}
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)
case class SetUserAsSecondPlayer(lobbyInfo: LobbyInfo)
case class SetUserAsObs(lobbyInfo: LobbyInfo)
case class LobbyFatal(message: String)
case object CreateLobby
case object HostLeaveLobby
case object SecondPlayerLeaveLobby
}