Add visibility toggle for player & npc + refactor WebSocketMessage.

This commit is contained in:
Andres Gomez, Thomas (ITDV RL) 2025-03-19 15:19:31 +01:00
parent 2d164b265e
commit 4c37d8b937
47 changed files with 475 additions and 304 deletions

View file

@ -209,4 +209,24 @@ class CampaignService(
}
}
}
suspend fun updateToggleParty() {
store.save(
campaign = campaign.copy(
options = campaign.options.copy(
showParty = campaign.options.showParty.not()
)
)
)
}
suspend fun updateToggleNpc() {
store.save(
campaign = campaign.copy(
options = campaign.options.copy(
showNpcs = campaign.options.showNpcs.not()
)
)
)
}
}

View file

@ -5,11 +5,13 @@ import com.pixelized.server.lwa.model.campaign.CampaignService
import com.pixelized.server.lwa.model.character.CharacterSheetService
import com.pixelized.shared.lwa.model.campaign.Campaign
import com.pixelized.shared.lwa.model.campaign.factory.CampaignJsonFactory
import com.pixelized.shared.lwa.protocol.websocket.Message
import com.pixelized.shared.lwa.protocol.websocket.payload.CampaignMessage
import com.pixelized.shared.lwa.protocol.websocket.payload.RestSynchronisation
import com.pixelized.shared.lwa.protocol.websocket.payload.RollMessage
import com.pixelized.shared.lwa.protocol.websocket.payload.UpdateSkillUsageMessage
import com.pixelized.shared.lwa.protocol.websocket.SocketMessage
import com.pixelized.shared.lwa.protocol.websocket.CampaignMessage
import com.pixelized.shared.lwa.protocol.websocket.GameMasterEvent
import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation
import com.pixelized.shared.lwa.protocol.websocket.RollMessage
import com.pixelized.shared.lwa.protocol.websocket.ToggleActiveAlteration
import com.pixelized.shared.lwa.protocol.websocket.UpdateSkillUsageMessage
import kotlinx.coroutines.flow.MutableSharedFlow
class Engine(
@ -18,46 +20,51 @@ class Engine(
val alterationService: AlterationService,
val campaignJsonFactory: CampaignJsonFactory,
) {
val webSocket = MutableSharedFlow<Message>()
val webSocket = MutableSharedFlow<SocketMessage>()
suspend fun handle(message: Message) {
when (val data = message.value) {
suspend fun handle(message: SocketMessage) {
when (message) {
is RollMessage -> Unit // Nothing to do here.
is CampaignMessage -> {
val instanceId = Campaign.CharacterInstance.Id(
prefix = data.prefix,
characterSheetId = data.characterSheetId,
instanceId = data.instanceId,
prefix = message.prefix,
characterSheetId = message.characterSheetId,
instanceId = message.instanceId,
)
when (data) {
when (message) {
is CampaignMessage.UpdateCharacteristic -> campaignService.updateCharacteristic(
characterInstanceId = instanceId,
characteristic = campaignJsonFactory.convertFromJson(json = data.characteristic),
value = data.value,
characteristic = campaignJsonFactory.convertFromJson(json = message.characteristic),
value = message.value,
)
is CampaignMessage.UpdateDiminished -> campaignService.updateDiminished(
characterInstanceId = instanceId,
diminished = data.diminished,
diminished = message.diminished,
)
}
}
is UpdateSkillUsageMessage -> characterService.updateCharacterSkillUsage(
characterSheetId = data.characterSheetId,
skillId = data.skillId,
used = data.used,
characterSheetId = message.characterSheetId,
skillId = message.skillId,
used = message.used,
)
RestSynchronisation.Campaign -> Unit // Handle in the Rest
is RestSynchronisation.Campaign -> Unit // Handle in the Rest
is RestSynchronisation.CharacterUpdate -> Unit // Handle in the Rest
is RestSynchronisation.CharacterSheetUpdate -> Unit // Handle in the Rest
is RestSynchronisation.CharacterDelete -> Unit // Handle in the Rest
is RestSynchronisation.CharacterSheetDelete -> Unit // Handle in the Rest
is RestSynchronisation.ToggleActiveAlteration -> Unit // Handle in the Rest
is ToggleActiveAlteration -> Unit // Handle in the Rest
is GameMasterEvent -> when (message) {
is GameMasterEvent.TogglePlayer -> campaignService.updateToggleParty()
is GameMasterEvent.ToggleNpc -> campaignService.updateToggleNpc()
}
}
}
}

View file

@ -15,7 +15,7 @@ import com.pixelized.server.lwa.server.rest.character.getCharacter
import com.pixelized.server.lwa.server.rest.character.getCharacters
import com.pixelized.server.lwa.server.rest.character.putCharacter
import com.pixelized.shared.lwa.SERVER_PORT
import com.pixelized.shared.lwa.protocol.websocket.Message
import com.pixelized.shared.lwa.protocol.websocket.SocketMessage
import com.pixelized.shared.lwa.sharedModuleDependencies
import io.ktor.serialization.kotlinx.json.json
import io.ktor.server.application.install
@ -97,7 +97,7 @@ class LocalServer {
incoming.consumeEach { frame ->
if (frame is Frame.Text) {
val data = frame.readText()
val message = json.decodeFromString<Message>(data)
val message = json.decodeFromString<SocketMessage>(data)
// log the message
engine.handle(message)
// broadcast to clients the message

View file

@ -2,8 +2,7 @@ package com.pixelized.server.lwa.server.rest.alteration
import com.pixelized.server.lwa.server.Engine
import com.pixelized.server.lwa.utils.extentions.characterInstanceId
import com.pixelized.shared.lwa.protocol.websocket.Message
import com.pixelized.shared.lwa.protocol.websocket.payload.RestSynchronisation
import com.pixelized.shared.lwa.protocol.websocket.ToggleActiveAlteration
import io.ktor.http.HttpStatusCode
import io.ktor.server.request.receive
import io.ktor.server.response.respondText
@ -32,15 +31,15 @@ fun Engine.putActiveAlteration(): suspend io.ktor.server.routing.RoutingContext.
)
// share the modification to all client through the websocket.
webSocket.emit(
Message(
from = "Server",
value = RestSynchronisation.ToggleActiveAlteration(
characterId = campaignJsonFactory.convertToJson(id = characterInstanceId),
alterationId = alterationId,
active = alterationService.isAlterationActive(
characterInstanceId = characterInstanceId,
alterationId = alterationId
),
ToggleActiveAlteration(
timestamp = System.currentTimeMillis(),
prefix = characterInstanceId.prefix,
characterSheetId = characterInstanceId.characterSheetId,
instanceId = characterInstanceId.instanceId,
alterationId = alterationId,
active = alterationService.isAlterationActive(
characterInstanceId = characterInstanceId,
alterationId = alterationId
),
)
)

View file

@ -2,8 +2,7 @@ package com.pixelized.server.lwa.server.rest.campaign
import com.pixelized.server.lwa.server.Engine
import com.pixelized.server.lwa.utils.extentions.characterInstanceId
import com.pixelized.shared.lwa.protocol.websocket.Message
import com.pixelized.shared.lwa.protocol.websocket.payload.RestSynchronisation
import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation
import io.ktor.http.HttpStatusCode
import io.ktor.server.response.respondText
@ -24,9 +23,8 @@ fun Engine.removeCampaignCharacter(): suspend io.ktor.server.routing.RoutingCont
status = HttpStatusCode.Accepted,
)
webSocket.emit(
Message(
from = "Server",
value = RestSynchronisation.Campaign,
RestSynchronisation.Campaign(
timestamp = System.currentTimeMillis(),
)
)
} catch (exception: Exception) {

View file

@ -2,8 +2,7 @@ package com.pixelized.server.lwa.server.rest.campaign
import com.pixelized.server.lwa.server.Engine
import com.pixelized.server.lwa.utils.extentions.characterInstanceId
import com.pixelized.shared.lwa.protocol.websocket.Message
import com.pixelized.shared.lwa.protocol.websocket.payload.RestSynchronisation
import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation
import io.ktor.http.HttpStatusCode
import io.ktor.server.response.respondText
@ -24,9 +23,8 @@ fun Engine.deleteCampaignNpc(): suspend io.ktor.server.routing.RoutingContext.()
status = HttpStatusCode.Accepted,
)
webSocket.emit(
Message(
from = "Server",
value = RestSynchronisation.Campaign,
RestSynchronisation.Campaign(
timestamp = System.currentTimeMillis(),
)
)
} catch (exception: Exception) {

View file

@ -1,11 +1,8 @@
package com.pixelized.server.lwa.server.rest.campaign
import com.pixelized.server.lwa.server.Engine
import com.pixelized.shared.lwa.model.campaign.Campaign
import com.pixelized.shared.lwa.model.campaign.CampaignJsonV1
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetJson
import com.pixelized.shared.lwa.protocol.websocket.Message
import com.pixelized.shared.lwa.protocol.websocket.payload.RestSynchronisation
import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation
import io.ktor.http.HttpStatusCode
import io.ktor.server.request.receive
import io.ktor.server.response.respondText
@ -29,9 +26,8 @@ fun Engine.putCampaignScene(): suspend io.ktor.server.routing.RoutingContext.()
)
webSocket.emit(
Message(
from = "Server",
value = RestSynchronisation.Campaign,
RestSynchronisation.Campaign(
timestamp = System.currentTimeMillis(),
)
)
}

View file

@ -3,8 +3,7 @@ package com.pixelized.server.lwa.server.rest.campaign
import com.pixelized.server.lwa.server.Engine
import com.pixelized.server.lwa.utils.extentions.characterSheetId
import com.pixelized.shared.lwa.model.campaign.Campaign
import com.pixelized.shared.lwa.protocol.websocket.Message
import com.pixelized.shared.lwa.protocol.websocket.payload.RestSynchronisation
import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation
import io.ktor.http.HttpStatusCode
import io.ktor.server.response.respondText
@ -36,9 +35,8 @@ fun Engine.putCampaignCharacter(): suspend io.ktor.server.routing.RoutingContext
status = HttpStatusCode.Accepted,
)
webSocket.emit(
Message(
from = "Server",
value = RestSynchronisation.Campaign,
RestSynchronisation.Campaign(
timestamp = System.currentTimeMillis(),
)
)
} catch (exception: Exception) {

View file

@ -3,8 +3,7 @@ package com.pixelized.server.lwa.server.rest.campaign
import com.pixelized.server.lwa.server.Engine
import com.pixelized.server.lwa.utils.extentions.characterSheetId
import com.pixelized.shared.lwa.model.campaign.Campaign
import com.pixelized.shared.lwa.protocol.websocket.Message
import com.pixelized.shared.lwa.protocol.websocket.payload.RestSynchronisation
import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation
import io.ktor.http.HttpStatusCode
import io.ktor.server.response.respondText
@ -39,9 +38,8 @@ fun Engine.putCampaignNpc(): suspend io.ktor.server.routing.RoutingContext.() ->
status = HttpStatusCode.Accepted,
)
webSocket.emit(
Message(
from = "Server",
value = RestSynchronisation.Campaign,
RestSynchronisation.Campaign(
timestamp = System.currentTimeMillis(),
)
)
} catch (exception: Exception) {

View file

@ -2,8 +2,7 @@ package com.pixelized.server.lwa.server.rest.character
import com.pixelized.server.lwa.server.Engine
import com.pixelized.server.lwa.utils.extentions.characterSheetId
import com.pixelized.shared.lwa.protocol.websocket.Message
import com.pixelized.shared.lwa.protocol.websocket.payload.RestSynchronisation
import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation
import io.ktor.http.HttpStatusCode
import io.ktor.server.response.respondText
@ -18,10 +17,10 @@ fun Engine.deleteCharacter(): suspend io.ktor.server.routing.RoutingContext.() -
status = HttpStatusCode.OK,
)
webSocket.emit(
Message(
from = "Server",
value = RestSynchronisation.CharacterDelete(characterId = characterSheetId),
)
RestSynchronisation.CharacterSheetDelete(
timestamp = System.currentTimeMillis(),
characterSheetId = characterSheetId,
),
)
} else {
call.respondText(

View file

@ -2,8 +2,7 @@ package com.pixelized.server.lwa.server.rest.character
import com.pixelized.server.lwa.server.Engine
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetJson
import com.pixelized.shared.lwa.protocol.websocket.Message
import com.pixelized.shared.lwa.protocol.websocket.payload.RestSynchronisation
import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation
import io.ktor.http.HttpStatusCode
import io.ktor.server.request.receive
import io.ktor.server.response.respondText
@ -19,10 +18,10 @@ fun Engine.putCharacter(): suspend io.ktor.server.routing.RoutingContext.() -> U
status = HttpStatusCode.OK
)
webSocket.emit(
Message(
from = "Server",
value = RestSynchronisation.CharacterUpdate(id = form.id),
)
RestSynchronisation.CharacterSheetUpdate(
timestamp = System.currentTimeMillis(),
characterSheetId = form.id,
),
)
}
}