196 lines
6.0 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.{GetName, HostLeaveLobby, LobbyFatal, RefreshLobbyInfo, SecondPlayerLeaveLobby, SetUserAsHost, 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,
lobbiesActor: ActorRef) extends Actor with LazyLogging {
implicit val timeout: Timeout = 3.seconds
var lobbieActor: Option[ActorRef] = None
implicit val mapJson: Writes[DeciderMap] = new Writes[DeciderMap] {
def writes(deciderMap: DeciderMap): JsValue = {
Json.obj(
"map" -> deciderMap.map,
"isBanned" -> deciderMap.isBanned
)
}
}
implicit val userInfoWrites: OWrites[UserInfo] = Json.writes[UserInfo]
implicit val lobbyWrites: OWrites[LobbyInfo] = Json.writes[LobbyInfo]
implicit val lobbyResponseWrites: Writes[List[LobbyInfo]] = new Writes[List[LobbyInfo]] {
override def writes(o: List[LobbyInfo]): JsValue = {
JsArray(o.map(lobby => Json.toJson(lobby)))
}
}
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 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 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("getAllUsers") =>
val userActorsFuture = (userParentActor ? UserParentActor.GetAllUsers).mapTo[Iterable[ActorRef]]
userActorsFuture.map(actorRefs => {
logger.debug(s"There are ${actorRefs.size} users on site")
actorRefs.map(userActorRef => userActorRef ? GetName).map(res => {
res.onComplete {
case Success(name) => logger.debug(s"There is $name on site")
}
})
})
case Some("createDecider") =>
lobbiesActor ! CreateLobby(name)
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("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 ! JoinLobbyByActorName(lobbyActorName, name)
case Some("banMap") =>
val map = (json \ "map").as[String]
lobbieActor.foreach(lobby => lobby ! BanMap(map))
case Some("getLobbies") =>
logger.debug("Get all lobby request")
(lobbiesActor ? GetAllLobbies).mapTo[List[RefreshLobbyInfo]] onComplete {
case Success(lobbies) => {
logger.info(s"Received lobbies: $lobbies")
out ! Json.obj("type" -> "lobbies", "lobbies" -> lobbies.map(res => res.lobbyInfo))
}
case Failure(ex) => logger.error("Received error", ex)
}
}
}
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, out, lobbiesActor) =>
val child: ActorRef = actorSystem.actorOf(Props(classOf[UserActor], out, self, lobbiesActor), s"userActor-$id")
sender() ! child
case GetAllUsers =>
sender() ! context.children
}
}
object UserParentActor {
case class Create(id: String, out: ActorRef, lobbiesActor: 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 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
}