feat!: implemented multigame support #34

Merged
Janis merged 16 commits from feat/5-create-user-sessions into main 2025-11-01 20:53:23 +01:00
40 changed files with 2375 additions and 133 deletions
Showing only changes of commit 76bde997ef - Show all commits

View File

@@ -55,32 +55,35 @@ class HomeController @Inject()(val controllerComponents: ControllerComponents) e
def ingame(id: String): Action[AnyContent] = { def ingame(id: String): Action[AnyContent] = {
val uuid: UUID = UUID.fromString(id) val uuid: UUID = UUID.fromString(id)
if (PodGameManager.identify(uuid).isEmpty) {
return Action { implicit request =>
NotFound(views.html.tui.apply(List(Html(s"<p>Session with id $id not found!</p>"))))
}
} else {
val session = PodGameManager.identify(uuid).get
val player = session.asInstanceOf[SimpleSession].player
val logic = null
if (logic.getCurrentState == Lobby) {
} else if (logic.getCurrentState == InGame) {
return Action { implicit request =>
Ok(views.html.ingame.apply(player, logic))
}
} else if (logic.getCurrentState == SelectTrump) {
return Action { implicit request =>
Ok(views.html.selecttrump.apply(player, logic))
}
} else if (logic.getCurrentState == TieBreak) {
return Action { implicit request =>
Ok(views.html.tie.apply(player, logic))
}
}
}
Action { implicit request => Action { implicit request =>
InternalServerError("Oops") NotFound(views.html.tui.apply(List(Html(s"<p>Session with id $id not found!</p>"))))
} }
// if (PodGameManager.identify(uuid).isEmpty) {
// return Action { implicit request =>
// NotFound(views.html.tui.apply(List(Html(s"<p>Session with id $id not found!</p>"))))
// }
// } else {
// val session = PodGameManager.identify(uuid).get
// val player = session.asInstanceOf[SimpleSession].player
// val logic = BaseGameLogic(null)
// if (logic.getCurrentState == Lobby) {
//
// } else if (logic.getCurrentState == InGame) {
// return Action { implicit request =>
// Ok(views.html.ingame.apply(player, logic))
// }
// } else if (logic.getCurrentState == SelectTrump) {
// return Action { implicit request =>
// Ok(views.html.selecttrump.apply(player, logic))
// }
// } else if (logic.getCurrentState == TieBreak) {
// return Action { implicit request =>
// Ok(views.html.tie.apply(player, logic))
// }
// }
// }
// Action { implicit request =>
// InternalServerError("Oops")
// }
} }
} }

View File

@@ -0,0 +1,7 @@
package exceptions;
public class NotHostException extends RuntimeException {
public NotHostException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,7 @@
package exceptions;
public class NotInThisGameException extends RuntimeException {
public NotInThisGameException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,7 @@
package exceptions;
public class NotInteractableException extends RuntimeException {
public NotInteractableException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,69 @@
package logic.game
import de.knockoutwhist.control.GameLogic
import de.knockoutwhist.events.player.PlayerEvent
import de.knockoutwhist.player.Playertype.HUMAN
import de.knockoutwhist.player.{AbstractPlayer, PlayerFactory}
import de.knockoutwhist.rounds.Match
import de.knockoutwhist.utils.events.{EventListener, SimpleEvent}
import exceptions.{NotHostException, NotInThisGameException, NotInteractableException}
import model.sessions.UserSession
import model.users.User
import java.util.UUID
import scala.collection.mutable.ListBuffer
class GameLobby(val logic: GameLogic, val id: String, internalId: UUID) extends EventListener{
logic.addListener(this)
logic.createSession()
val users: Map[UUID, UserSession] = Map()
override def listen(event: SimpleEvent): Unit = {
event match {
case event: PlayerEvent =>
users.get(event.playerId).foreach(session => session.updatePlayer(event))
case event: SimpleEvent =>
users.values.foreach(session => session.updatePlayer(event))
}
}
def startGame(user: User): Unit = {
val sessionOpt = users.get(user.id)
if (sessionOpt.isEmpty) {
throw new NotInThisGameException("You are not in this game!")
}
if (!sessionOpt.get.host) {
throw new NotHostException("Only the host can start the game!")
}
val playerNamesList = ListBuffer[AbstractPlayer]()
users.values.foreach { player =>
playerNamesList += PlayerFactory.createPlayer(player.name, player.id, HUMAN)
}
logic.createMatch(playerNamesList.toList)
logic.controlMatch()
}
def playCard(user: User, card: Int): Unit = {
val sessionOpt = users.get(user.id)
if (sessionOpt.isEmpty) {
throw new NotInThisGameException("You are not in this game!")
}
if (!sessionOpt.get.canInteract) {
throw new NotInteractableException("You can't play a card!")
}
}
//-------------------
private def getMatch: Match = {
val matchOpt = logic.getCurrentMatch
if (matchOpt.isEmpty) {
throw new IllegalStateException("No match is currently running!")
}
matchOpt.get
}
}

View File

@@ -1,14 +0,0 @@
package model.game
import de.knockoutwhist.control.GameLogic
import de.knockoutwhist.utils.events.{EventListener, SimpleEvent}
class GameLobby(val logic: GameLogic) extends EventListener{
logic.addListener(this)
logic.createSession()
override def listen(event: SimpleEvent): Unit = {
}
}

View File

@@ -1,6 +1,5 @@
package model.sessions package model.sessions
import de.knockoutwhist.player.AbstractPlayer
import de.knockoutwhist.utils.events.SimpleEvent import de.knockoutwhist.utils.events.SimpleEvent
import java.util.UUID import java.util.UUID
@@ -9,7 +8,6 @@ trait PlayerSession {
def id: UUID def id: UUID
def name: String def name: String
def player: AbstractPlayer
def updatePlayer(event: SimpleEvent): Unit def updatePlayer(event: SimpleEvent): Unit
} }

View File

@@ -1,8 +1,28 @@
package model.sessions package model.sessions
import de.knockoutwhist.player.AbstractPlayer import de.knockoutwhist.events.player.{RequestCardEvent, RequestTieChoiceEvent, RequestTrumpSuitEvent}
import de.knockoutwhist.utils.events.SimpleEvent
import model.users.User
import java.util.UUID import java.util.UUID
class UserSession(id: UUID, player: AbstractPlayer) extends SimpleSession(id, player) { class UserSession(user: User, val host: Boolean) extends PlayerSession {
var canInteract: Boolean = false
override def updatePlayer(event: SimpleEvent): Unit = {
event match {
case event: RequestTrumpSuitEvent =>
canInteract = true
case event: RequestTieChoiceEvent =>
canInteract = true
case event: RequestCardEvent =>
canInteract = true
case _ =>
}
}
override def id: UUID = user.id
override def name: String = user.name
} }

View File

@@ -6,9 +6,9 @@ auth {
issuer = "knockoutwhistweb" issuer = "knockoutwhistweb"
audience = "ui" audience = "ui"
# ${?PUBLIC_KEY_FILE} # ${?PUBLIC_KEY_FILE}
privateKeyFile = "D:\\Workspaces\\Gitops\\rsa512-private.pem" privateKeyFile = "/home/janis/Workspaces/IntelliJ/KnockOutWhist/Gitops/rsa512-private.pem"
privateKeyPem = ${?PUBLIC_KEY_PEM} privateKeyPem = ${?PUBLIC_KEY_PEM}
#${?PUBLIC_KEY_FILE} #${?PUBLIC_KEY_FILE}
publicKeyFile = "D:\\Workspaces\\Gitops\\rsa512-public.pem" publicKeyFile = "/home/janis/Workspaces/IntelliJ/KnockOutWhist/Gitops/rsa512-public.pem"
publicKeyPem = ${?PUBLIC_KEY_PEM} publicKeyPem = ${?PUBLIC_KEY_PEM}
} }