diff --git a/build.sbt b/build.sbt index 53846e6..35210c3 100644 --- a/build.sbt +++ b/build.sbt @@ -40,8 +40,8 @@ lazy val knockoutwhistweb = project.in(file("knockoutwhistweb")) libraryDependencies += "de.mkammerer" % "argon2-jvm" % "2.12", libraryDependencies += "com.auth0" % "java-jwt" % "4.5.0", libraryDependencies += "com.github.ben-manes.caffeine" % "caffeine" % "3.2.3", - libraryDependencies += "tools.jackson.module" %% "jackson-module-scala" % "3.0.2", - JsEngineKeys.engineType := JsEngineKeys.EngineType.Node + libraryDependencies += "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.16.1", + //JsEngineKeys.engineType := JsEngineKeys.EngineType.Node ) lazy val root = (project in file(".")) diff --git a/knockoutwhistweb/app/logic/game/GameLobby.scala b/knockoutwhistweb/app/logic/game/GameLobby.scala index 0da9376..2bcdc7f 100644 --- a/knockoutwhistweb/app/logic/game/GameLobby.scala +++ b/knockoutwhistweb/app/logic/game/GameLobby.scala @@ -2,7 +2,7 @@ package logic.game import de.knockoutwhist.cards.{Hand, Suit} import de.knockoutwhist.control.GameLogic -import de.knockoutwhist.control.GameState.{Lobby, MainMenu} +import de.knockoutwhist.control.GameState.{InGame, Lobby, MainMenu} import de.knockoutwhist.control.controllerBaseImpl.sublogic.util.{MatchUtil, PlayerUtil} import de.knockoutwhist.events.global.{GameStateChangeEvent, SessionClosed} import de.knockoutwhist.events.player.PlayerEvent @@ -59,6 +59,9 @@ class GameLobby private( if (event.oldState == MainMenu && event.newState == Lobby) { return } + if (event.oldState == Lobby && event.newState == InGame) { + println("RECEIVED GAMESTATEEVENT") + } users.values.foreach(session => session.updatePlayer(event)) case event: SimpleEvent => users.values.foreach(session => session.updatePlayer(event)) @@ -71,6 +74,7 @@ class GameLobby private( * @param user the user who wants to start the game. */ def startGame(user: User): Unit = { + println("STARTED GAME IN LOGIC") val sessionOpt = users.get(user.id) if (sessionOpt.isEmpty) { throw new NotInThisGameException("You are not in this game!") diff --git a/knockoutwhistweb/app/model/sessions/UserSession.scala b/knockoutwhistweb/app/model/sessions/UserSession.scala index c98e384..f66e405 100644 --- a/knockoutwhistweb/app/model/sessions/UserSession.scala +++ b/knockoutwhistweb/app/model/sessions/UserSession.scala @@ -2,9 +2,11 @@ package model.sessions import de.knockoutwhist.events.player.{RequestCardEvent, RequestTieChoiceEvent, RequestTrumpSuitEvent} import de.knockoutwhist.utils.events.SimpleEvent +import logic.PodManager import logic.game.GameLobby import model.users.User -import play.api.libs.json.JsObject +import play.api.libs.json.Format.GenericFormat +import play.api.libs.json.{JsError, JsObject, JsResult, JsSuccess, JsValue} import java.util.UUID import java.util.concurrent.locks.ReentrantLock @@ -26,7 +28,7 @@ class UserSession(val user: User, val host: Boolean, val gameLobby: GameLobby) e else canInteract = Some(InteractionType.Card) case _ => } - websocketActor.foreach(_.transmitEventToClient(event)) + websocketActor.foreach(_.transmitEventToClient(event, gameLobby)) } override def id: UUID = user.id @@ -44,6 +46,21 @@ class UserSession(val user: User, val host: Boolean, val gameLobby: GameLobby) e case "Ping" => // No action needed for Ping () + case "Start Game" => + println("INSIDE HANDLE WEB RESPONSE" + data) + val gameId: String = (data \ "gameId").get.toString + val cleanGameId: String = gameId.replaceAll("^[\"']|[\"']$", "") + val user: JsObject = (data \ "user").asOpt[JsObject].get + val gameLobby: GameLobby = PodManager.getGame(cleanGameId).get + val realUser: JsResult[User] = user.validate[User] + val uu: User = realUser match { + case JsSuccess(extractedUser, _) => + extractedUser + case e: JsError => + println("FAILED" + JsError.toJson(e).toString()) + throw new Exception("Failed to deserialize User object: " + JsError.toJson(e).toString()) + } + gameLobby.startGame(uu) } } lock.unlock() diff --git a/knockoutwhistweb/app/model/users/User.scala b/knockoutwhistweb/app/model/users/User.scala index f418618..a07fd5b 100644 --- a/knockoutwhistweb/app/model/users/User.scala +++ b/knockoutwhistweb/app/model/users/User.scala @@ -1,5 +1,7 @@ package model.users +import play.api.libs.json.{Format, Json} + import java.util.UUID case class User( @@ -16,5 +18,7 @@ case class User( private def withPasswordHash(newPasswordHash: String): User = { this.copy(passwordHash = newPasswordHash) } - } +object User { + implicit val userFormat: Format[User] = Json.format[User] +} \ No newline at end of file diff --git a/knockoutwhistweb/app/util/WebsocketEventMapper.scala b/knockoutwhistweb/app/util/WebsocketEventMapper.scala index 50f8f3e..518b5d8 100644 --- a/knockoutwhistweb/app/util/WebsocketEventMapper.scala +++ b/knockoutwhistweb/app/util/WebsocketEventMapper.scala @@ -27,6 +27,10 @@ object WebsocketEventMapper { registerCustomMapper(ReceivedHandEventMapper) registerCustomMapper(GameStateEventMapper) registerCustomMapper(CardPlayedEventMapper) + registerCustomMapper(NewRoundEventMapper) + registerCustomMapper(NewTrickEventMapper) + registerCustomMapper(TrickEndEventMapper) + registerCustomMapper(RequestCardEventMapper) registerCustomMapper(LobbyUpdateEventMapper) registerCustomMapper(LeftEventMapper) registerCustomMapper(KickEventMapper) diff --git a/knockoutwhistweb/app/util/mapper/GameStateChangeEventMapper.scala b/knockoutwhistweb/app/util/mapper/GameStateChangeEventMapper.scala new file mode 100644 index 0000000..e42d4a2 --- /dev/null +++ b/knockoutwhistweb/app/util/mapper/GameStateChangeEventMapper.scala @@ -0,0 +1,18 @@ +package util.mapper + +import de.knockoutwhist.events.global.GameStateChangeEvent +import logic.game.GameLobby +import play.api.libs.json.{JsObject, Json} + +object GameStateChangeEventMapper extends SimpleEventMapper[GameStateChangeEvent]{ + override def id: String = "GameStateChangeEvent" + + override def toJson(event: GameStateChangeEvent, gameLobby: GameLobby): JsObject = { + println("CALLED toJSON FOR GAMESTATECHANGE") + Json.obj( + "oldState" -> event.oldState.toString, + "newState" -> event.newState.toString, + "gameLobby" -> gameLobby.id + ) + } +} diff --git a/knockoutwhistweb/app/util/mapper/NewRoundEventMapper.scala b/knockoutwhistweb/app/util/mapper/NewRoundEventMapper.scala new file mode 100644 index 0000000..b7be5ea --- /dev/null +++ b/knockoutwhistweb/app/util/mapper/NewRoundEventMapper.scala @@ -0,0 +1,16 @@ +package util.mapper + +import de.knockoutwhist.events.global.NewRoundEvent +import logic.game.GameLobby +import play.api.libs.json.{JsObject, Json} + +object NewRoundEventMapper extends SimpleEventMapper[NewRoundEvent]{ + override def id: String = "NewRoundEvent" + + override def toJson(event: NewRoundEvent, gameLobby: GameLobby): JsObject = { + Json.obj( + "trumpsuit" -> gameLobby.getLogic.getCurrentRound.get.trumpSuit.toString, + "players" -> gameLobby.getLogic.getCurrentMatch.get.playersIn.map(player => player.toString) + ) + } +} diff --git a/knockoutwhistweb/app/util/mapper/NewTrickEventMapper.scala b/knockoutwhistweb/app/util/mapper/NewTrickEventMapper.scala new file mode 100644 index 0000000..863c75d --- /dev/null +++ b/knockoutwhistweb/app/util/mapper/NewTrickEventMapper.scala @@ -0,0 +1,13 @@ +package util.mapper + +import de.knockoutwhist.events.global.NewTrickEvent +import logic.game.GameLobby +import play.api.libs.json.{JsObject, Json} + +object NewTrickEventMapper extends SimpleEventMapper[NewTrickEvent]{ + override def id: String = "NewTrickEvent" + + override def toJson(event: NewTrickEvent, gameLobby: GameLobby): JsObject = { + Json.obj() + } +} diff --git a/knockoutwhistweb/app/util/mapper/RequestCardEventMapper.scala b/knockoutwhistweb/app/util/mapper/RequestCardEventMapper.scala new file mode 100644 index 0000000..8b193cf --- /dev/null +++ b/knockoutwhistweb/app/util/mapper/RequestCardEventMapper.scala @@ -0,0 +1,15 @@ +package util.mapper + +import de.knockoutwhist.events.player.RequestCardEvent +import logic.game.GameLobby +import play.api.libs.json.{JsObject, Json} + +object RequestCardEventMapper extends SimpleEventMapper[RequestCardEvent]{ + override def id: String = "RequestCardEvent" + + override def toJson(event: RequestCardEvent, gameLobby: GameLobby): JsObject = { + Json.obj( + "player" -> event.player.name + ) + } +} diff --git a/knockoutwhistweb/app/util/mapper/TrickEndEventMapper.scala b/knockoutwhistweb/app/util/mapper/TrickEndEventMapper.scala new file mode 100644 index 0000000..9e6e1f7 --- /dev/null +++ b/knockoutwhistweb/app/util/mapper/TrickEndEventMapper.scala @@ -0,0 +1,18 @@ +package util.mapper + +import de.knockoutwhist.events.global.TrickEndEvent +import de.knockoutwhist.rounds.Trick +import logic.game.GameLobby +import play.api.libs.json.{JsObject, Json} + +object TrickEndEventMapper extends SimpleEventMapper[TrickEndEvent]{ + override def id: String = "TrickEndEvent" + + override def toJson(event: TrickEndEvent, gameLobby: GameLobby): JsObject = { + Json.obj( + "playerwon" -> event.winner.name, + "playersin" -> gameLobby.getLogic.getCurrentMatch.get.playersIn.map(player => player.name), + "tricklist" -> gameLobby.getLogic.getCurrentRound.get.tricklist.map(trick => trick.winner.map(player => player.name).getOrElse("Trick in Progress")) + ) + } +} diff --git a/knockoutwhistweb/app/views/lobby/lobby.scala.html b/knockoutwhistweb/app/views/lobby/lobby.scala.html index 66c4390..0d522b6 100644 --- a/knockoutwhistweb/app/views/lobby/lobby.scala.html +++ b/knockoutwhistweb/app/views/lobby/lobby.scala.html @@ -69,7 +69,7 @@ }
+ `;
+
+ firstCardContainer.html(newHtml);
+}
+function requestCardEvent(eventData) {
+ const player = eventData.player;
+ const handElement = $('#card-slide')
+ handElement.removeClass('inactive');
+}
+//alertMessage("It worked!")
+
function receiveGameStateChange(eventData) {
const content = eventData.content;
@@ -218,6 +340,10 @@ function receiveTurnEvent(eventData) {
onEvent("ReceivedHandEvent", receiveHandEvent)
onEvent("GameStateChangeEvent", receiveGameStateChange)
+onEvent("NewRoundEvent", newRoundEvent)
+onEvent("TrickEndEvent", trickEndEvent)
+onEvent("NewTrickEvent", newTrickEvent)
+onEvent("RequestCardEvent", requestCardEvent)
onEvent("CardPlayedEvent", receiveCardPlayedEvent)
onEvent("LobbyUpdateEvent", receiveLobbyUpdateEvent)
onEvent("LeftEvent", receiveGameStateChange)
diff --git a/knockoutwhistweb/public/javascripts/interact.js b/knockoutwhistweb/public/javascripts/interact.js
index 555634e..7e8ace5 100644
--- a/knockoutwhistweb/public/javascripts/interact.js
+++ b/knockoutwhistweb/public/javascripts/interact.js
@@ -5,6 +5,19 @@ function handlePlayCard(card, dog) {
function handleSkipDogLife(button) {
// TODO needs implementation
}
+function startGame(gameId, userId, username, userpasswordhash, userinternalid) {
+ const userpayload = {
+ internalId: userinternalid,
+ id: userId,
+ name: username,
+ passwordHash: userpasswordhash
+ }
+ const payload = {
+ gameId: gameId,
+ user: userpayload
+ };
+ sendEvent("Start Game", payload)
+}
function handleKickPlayer(playerId) {
// TODO needs implementation
}