Files
KnockOutWhist-Web/knockoutwhistweb/app/controllers/IngameController.scala
Janis 32d4f9c6ce feat(ui): add main menu navbar and join game functionality (#35)
Reviewed-on: #35
Reviewed-by: lq64 <lq@blackhole.local>
Co-authored-by: Janis <janis.e.20@gmx.de>
Co-committed-by: Janis <janis.e.20@gmx.de>
2025-11-04 12:43:08 +01:00

259 lines
8.9 KiB
Scala

package controllers
import auth.{AuthAction, AuthenticatedRequest}
import de.knockoutwhist.control.GameState.{InGame, Lobby, SelectTrump, TieBreak}
import exceptions.{CantPlayCardException, GameFullException, NotEnoughPlayersException, NotHostException, NotInThisGameException}
import logic.PodManager
import play.api.*
import play.api.mvc.*
import javax.inject.*
import scala.util.Try
/**
* This controller creates an `Action` to handle HTTP requests to the
* application's home page.
*/
@Singleton
class IngameController @Inject()(
val controllerComponents: ControllerComponents,
val authAction: AuthAction,
val podManager: PodManager
) extends BaseController {
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("Lobby: " + gameId)
case InGame =>
Ok(views.html.ingame.ingame(
g.getPlayerByUser(request.user),
g.logic
))
case SelectTrump =>
Ok(views.html.ingame.selecttrump(
g.getPlayerByUser(request.user),
g.logic
))
case TieBreak =>
Ok(views.html.ingame.tie(
g.getPlayerByUser(request.user),
g.logic
))
case _ =>
InternalServerError(s"Invalid game state for in-game view. GameId: $gameId" + s" State: ${g.logic.getCurrentState}")
}
case None =>
NotFound("Game not found")
}
//NotFound(s"Reached end of game method unexpectedly. GameId: $gameId")
}
def startGame(gameId: String): Action[AnyContent] = authAction { implicit request: AuthenticatedRequest[AnyContent] =>
val game = podManager.getGame(gameId)
val result = Try {
game match {
case Some(g) =>
g.startGame(request.user)
case None =>
NotFound("Game not found")
}
}
if (result.isSuccess) {
NoContent
} else {
val throwable = result.failed.get
throwable match {
case _: NotInThisGameException =>
BadRequest(throwable.getMessage)
case _: NotHostException =>
Forbidden(throwable.getMessage)
case _: NotEnoughPlayersException =>
BadRequest(throwable.getMessage)
case _ =>
InternalServerError(throwable.getMessage)
}
}
}
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 {
case Some(g) =>
val cardIdOpt = request.body.asFormUrlEncoded.flatMap(_.get("cardId").flatMap(_.headOption))
cardIdOpt match {
case Some(cardId) =>
val result = Try {
val session = g.getUserSession(request.user.id)
session.lock.lock()
g.playCard(session, cardId.toInt)
session.lock.unlock()
}
if (result.isSuccess) {
NoContent
} else {
val throwable = result.failed.get
throwable match {
case _: CantPlayCardException =>
BadRequest(throwable.getMessage)
case _: NotInThisGameException =>
BadRequest(throwable.getMessage)
case _: IllegalArgumentException =>
BadRequest(throwable.getMessage)
case _: IllegalStateException =>
BadRequest(throwable.getMessage)
case _ =>
InternalServerError(throwable.getMessage)
}
}
case None =>
BadRequest("cardId parameter is missing")
}
case None =>
NotFound("Game not found")
}
}
}
def playDogCard(gameId: String): Action[AnyContent] = authAction { implicit request: AuthenticatedRequest[AnyContent] => {
val game = podManager.getGame(gameId)
game match {
case Some(g) => {
val cardIdOpt = request.body.asFormUrlEncoded.flatMap(_.get("cardId").flatMap(_.headOption))
val result = Try {
cardIdOpt match {
case Some(cardId) if cardId == "skip" =>
val session = g.getUserSession(request.user.id)
session.lock.lock()
g.playDogCard(session, -1)
session.lock.unlock()
case Some(cardId) =>
val session = g.getUserSession(request.user.id)
session.lock.lock()
g.playDogCard(session, cardId.toInt)
session.lock.unlock()
case None =>
throw new IllegalArgumentException("cardId parameter is missing")
}
}
if (result.isSuccess) {
NoContent
} else {
val throwable = result.failed.get
throwable match {
case _: CantPlayCardException =>
BadRequest(throwable.getMessage)
case _: NotInThisGameException =>
BadRequest(throwable.getMessage)
case _: IllegalArgumentException =>
BadRequest(throwable.getMessage)
case _: IllegalStateException =>
BadRequest(throwable.getMessage)
case _ =>
InternalServerError(throwable.getMessage)
}
}
}
case None =>
NotFound("Game not found")
}
}
}
def playTrump(gameId: String): Action[AnyContent] = authAction { implicit request: AuthenticatedRequest[AnyContent] =>
val game = podManager.getGame(gameId)
game match {
case Some(g) =>
val trumpOpt = request.body.asFormUrlEncoded.flatMap(_.get("trump").flatMap(_.headOption))
trumpOpt match {
case Some(trump) =>
val result = Try {
val session = g.getUserSession(request.user.id)
session.lock.lock()
g.selectTrump(session, trump.toInt)
session.lock.unlock()
}
if (result.isSuccess) {
NoContent
} else {
val throwable = result.failed.get
throwable match {
case _: IllegalArgumentException =>
BadRequest(throwable.getMessage)
case _: NotInThisGameException =>
BadRequest(throwable.getMessage)
case _: IllegalStateException =>
BadRequest(throwable.getMessage)
case _ =>
InternalServerError(throwable.getMessage)
}
}
case None =>
BadRequest("trump parameter is missing")
}
case None =>
NotFound("Game not found")
}
}
def playTie(gameId: String): Action[AnyContent] = authAction { implicit request: AuthenticatedRequest[AnyContent] =>
val game = podManager.getGame(gameId)
game match {
case Some(g) =>
val tieOpt = request.body.asFormUrlEncoded.flatMap(_.get("tie").flatMap(_.headOption))
tieOpt match {
case Some(tie) =>
val result = Try {
val session = g.getUserSession(request.user.id)
session.lock.lock()
g.selectTie(g.getUserSession(request.user.id), tie.toInt)
session.lock.unlock()
}
if (result.isSuccess) {
NoContent
} else {
val throwable = result.failed.get
throwable match {
case _: IllegalArgumentException =>
BadRequest(throwable.getMessage)
case _: NotInThisGameException =>
BadRequest(throwable.getMessage)
case _: IllegalStateException =>
BadRequest(throwable.getMessage)
case _ =>
InternalServerError(throwable.getMessage)
}
}
case None =>
BadRequest("tie parameter is missing")
}
case None =>
NotFound("Game not found")
}
}
}