feat(api): Implemented turn event via websocket (#86)

Co-authored-by: TeamCity <teamcity@service.local>
Reviewed-on: #86
Reviewed-by: lq64 <lq@blackhole.local>
This commit is contained in:
2025-11-27 07:57:37 +01:00
parent 46c96d4ceb
commit 2aee79bb68
4 changed files with 110 additions and 7 deletions

View File

@@ -6,7 +6,7 @@ import model.sessions.UserSession
import play.api.libs.json.{JsValue, Json} import play.api.libs.json.{JsValue, Json}
import tools.jackson.databind.json.JsonMapper import tools.jackson.databind.json.JsonMapper
import tools.jackson.module.scala.ScalaModule import tools.jackson.module.scala.ScalaModule
import util.mapper.{CardPlayedEventMapper, GameStateEventMapper, KickEventMapper, LeftEventMapper, LobbyUpdateEventMapper, ReceivedHandEventMapper, SessionClosedMapper, SimpleEventMapper} import util.mapper.{CardPlayedEventMapper, GameStateEventMapper, KickEventMapper, LeftEventMapper, LobbyUpdateEventMapper, ReceivedHandEventMapper, SessionClosedMapper, SimpleEventMapper, TurnEventMapper}
object WebsocketEventMapper { object WebsocketEventMapper {
@@ -31,7 +31,8 @@ object WebsocketEventMapper {
registerCustomMapper(LeftEventMapper) registerCustomMapper(LeftEventMapper)
registerCustomMapper(KickEventMapper) registerCustomMapper(KickEventMapper)
registerCustomMapper(SessionClosedMapper) registerCustomMapper(SessionClosedMapper)
registerCustomMapper(TurnEventMapper)
def toJson(obj: SimpleEvent, session: UserSession): JsValue = { def toJson(obj: SimpleEvent, session: UserSession): JsValue = {
val data: Option[JsValue] = if (customMappers.contains(obj.id)) { val data: Option[JsValue] = if (customMappers.contains(obj.id)) {
Some(customMappers(obj.id).toJson(obj, session)) Some(customMappers(obj.id).toJson(obj, session))

View File

@@ -0,0 +1,35 @@
package util.mapper
import de.knockoutwhist.events.global.TurnEvent
import de.knockoutwhist.player.AbstractPlayer
import model.sessions.UserSession
import play.api.libs.json.{JsArray, JsObject, Json}
object TurnEventMapper extends SimpleEventMapper[TurnEvent] {
override def id: String = "TurnEvent"
override def toJson(event: TurnEvent, session: UserSession): JsObject = {
val nextPlayers = if (session.gameLobby.logic.getPlayerQueue.isEmpty) {
Json.arr()
} else {
val queue = session.gameLobby.logic.getPlayerQueue.get
JsArray(
queue.duplicate().map(player => mapPlayer(player)).toList
)
}
Json.obj(
"currentPlayer" -> mapPlayer(event.player),
"nextPlayers" -> nextPlayers
)
}
private def mapPlayer(player: AbstractPlayer): JsObject = {
Json.obj(
"name" -> player.name,
"dog" -> player.isInDogLife
)
}
}

View File

@@ -15,12 +15,16 @@
}else { }else {
<p class="fs-5 text-primary" id="current-player-name">---</p> <p class="fs-5 text-primary" id="current-player-name">---</p>
} }
@if(gamelobby.getLogic.getPlayerQueue.isDefined && gamelobby.getLogic.getCurrentMatch && !TrickUtil.isOver(gamelobby.getLogic.getCurrentMatch.get, gamelobby.getLogic.getPlayerQueue.get)) { <h4 class="fw-semibold mb-1" style="display: none;" id="next-players-text">Next Players</h4>
<h4 class="fw-semibold mb-1">Next Player</h4> <div id="next-players-container">
@for(nextplayer <- gamelobby.getLogic.getPlayerQueue.get.duplicate()) { @if(gamelobby.getLogic.getPlayerQueue.isDefined && gamelobby.getLogic.getCurrentMatch && !TrickUtil.isOver(gamelobby.getLogic.getCurrentMatch.get, gamelobby.getLogic.getPlayerQueue.get)) {
<p class="fs-5 text-primary" id="next-player-name">@nextplayer</p> @for(nextplayer <- gamelobby.getLogic.getPlayerQueue.get.duplicate()) {
<p class="fs-5 text-primary">@nextplayer @if(nextplayer.isInDogLife) {
🐶
}</p>
}
} }
} </div>
</div> </div>
<div class="col-4 text-center"> <div class="col-4 text-center">

View File

@@ -85,6 +85,37 @@ function receiveCardPlayedEvent(eventData) {
`; `;
firstCardContainer.html(newFirstCardHTML); firstCardContainer.html(newFirstCardHTML);
} }
function receiveTurnEvent(eventData) {
const currentPlayer = eventData.currentPlayer;
const nextPlayers = eventData.nextPlayers;
const currentPlayerNameContainer = $('#current-player-name');
const nextPlayersContainer = $('#next-players-container');
const nextPlayerText = $('#next-players-section');
let currentPlayerName = currentPlayer.name;
if (currentPlayer.dog) {
currentPlayerName += " 🐶";
}
currentPlayerNameContainer.text(currentPlayerName);
if (nextPlayers.length === 0) {
nextPlayerText.hide();
nextPlayersContainer.html('');
} else {
nextPlayerText.show();
let nextPlayersHtml = '';
nextPlayers.forEach((player) => {
let playerName = player.name;
if (player.dog) {
playerName += " 🐶";
}
nextPlayersHtml += `<p className="fs-5 text-primary">${playerName}</p>`;
});
nextPlayersContainer.html(nextPlayersHtml);
}
}
function receiveLobbyUpdateEvent(eventData) { function receiveLobbyUpdateEvent(eventData) {
const host = eventData.host; const host = eventData.host;
const maxPlayers = eventData.maxPlayers; const maxPlayers = eventData.maxPlayers;
@@ -154,6 +185,37 @@ function receiveSessionClosedEvent(eventData) {
} }
function receiveTurnEvent(eventData) {
const currentPlayer = eventData.currentPlayer;
const nextPlayers = eventData.nextPlayers;
const currentPlayerNameContainer = $('#current-player-name');
const nextPlayersContainer = $('#next-players-container');
const nextPlayerText = $('#next-players-section');
let currentPlayerName = currentPlayer.name;
if (currentPlayer.dog) {
currentPlayerName += " 🐶";
}
currentPlayerNameContainer.text(currentPlayerName);
if (nextPlayers.length === 0) {
nextPlayerText.hide();
nextPlayersContainer.html('');
} else {
nextPlayerText.show();
let nextPlayersHtml = '';
nextPlayers.forEach((player) => {
let playerName = player.name;
if (player.dog) {
playerName += " 🐶";
}
nextPlayersHtml += `<p className="fs-5 text-primary">${playerName}</p>`;
});
nextPlayersContainer.html(nextPlayersHtml);
}
}
onEvent("ReceivedHandEvent", receiveHandEvent) onEvent("ReceivedHandEvent", receiveHandEvent)
onEvent("GameStateChangeEvent", receiveGameStateChange) onEvent("GameStateChangeEvent", receiveGameStateChange)
onEvent("CardPlayedEvent", receiveCardPlayedEvent) onEvent("CardPlayedEvent", receiveCardPlayedEvent)
@@ -161,3 +223,4 @@ onEvent("LobbyUpdateEvent", receiveLobbyUpdateEvent)
onEvent("LeftEvent", receiveGameStateChange) onEvent("LeftEvent", receiveGameStateChange)
onEvent("KickEvent", receiveKickEvent) onEvent("KickEvent", receiveKickEvent)
onEvent("SessionClosed", receiveSessionClosedEvent) onEvent("SessionClosed", receiveSessionClosedEvent)
onEvent("TurnEvent", receiveTurnEvent)