feat(game)!: Add winner display and return to lobby functionality
This commit is contained in:
@@ -1,14 +1,16 @@
|
||||
package controllers
|
||||
|
||||
import auth.{AuthAction, AuthenticatedRequest}
|
||||
import de.knockoutwhist.control.GameState.{InGame, Lobby, SelectTrump, TieBreak}
|
||||
import de.knockoutwhist.control.GameState.{FinishedMatch, InGame, Lobby, SelectTrump, TieBreak}
|
||||
import exceptions.*
|
||||
import logic.PodManager
|
||||
import logic.game.GameLobby
|
||||
import model.sessions.UserSession
|
||||
import model.users.User
|
||||
import play.api.*
|
||||
import play.api.libs.json.{JsValue, Json}
|
||||
import play.api.mvc.*
|
||||
import play.twirl.api.Html
|
||||
|
||||
import java.util.UUID
|
||||
import javax.inject.*
|
||||
@@ -22,29 +24,47 @@ class IngameController @Inject() (
|
||||
val authAction: AuthAction,
|
||||
implicit val ec: ExecutionContext
|
||||
) extends AbstractController(cc) {
|
||||
|
||||
def returnInnerHTML(gameLobby: GameLobby, user: User): Html = {
|
||||
gameLobby.logic.getCurrentState match {
|
||||
case Lobby => views.html.lobby.lobby(Some(user), gameLobby)
|
||||
case InGame =>
|
||||
views.html.ingame.ingame(
|
||||
gameLobby.getPlayerByUser(user),
|
||||
gameLobby
|
||||
)
|
||||
case SelectTrump =>
|
||||
views.html.ingame.selecttrump(
|
||||
gameLobby.getPlayerByUser(user),
|
||||
gameLobby
|
||||
)
|
||||
case TieBreak =>
|
||||
views.html.ingame.tie(
|
||||
gameLobby.getPlayerByUser(user),
|
||||
gameLobby
|
||||
)
|
||||
case FinishedMatch =>
|
||||
views.html.ingame.finishedMatch(
|
||||
Some(user),
|
||||
gameLobby
|
||||
)
|
||||
case _ =>
|
||||
throw new IllegalStateException(s"Invalid game state for in-game view. GameId: ${gameLobby.id}" + s" State: ${gameLobby.logic.getCurrentState}")
|
||||
}
|
||||
}
|
||||
|
||||
def game(gameId: String): Action[AnyContent] = authAction { implicit request: AuthenticatedRequest[AnyContent] =>
|
||||
val game = podManager.getGame(gameId)
|
||||
game match {
|
||||
case Some(g) =>
|
||||
g.logic.getCurrentState match {
|
||||
case Lobby => Ok(views.html.lobby.lobby(Some(request.user), g))
|
||||
case InGame =>
|
||||
Ok(views.html.ingame.ingame(
|
||||
g.getPlayerByUser(request.user),
|
||||
g
|
||||
))
|
||||
case SelectTrump =>
|
||||
Ok(views.html.ingame.selecttrump(
|
||||
g.getPlayerByUser(request.user),
|
||||
g
|
||||
))
|
||||
case TieBreak =>
|
||||
Ok(views.html.ingame.tie(
|
||||
g.getPlayerByUser(request.user),
|
||||
g
|
||||
))
|
||||
case _ =>
|
||||
InternalServerError(s"Invalid game state for in-game view. GameId: $gameId" + s" State: ${g.logic.getCurrentState}")
|
||||
val results = Try {
|
||||
returnInnerHTML(g, request.user)
|
||||
|
||||
}
|
||||
if (results.isSuccess) {
|
||||
Ok(views.html.main("In-Game - Knockout Whist")(results.get))
|
||||
} else {
|
||||
InternalServerError(results.failed.get.getMessage)
|
||||
}
|
||||
case None =>
|
||||
NotFound("Game not found")
|
||||
@@ -126,32 +146,7 @@ class IngameController @Inject() (
|
||||
))
|
||||
}
|
||||
}
|
||||
def joinGame(gameId: String): Action[AnyContent] = authAction { implicit request: AuthenticatedRequest[AnyContent] =>
|
||||
val game = podManager.getGame(gameId)
|
||||
val result = Try {
|
||||
game match {
|
||||
case Some(g) =>
|
||||
g.addUser(request.user)
|
||||
case None =>
|
||||
NotFound("Game not found")
|
||||
}
|
||||
}
|
||||
if (result.isSuccess) {
|
||||
Redirect(routes.IngameController.game(gameId))
|
||||
} else {
|
||||
val throwable = result.failed.get
|
||||
throwable match {
|
||||
case _: GameFullException =>
|
||||
BadRequest(throwable.getMessage)
|
||||
case _: IllegalArgumentException =>
|
||||
BadRequest(throwable.getMessage)
|
||||
case _: IllegalStateException =>
|
||||
BadRequest(throwable.getMessage)
|
||||
case _ =>
|
||||
InternalServerError(throwable.getMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def playCard(gameId: String): Action[AnyContent] = authAction { implicit request: AuthenticatedRequest[AnyContent] => {
|
||||
val game = podManager.getGame(gameId)
|
||||
game match {
|
||||
@@ -255,15 +250,30 @@ class IngameController @Inject() (
|
||||
val throwable = result.failed.get
|
||||
throwable match {
|
||||
case _: CantPlayCardException =>
|
||||
BadRequest(throwable.getMessage)
|
||||
BadRequest(Json.obj(
|
||||
"status" -> "failure",
|
||||
"errorMessage" -> throwable.getMessage
|
||||
))
|
||||
case _: NotInThisGameException =>
|
||||
BadRequest(throwable.getMessage)
|
||||
BadRequest(Json.obj(
|
||||
"status" -> "failure",
|
||||
"errorMessage" -> throwable.getMessage
|
||||
))
|
||||
case _: IllegalArgumentException =>
|
||||
BadRequest(throwable.getMessage)
|
||||
BadRequest(Json.obj(
|
||||
"status" -> "failure",
|
||||
"errorMessage" -> throwable.getMessage
|
||||
))
|
||||
case _: IllegalStateException =>
|
||||
BadRequest(throwable.getMessage)
|
||||
BadRequest(Json.obj(
|
||||
"status" -> "failure",
|
||||
"errorMessage" -> throwable.getMessage
|
||||
))
|
||||
case _ =>
|
||||
InternalServerError(throwable.getMessage)
|
||||
InternalServerError(Json.obj(
|
||||
"status" -> "failure",
|
||||
"errorMessage" -> throwable.getMessage
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -276,7 +286,10 @@ class IngameController @Inject() (
|
||||
val game = podManager.getGame(gameId)
|
||||
game match {
|
||||
case Some(g) =>
|
||||
val trumpOpt = request.body.asFormUrlEncoded.flatMap(_.get("trump").flatMap(_.headOption))
|
||||
val jsonBody = request.body.asJson
|
||||
val trumpOpt: Option[String] = jsonBody.flatMap { jsValue =>
|
||||
(jsValue \ "trump").asOpt[String]
|
||||
}
|
||||
trumpOpt match {
|
||||
case Some(trump) =>
|
||||
var optSession: Option[UserSession] = None
|
||||
@@ -293,13 +306,25 @@ class IngameController @Inject() (
|
||||
val throwable = result.failed.get
|
||||
throwable match {
|
||||
case _: IllegalArgumentException =>
|
||||
BadRequest(throwable.getMessage)
|
||||
BadRequest(Json.obj(
|
||||
"status" -> "failure",
|
||||
"errorMessage" -> throwable.getMessage
|
||||
))
|
||||
case _: NotInThisGameException =>
|
||||
BadRequest(throwable.getMessage)
|
||||
BadRequest(Json.obj(
|
||||
"status" -> "failure",
|
||||
"errorMessage" -> throwable.getMessage
|
||||
))
|
||||
case _: IllegalStateException =>
|
||||
BadRequest(throwable.getMessage)
|
||||
BadRequest(Json.obj(
|
||||
"status" -> "failure",
|
||||
"errorMessage" -> throwable.getMessage
|
||||
))
|
||||
case _ =>
|
||||
InternalServerError(throwable.getMessage)
|
||||
InternalServerError(Json.obj(
|
||||
"status" -> "failure",
|
||||
"errorMessage" -> throwable.getMessage
|
||||
))
|
||||
}
|
||||
}
|
||||
case None =>
|
||||
@@ -313,7 +338,10 @@ class IngameController @Inject() (
|
||||
val game = podManager.getGame(gameId)
|
||||
game match {
|
||||
case Some(g) =>
|
||||
val tieOpt = request.body.asFormUrlEncoded.flatMap(_.get("tie").flatMap(_.headOption))
|
||||
val jsonBody = request.body.asJson
|
||||
val tieOpt: Option[String] = jsonBody.flatMap { jsValue =>
|
||||
(jsValue \ "tie").asOpt[String]
|
||||
}
|
||||
tieOpt match {
|
||||
case Some(tie) =>
|
||||
var optSession: Option[UserSession] = None
|
||||
@@ -330,13 +358,25 @@ class IngameController @Inject() (
|
||||
val throwable = result.failed.get
|
||||
throwable match {
|
||||
case _: IllegalArgumentException =>
|
||||
BadRequest(throwable.getMessage)
|
||||
BadRequest(Json.obj(
|
||||
"status" -> "failure",
|
||||
"errorMessage" -> throwable.getMessage
|
||||
))
|
||||
case _: NotInThisGameException =>
|
||||
BadRequest(throwable.getMessage)
|
||||
BadRequest(Json.obj(
|
||||
"status" -> "failure",
|
||||
"errorMessage" -> throwable.getMessage
|
||||
))
|
||||
case _: IllegalStateException =>
|
||||
BadRequest(throwable.getMessage)
|
||||
BadRequest(Json.obj(
|
||||
"status" -> "failure",
|
||||
"errorMessage" -> throwable.getMessage
|
||||
))
|
||||
case _ =>
|
||||
InternalServerError(throwable.getMessage)
|
||||
InternalServerError(Json.obj(
|
||||
"status" -> "failure",
|
||||
"errorMessage" -> throwable.getMessage
|
||||
))
|
||||
}
|
||||
}
|
||||
case None =>
|
||||
|
||||
@@ -12,16 +12,22 @@ class JavaScriptRoutingController @Inject()(
|
||||
val authAction: AuthAction,
|
||||
val podManager: PodManager
|
||||
) extends BaseController {
|
||||
def javascriptRoutes(): Action[AnyContent] = authAction { implicit request: AuthenticatedRequest[AnyContent] =>
|
||||
def javascriptRoutes(): Action[AnyContent] =
|
||||
Action { implicit request =>
|
||||
Ok(
|
||||
JavaScriptReverseRouter("jsRoutes")(
|
||||
routes.javascript.MainMenuController.createGame,
|
||||
routes.javascript.IngameController.startGame,
|
||||
routes.javascript.MainMenuController.joinGame,
|
||||
routes.javascript.IngameController.kickPlayer,
|
||||
routes.javascript.IngameController.leaveGame,
|
||||
routes.javascript.IngameController.playCard,
|
||||
routes.javascript.IngameController.playDogCard,
|
||||
routes.javascript.PollingController.polling
|
||||
routes.javascript.IngameController.playTrump,
|
||||
routes.javascript.IngameController.playTie,
|
||||
routes.javascript.IngameController.returnToLobby,
|
||||
routes.javascript.PollingController.polling,
|
||||
routes.javascript.UserController.login_Post
|
||||
)
|
||||
).as("text/javascript")
|
||||
}
|
||||
|
||||
@@ -17,12 +17,13 @@ import javax.inject.*
|
||||
class MainMenuController @Inject()(
|
||||
val controllerComponents: ControllerComponents,
|
||||
val authAction: AuthAction,
|
||||
val podManager: PodManager
|
||||
val podManager: PodManager,
|
||||
val ingameController: IngameController
|
||||
) extends BaseController {
|
||||
|
||||
// Pass the request-handling function directly to authAction (no nested Action)
|
||||
def mainMenu(): Action[AnyContent] = authAction { implicit request: AuthenticatedRequest[AnyContent] =>
|
||||
Ok(views.html.mainmenu.creategame(Some(request.user)))
|
||||
Ok(views.html.main("KnockOutWhist")(views.html.mainmenu.creategame(Some(request.user))))
|
||||
}
|
||||
|
||||
def index(): Action[AnyContent] = authAction { implicit request: AuthenticatedRequest[AnyContent] =>
|
||||
@@ -45,7 +46,8 @@ class MainMenuController @Inject()(
|
||||
)
|
||||
Ok(Json.obj(
|
||||
"status" -> "success",
|
||||
"redirectUrl" -> routes.IngameController.game(gameLobby.id).url
|
||||
"redirectUrl" -> routes.IngameController.game(gameLobby.id).url,
|
||||
"content" -> ingameController.returnInnerHTML(gameLobby, request.user).toString
|
||||
))
|
||||
} else {
|
||||
BadRequest(Json.obj(
|
||||
@@ -57,18 +59,31 @@ class MainMenuController @Inject()(
|
||||
}
|
||||
|
||||
def joinGame(): Action[AnyContent] = authAction { implicit request: AuthenticatedRequest[AnyContent] =>
|
||||
val postData = request.body.asFormUrlEncoded
|
||||
if (postData.isDefined) {
|
||||
val gameId = postData.get.get("gameId").flatMap(_.headOption).getOrElse("")
|
||||
val game = podManager.getGame(gameId)
|
||||
val jsonBody = request.body.asJson
|
||||
val gameId: Option[String] = jsonBody.flatMap { jsValue =>
|
||||
(jsValue \ "gameId").asOpt[String]
|
||||
}
|
||||
if (gameId.isDefined) {
|
||||
val game = podManager.getGame(gameId.get)
|
||||
game match {
|
||||
case Some(g) =>
|
||||
Redirect(routes.IngameController.joinGame(gameId))
|
||||
g.addUser(request.user)
|
||||
Ok(Json.obj(
|
||||
"status" -> "success",
|
||||
"redirectUrl" -> routes.IngameController.game(g.id).url,
|
||||
"content" -> ingameController.returnInnerHTML(g, request.user).toString
|
||||
))
|
||||
case None =>
|
||||
NotFound("Game not found")
|
||||
NotFound(Json.obj(
|
||||
"status" -> "failure",
|
||||
"errorMessage" -> "No Game found"
|
||||
))
|
||||
}
|
||||
} else {
|
||||
BadRequest("Invalid form submission")
|
||||
BadRequest(Json.obj(
|
||||
"status" -> "failure",
|
||||
"errorMessage" -> "Invalid form submission"
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import de.knockoutwhist.cards.Hand
|
||||
import de.knockoutwhist.player.AbstractPlayer
|
||||
import logic.PodManager
|
||||
import logic.game.{GameLobby, PollingEvents}
|
||||
import logic.game.PollingEvents.{CardPlayed, LobbyCreation, LobbyUpdate, NewRound, ReloadEvent}
|
||||
import logic.game.PollingEvents.{CardPlayed, LobbyCreation, LobbyUpdate, NewRound, NewTrick, ReloadEvent}
|
||||
import model.sessions.UserSession
|
||||
import model.users.User
|
||||
import play.api.libs.json.{JsArray, JsValue, Json}
|
||||
@@ -26,6 +26,7 @@ class PollingController @Inject() (
|
||||
val cc: ControllerComponents,
|
||||
val podManager: PodManager,
|
||||
val authAction: AuthAction,
|
||||
val ingameController: IngameController,
|
||||
implicit val ec: ExecutionContext
|
||||
) extends AbstractController(cc) {
|
||||
|
||||
@@ -64,7 +65,8 @@ class PollingController @Inject() (
|
||||
"trickCards" -> trickCardsJson,
|
||||
"scoreTable" -> scoreTableJson,
|
||||
"firstCardId" -> firstCardId,
|
||||
"nextPlayer" -> nextPlayer
|
||||
"nextPlayer" -> nextPlayer,
|
||||
"yourTurn" -> (game.logic.getCurrentPlayer.get == player)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -88,6 +90,11 @@ class PollingController @Inject() (
|
||||
val hand = player.currentHand()
|
||||
val jsonResponse = buildCardPlayResponse(game, hand, player, true)
|
||||
Ok(jsonResponse)
|
||||
case NewTrick =>
|
||||
val player = game.getPlayerByUser(userSession.user)
|
||||
val hand = player.currentHand()
|
||||
val jsonResponse = buildCardPlayResponse(game, hand, player, false)
|
||||
Ok(jsonResponse)
|
||||
case CardPlayed =>
|
||||
val player = game.getPlayerByUser(userSession.user)
|
||||
val hand = player.currentHand()
|
||||
@@ -98,7 +105,8 @@ class PollingController @Inject() (
|
||||
case ReloadEvent =>
|
||||
val jsonResponse = Json.obj(
|
||||
"status" -> "reloadEvent",
|
||||
"redirectUrl" -> routes.IngameController.game(game.id).url
|
||||
"redirectUrl" -> routes.IngameController.game(game.id).url,
|
||||
"content" -> ingameController.returnInnerHTML(game, userSession.user).toString
|
||||
)
|
||||
Ok(jsonResponse)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package controllers
|
||||
import auth.{AuthAction, AuthenticatedRequest}
|
||||
import logic.user.{SessionManager, UserManager}
|
||||
import play.api.*
|
||||
import play.api.libs.json.Json
|
||||
import play.api.mvc.*
|
||||
|
||||
import javax.inject.*
|
||||
@@ -28,28 +29,35 @@ class UserController @Inject()(
|
||||
if (possibleUser.isDefined) {
|
||||
Redirect(routes.MainMenuController.mainMenu())
|
||||
} else {
|
||||
Ok(views.html.login.login())
|
||||
Ok(views.html.main("Login")(views.html.login.login()))
|
||||
}
|
||||
} else {
|
||||
Ok(views.html.login.login())
|
||||
Ok(views.html.main("Login")(views.html.login.login()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def login_Post(): Action[AnyContent] = {
|
||||
Action { implicit request =>
|
||||
val postData = request.body.asFormUrlEncoded
|
||||
if (postData.isDefined) {
|
||||
val jsonBody = request.body.asJson
|
||||
val username: Option[String] = jsonBody.flatMap { jsValue =>
|
||||
(jsValue \ "username").asOpt[String]
|
||||
}
|
||||
val password: Option[String] = jsonBody.flatMap { jsValue =>
|
||||
(jsValue \ "password").asOpt[String]
|
||||
}
|
||||
if (username.isDefined && password.isDefined) {
|
||||
// Extract username and password from form data
|
||||
val username = postData.get.get("username").flatMap(_.headOption).getOrElse("")
|
||||
val password = postData.get.get("password").flatMap(_.headOption).getOrElse("")
|
||||
val possibleUser = userManager.authenticate(username, password)
|
||||
val possibleUser = userManager.authenticate(username.get, password.get)
|
||||
if (possibleUser.isDefined) {
|
||||
Redirect(routes.MainMenuController.mainMenu()).withCookies(
|
||||
Ok(Json.obj(
|
||||
"status" -> "success",
|
||||
"redirectUrl" -> routes.MainMenuController.mainMenu().url,
|
||||
"content" -> views.html.mainmenu.creategame(possibleUser).toString
|
||||
)).withCookies(
|
||||
Cookie("sessionId", sessionManager.createSession(possibleUser.get))
|
||||
)
|
||||
} else {
|
||||
println("Failed login attempt for user: " + username)
|
||||
Unauthorized("Invalid username or password")
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user