feat(websocket)!: Implement WebSocket connection and event handling

This commit is contained in:
2025-11-22 18:32:28 +01:00
parent 09cc96141d
commit ba373f91e9
25 changed files with 420 additions and 80 deletions

View File

@@ -11,14 +11,14 @@ import util.GameUtil
import javax.inject.Singleton
import scala.collection.mutable
@Singleton
class PodManager {
object PodManager {
val TTL: Long = System.currentTimeMillis() + 86400000L // 24 hours in milliseconds
val podIp: String = System.getenv("POD_IP")
val podName: String = System.getenv("POD_NAME")
private val sessions: mutable.Map[String, GameLobby] = mutable.Map()
private val userSession: mutable.Map[User, String] = mutable.Map()
private val injector: Injector = Guice.createInjector(KnockOutWebConfigurationModule())
def createGame(
@@ -35,6 +35,7 @@ class PodManager {
host = host
)
sessions += (gameLobby.id -> gameLobby)
userSession += (host -> gameLobby.id)
gameLobby
}
@@ -44,6 +45,30 @@ class PodManager {
private[logic] def removeGame(gameId: String): Unit = {
sessions.remove(gameId)
// Also remove all user sessions associated with this game
userSession.filterInPlace((_, v) => v != gameId)
}
def registerUserToGame(user: User, gameId: String): Boolean = {
if (sessions.contains(gameId)) {
userSession += (user -> gameId)
true
} else {
false
}
}
def unregisterUserFromGame(user: User): Unit = {
userSession.remove(user)
}
def identifyGameOfUser(user: User): Option[GameLobby] = {
userSession.get(user) match {
case Some(gameId) => sessions.get(gameId)
case None => None
}
}
}

View File

@@ -12,6 +12,7 @@ import de.knockoutwhist.player.{AbstractPlayer, PlayerFactory}
import de.knockoutwhist.rounds.{Match, Round, Trick}
import de.knockoutwhist.utils.events.{EventListener, SimpleEvent}
import exceptions.*
import logic.PodManager
import logic.game.PollingEvents.{CardPlayed, LobbyCreation, LobbyUpdate, NewRound, NewTrick, ReloadEvent}
import model.sessions.{InteractionType, UserSession}
import model.users.User
@@ -69,9 +70,11 @@ class GameLobby private(
if (logic.getCurrentState != Lobby) throw new IllegalStateException("The game has already started!")
val userSession = new UserSession(
user = user,
host = false
host = false,
gameLobby = this
)
users += (user.id -> userSession)
PodManager.registerUserToGame(user, id)
addToQueue(LobbyUpdate)
userSession
}
@@ -156,7 +159,14 @@ class GameLobby private(
if (sessionOpt.isEmpty) {
throw new NotInThisGameException("You are not in this game!")
}
if (sessionOpt.get.host) {
logic.invoke(SessionClosed())
users.clear()
PodManager.removeGame(id)
return
}
users.remove(userId)
PodManager.unregisterUserFromGame(sessionOpt.get.user)
addToQueue(LobbyUpdate)
}
@@ -338,7 +348,8 @@ object GameLobby {
)
lobby.users += (host.id -> new UserSession(
user = host,
host = true
host = true,
gameLobby = lobby
))
lobby
}