diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/alteration/AlterationStore.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/alteration/AlterationStore.kt index 01d122e..47ae649 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/alteration/AlterationStore.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/alteration/AlterationStore.kt @@ -6,8 +6,8 @@ import com.pixelized.shared.lwa.model.alteration.Alteration import com.pixelized.shared.lwa.model.alteration.AlterationJsonFactory import com.pixelized.shared.lwa.model.campaign.Campaign.CharacterInstance 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.RestSynchronisation +import com.pixelized.shared.lwa.protocol.websocket.SocketMessage +import com.pixelized.shared.lwa.protocol.websocket.ToggleActiveAlteration import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -88,15 +88,17 @@ class AlterationStore( ) } - private suspend fun handleMessage(message: Message) { - when (val payload = message.value) { - is RestSynchronisation.ToggleActiveAlteration -> { + private suspend fun handleMessage(message: SocketMessage) { + when (message) { + is ToggleActiveAlteration -> { setActiveAlteration( - characterInstanceId = campaignJsonFactory.characterInstanceIdFromJson( - characterInstanceIdJson = payload.characterId, + characterInstanceId = CharacterInstance.Id( + prefix = message.prefix, + characterSheetId = message.characterSheetId, + instanceId = message.instanceId, ), - alterationId = payload.alterationId, - active = payload.active, + alterationId = message.alterationId, + active = message.active, ) } diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/campaign/CampaignStore.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/campaign/CampaignStore.kt index a106d27..d763745 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/campaign/CampaignStore.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/campaign/CampaignStore.kt @@ -6,9 +6,10 @@ import com.pixelized.shared.lwa.model.campaign.Campaign import com.pixelized.shared.lwa.model.campaign.character import com.pixelized.shared.lwa.model.campaign.factory.CampaignJsonFactory import com.pixelized.shared.lwa.model.campaign.npc -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.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.usecase.CampaignUseCase import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -106,28 +107,46 @@ class CampaignStore( // region : WebSocket message Handling. - private suspend fun handleMessage(message: Message) { - when (val payload = message.value) { + private suspend fun handleMessage(message: SocketMessage) { + when (message) { is RestSynchronisation.Campaign -> { campaign(update = true) } is CampaignMessage -> { val instanceId = Campaign.CharacterInstance.Id( - prefix = payload.prefix, - characterSheetId = payload.characterSheetId, - instanceId = payload.instanceId, + prefix = message.prefix, + characterSheetId = message.characterSheetId, + instanceId = message.instanceId, ) - when (payload) { + when (message) { is CampaignMessage.UpdateCharacteristic -> updateCharacteristic( characterInstanceId = instanceId, - characteristic = factory.convertFromJson(json = payload.characteristic), - value = payload.value, + characteristic = factory.convertFromJson(json = message.characteristic), + value = message.value, ) is CampaignMessage.UpdateDiminished -> updateDiminished( characterInstanceId = instanceId, - diminished = payload.diminished, + diminished = message.diminished, + ) + } + } + + is GameMasterEvent -> when (message) { + is GameMasterEvent.ToggleNpc -> { + _campaignFlow.value = _campaignFlow.value.copy( + options = _campaignFlow.value.options.copy( + showNpcs = _campaignFlow.value.options.showNpcs.not() + ) + ) + } + + is GameMasterEvent.TogglePlayer -> { + _campaignFlow.value = _campaignFlow.value.copy( + options = _campaignFlow.value.options.copy( + showParty = _campaignFlow.value.options.showParty.not() + ) ) } } diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetStore.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetStore.kt index b0cbb03..9c849b0 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetStore.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/characterSheet/CharacterSheetStore.kt @@ -5,9 +5,9 @@ import com.pixelized.desktop.lwa.repository.network.NetworkRepository import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetJsonFactory import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetPreview -import com.pixelized.shared.lwa.protocol.websocket.Message -import com.pixelized.shared.lwa.protocol.websocket.payload.RestSynchronisation -import com.pixelized.shared.lwa.protocol.websocket.payload.UpdateSkillUsageMessage +import com.pixelized.shared.lwa.protocol.websocket.SocketMessage +import com.pixelized.shared.lwa.protocol.websocket.RestSynchronisation +import com.pixelized.shared.lwa.protocol.websocket.UpdateSkillUsageMessage import com.pixelized.shared.lwa.usecase.CharacterSheetUseCase import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -97,29 +97,29 @@ class CharacterSheetStore( // endregion // region: WebSocket & data update. - private suspend fun handleMessage(message: Message) { - when (val payload = message.value) { - is RestSynchronisation.CharacterUpdate -> { + private suspend fun handleMessage(message: SocketMessage) { + when (message) { + is RestSynchronisation.CharacterSheetUpdate -> { getCharacterSheet( - characterSheetId = payload.id, + characterSheetId = message.characterSheetId, forceUpdate = true, ) - if (_previewFlow.value.firstOrNull { it.characterSheetId == payload.id } == null) { + if (_previewFlow.value.firstOrNull { it.characterSheetId == message.characterSheetId } == null) { charactersPreview() } } - is RestSynchronisation.CharacterDelete -> { + is RestSynchronisation.CharacterSheetDelete -> { _previewFlow.value = previewFlow.value.toMutableList() - .also { sheets -> sheets.removeIf { it.characterSheetId == payload.characterId } } - _detailFlow.delete(payload.characterId) + .also { sheets -> sheets.removeIf { it.characterSheetId == message.characterSheetId } } + _detailFlow.delete(message.characterSheetId) } is UpdateSkillUsageMessage -> { updateCharacterSkillChange( - characterId = payload.characterSheetId, - skillId = payload.skillId, - used = payload.used, + characterId = message.characterSheetId, + skillId = message.skillId, + used = message.used, ) } diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/network/NetworkRepository.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/network/NetworkRepository.kt index 2ce2d1e..52bde44 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/network/NetworkRepository.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/network/NetworkRepository.kt @@ -2,8 +2,7 @@ package com.pixelized.desktop.lwa.repository.network import com.pixelized.desktop.lwa.repository.network.helper.connectWebSocket import com.pixelized.desktop.lwa.repository.settings.SettingsRepository -import com.pixelized.shared.lwa.protocol.websocket.Message -import com.pixelized.shared.lwa.protocol.websocket.payload.MessagePayload +import com.pixelized.shared.lwa.protocol.websocket.SocketMessage import io.ktor.client.HttpClient import io.ktor.client.engine.okhttp.OkHttp import io.ktor.client.plugins.contentnegotiation.ContentNegotiation @@ -20,7 +19,6 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking import kotlinx.serialization.json.Json class NetworkRepository( @@ -31,9 +29,9 @@ class NetworkRepository( private var networkJob: Job? = null private var client: HttpClient? = null - private val outgoingMessageBuffer = MutableSharedFlow() - private val incomingMessageBuffer = MutableSharedFlow() - val data: SharedFlow get() = incomingMessageBuffer + private val outgoingMessageBuffer = MutableSharedFlow() + private val incomingMessageBuffer = MutableSharedFlow() + val data: SharedFlow get() = incomingMessageBuffer private val _status = MutableStateFlow(Status.DISCONNECTED) val status: StateFlow get() = _status @@ -67,7 +65,7 @@ class NetworkRepository( incoming.consumeEach { frame -> if (frame is Frame.Text) { val data = frame.readText() - val message = json.decodeFromString(data) + val message = json.decodeFromString(data) incomingMessageBuffer.emit(message) } } @@ -96,14 +94,9 @@ class NetworkRepository( } suspend fun share( - playerName: String = settingsRepository.settings().playerName, - payload: MessagePayload, + message: SocketMessage, ) { if (status.value == Status.CONNECTED) { - val message = Message( - from = playerName, - value = payload, - ) // emit the message into the outgoing buffer outgoingMessageBuffer.emit(message) } diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/roll_history/RollHistoryRepository.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/roll_history/RollHistoryRepository.kt index 633f3b5..5892b70 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/roll_history/RollHistoryRepository.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/roll_history/RollHistoryRepository.kt @@ -1,21 +1,23 @@ package com.pixelized.desktop.lwa.repository.roll_history import com.pixelized.desktop.lwa.repository.network.NetworkRepository -import com.pixelized.shared.lwa.protocol.websocket.payload.RollMessage +import com.pixelized.shared.lwa.protocol.websocket.RollMessage import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.shareIn class RollHistoryRepository( - private val network: NetworkRepository, + network: NetworkRepository, ) { private val scope = CoroutineScope(Dispatchers.IO) val rolls: SharedFlow = network.data - .mapNotNull { it.value as? RollMessage } + .filterIsInstance(RollMessage::class) .shareIn( scope = scope, started = SharingStarted.Eagerly, diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/composable/character/characteristic/CharacterDetailCharacteristicDialogViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/composable/character/characteristic/CharacterDetailCharacteristicDialogViewModel.kt index 647f697..cd859ac 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/composable/character/characteristic/CharacterDetailCharacteristicDialogViewModel.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/composable/character/characteristic/CharacterDetailCharacteristicDialogViewModel.kt @@ -13,7 +13,7 @@ import com.pixelized.shared.lwa.model.campaign.Campaign import com.pixelized.shared.lwa.model.campaign.Campaign.CharacterInstance.Characteristic import com.pixelized.shared.lwa.model.campaign.factory.CampaignJsonFactory import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet -import com.pixelized.shared.lwa.protocol.websocket.payload.CampaignMessage +import com.pixelized.shared.lwa.protocol.websocket.CampaignMessage class CharacterDetailCharacteristicDialogViewModel( private val characterSheetRepository: CharacterSheetRepository, @@ -79,7 +79,8 @@ class CharacterDetailCharacteristicDialogViewModel( ) // share the data through the websocket. network.share( - payload = CampaignMessage.UpdateCharacteristic( + message = CampaignMessage.UpdateCharacteristic( + timestamp = System.currentTimeMillis(), prefix = characterInstanceId.prefix, characterSheetId = characterInstanceId.characterSheetId, instanceId = characterInstanceId.instanceId, diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/overlay/roll/RollViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/overlay/roll/RollViewModel.kt index 63dd7a4..e3fb5a7 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/overlay/roll/RollViewModel.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/overlay/roll/RollViewModel.kt @@ -13,7 +13,7 @@ import com.pixelized.desktop.lwa.ui.overlay.roll.DifficultyUio.Difficulty import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction.RollActionUio import com.pixelized.shared.lwa.model.AlteredCharacterSheet import com.pixelized.shared.lwa.model.AlteredCharacterSheetFactory -import com.pixelized.shared.lwa.protocol.websocket.payload.RollMessage +import com.pixelized.shared.lwa.protocol.websocket.RollMessage import com.pixelized.shared.lwa.usecase.ExpressionUseCase import com.pixelized.shared.lwa.usecase.SkillStepUseCase import kotlinx.coroutines.Job @@ -31,6 +31,7 @@ import lwacharactersheet.composeapp.generated.resources.roll_page__failure import lwacharactersheet.composeapp.generated.resources.roll_page__special_success import lwacharactersheet.composeapp.generated.resources.roll_page__success import org.jetbrains.compose.resources.getString +import java.util.UUID class RollViewModel( private val characterSheetRepository: CharacterSheetRepository, @@ -267,7 +268,8 @@ class RollViewModel( val rollAction = rollAction ?: return val payload = RollMessage( - id = RollMessage.RollId.create(), + timestamp = System.currentTimeMillis(), + uuid = UUID.randomUUID().toString(), prefix = rollAction.characterInstanceId.prefix, characterSheetId = rollAction.characterInstanceId.characterSheetId, instanceId = rollAction.characterInstanceId.instanceId, @@ -294,7 +296,7 @@ class RollViewModel( }, ) networkRepository.share( - payload = payload, + message = payload, ) } } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDetailViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDetailViewModel.kt index 9401c13..d56f0a4 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDetailViewModel.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDetailViewModel.kt @@ -7,7 +7,7 @@ import com.pixelized.desktop.lwa.repository.campaign.CampaignRepository import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository import com.pixelized.desktop.lwa.repository.network.NetworkRepository import com.pixelized.shared.lwa.model.campaign.Campaign -import com.pixelized.shared.lwa.protocol.websocket.payload.UpdateSkillUsageMessage +import com.pixelized.shared.lwa.protocol.websocket.UpdateSkillUsageMessage import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow @@ -84,7 +84,8 @@ class CharacterDetailViewModel( ) { val characterSheetId = displayedCharacterId.value?.characterSheetId ?: return network.share( - payload = UpdateSkillUsageMessage( + message = UpdateSkillUsageMessage( + timestamp = System.currentTimeMillis(), characterSheetId = characterSheetId, skillId = skillId, used = used.not(), diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDiminishedViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDiminishedViewModel.kt index dbf7503..44de234 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDiminishedViewModel.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDiminishedViewModel.kt @@ -9,7 +9,7 @@ import com.pixelized.desktop.lwa.repository.campaign.CampaignRepository import com.pixelized.desktop.lwa.repository.network.NetworkRepository import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.dialog.DiminishedStatDialogUio import com.pixelized.shared.lwa.model.campaign.Campaign -import com.pixelized.shared.lwa.protocol.websocket.payload.CampaignMessage +import com.pixelized.shared.lwa.protocol.websocket.CampaignMessage import lwacharactersheet.composeapp.generated.resources.Res import lwacharactersheet.composeapp.generated.resources.character_sheet__diminished__label import org.jetbrains.compose.resources.getString @@ -56,7 +56,8 @@ class CharacterDiminishedViewModel( ) { val diminished = dialog.value().text.toIntOrNull() ?: 0 networkRepository.share( - payload = CampaignMessage.UpdateDiminished( + message = CampaignMessage.UpdateDiminished( + timestamp = System.currentTimeMillis(), prefix = dialog.characterInstanceId.prefix, characterSheetId = dialog.characterInstanceId.characterSheetId, instanceId = dialog.characterInstanceId.instanceId, diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/ribbon/CharacterRibbonViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/ribbon/CharacterRibbonViewModel.kt index cadd19c..59024ea 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/ribbon/CharacterRibbonViewModel.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/ribbon/CharacterRibbonViewModel.kt @@ -22,7 +22,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.flatMapMerge +import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.stateIn @@ -53,7 +53,7 @@ abstract class CharacterRibbonViewModel( */ @OptIn(ExperimentalCoroutinesApi::class) val characters: StateFlow> = campaignRepository.campaignFlow - .flatMapMerge { campaign -> + .flatMapLatest { campaign -> when (campaign.data.isEmpty()) { true -> flowOf(emptyList()) else -> combine>( diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/ribbon/npc/NpcRibbonViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/ribbon/npc/NpcRibbonViewModel.kt index f503b7a..dd0315b 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/ribbon/npc/NpcRibbonViewModel.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/ribbon/npc/NpcRibbonViewModel.kt @@ -24,7 +24,7 @@ class NpcRibbonViewModel( campaignRepository = campaignRepository, ribbonFactory = ribbonFactory, ) { - override val Campaign.data get() = npcs + override val Campaign.data get() = if (options.showNpcs) npcs else emptyMap() override val enableCharacterSheet = false override val enableCharacterStats = false diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/ribbon/player/PlayerRibbonViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/ribbon/player/PlayerRibbonViewModel.kt index 39eb3b1..a0ee28e 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/ribbon/player/PlayerRibbonViewModel.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/ribbon/player/PlayerRibbonViewModel.kt @@ -24,7 +24,7 @@ class PlayerRibbonViewModel( campaignRepository = campaignRepository, ribbonFactory = ribbonFactory, ) { - override val Campaign.data get() = characters + override val Campaign.data get() = if (options.showParty) characters else emptyMap() override val enableCharacterSheet = true override val enableCharacterStats = true diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/text/TextMessageFactory.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/text/TextMessageFactory.kt index ba4c107..34b4bbc 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/text/TextMessageFactory.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/text/TextMessageFactory.kt @@ -10,11 +10,13 @@ import com.pixelized.shared.lwa.model.AlteredCharacterSheetFactory import com.pixelized.shared.lwa.model.campaign.Campaign import com.pixelized.shared.lwa.model.campaign.CampaignJsonV1.CharacterInstanceJsonV1.CharacteristicV1.Damage import com.pixelized.shared.lwa.model.campaign.CampaignJsonV1.CharacterInstanceJsonV1.CharacteristicV1.Power -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 lwacharactersheet.composeapp.generated.resources.Res import lwacharactersheet.composeapp.generated.resources.chat__characteristic__hp import lwacharactersheet.composeapp.generated.resources.chat__characteristic__pp @@ -30,27 +32,27 @@ class TextMessageFactory( private val formatTime = SimpleDateFormat("HH:mm:ss") suspend fun convertToTextMessage( - message: Message, + message: SocketMessage, ): TextMessage? { - val time = System.currentTimeMillis() + val time = message.timestamp val id = formatId.format(time) - return when (val payload = message.value) { + return when (message) { is RollMessage -> { val sheetPreview = characterSheetRepository - .characterPreview(characterId = payload.characterSheetId) + .characterPreview(characterId = message.characterSheetId) ?: return null RollTextMessageUio( - id = "${payload.id.rollId}-${payload.id.timestamp}", + id = "${message.uuid}-${message.timestamp}", timestamp = formatTime.format(time), character = sheetPreview.name, - skillLabel = payload.skillLabel, - rollDifficulty = payload.rollDifficulty, - rollValue = payload.rollValue, - rollSuccessLimit = payload.rollSuccessLimit, - resultLabel = payload.resultLabel, - resultType = when (payload.critical) { + skillLabel = message.skillLabel, + rollDifficulty = message.rollDifficulty, + rollValue = message.rollValue, + rollSuccessLimit = message.rollSuccessLimit, + resultLabel = message.resultLabel, + resultType = when (message.critical) { RollMessage.Critical.CRITICAL_SUCCESS -> RollTextMessageUio.Critical.CRITICAL_SUCCESS RollMessage.Critical.SPECIAL_SUCCESS -> RollTextMessageUio.Critical.SPECIAL_SUCCESS RollMessage.Critical.SUCCESS -> RollTextMessageUio.Critical.SUCCESS @@ -63,25 +65,25 @@ class TextMessageFactory( is CampaignMessage.UpdateDiminished -> { val sheetPreview = characterSheetRepository - .characterPreview(characterId = payload.characterSheetId) + .characterPreview(characterId = message.characterSheetId) ?: return null DiminishedTextMessageUio( - id = "${message.from}-$id-Diminished", + id = "${message.timestamp}-$id-Diminished", timestamp = formatTime.format(time), character = sheetPreview.name, - diminished = payload.diminished, + diminished = message.diminished, ) } is CampaignMessage.UpdateCharacteristic -> { val sheet = characterSheetRepository.characterDetail( - characterSheetId = payload.characterSheetId, + characterSheetId = message.characterSheetId, ) ?: return null val characterInstanceId = Campaign.CharacterInstance.Id( - prefix = payload.prefix, - characterSheetId = payload.characterSheetId, - instanceId = payload.instanceId, + prefix = message.prefix, + characterSheetId = message.characterSheetId, + instanceId = message.instanceId, ) val alterations = alterationRepository.alterations( characterInstanceId = characterInstanceId, @@ -91,25 +93,26 @@ class TextMessageFactory( alterations = alterations, ) CharacteristicTextMessageUio( - id = "${message.from}-$id-Characteristic", + id = "${message.timestamp}-$id-Characteristic", timestamp = formatTime.format(time), character = sheet.name, - value = when (payload.characteristic) { - Damage -> alteredSheet.maxHp - payload.value - Power -> alteredSheet.maxPp - payload.value + value = when (message.characteristic) { + Damage -> alteredSheet.maxHp - message.value + Power -> alteredSheet.maxPp - message.value }, - characteristic = when (payload.characteristic) { + characteristic = when (message.characteristic) { Damage -> getString(Res.string.chat__characteristic__hp) Power -> getString(Res.string.chat__characteristic__pp) }, ) } - RestSynchronisation.Campaign -> null - is RestSynchronisation.CharacterDelete -> null - is RestSynchronisation.CharacterUpdate -> null - is RestSynchronisation.ToggleActiveAlteration -> null + is RestSynchronisation.Campaign -> null + is RestSynchronisation.CharacterSheetDelete -> null + is RestSynchronisation.CharacterSheetUpdate -> null + is ToggleActiveAlteration -> null is UpdateSkillUsageMessage -> null + is GameMasterEvent -> null } } } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/CharacterSheetViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/CharacterSheetViewModel.kt index cac6ff5..34ff48e 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/CharacterSheetViewModel.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/CharacterSheetViewModel.kt @@ -14,8 +14,8 @@ import com.pixelized.desktop.lwa.repository.network.NetworkRepository import com.pixelized.desktop.lwa.ui.navigation.screen.destination.CharacterSheetDestination import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.dialog.CharacterSheetDeleteConfirmationDialogUio import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.dialog.DiminishedStatDialogUio -import com.pixelized.shared.lwa.protocol.websocket.payload.CampaignMessage -import com.pixelized.shared.lwa.protocol.websocket.payload.UpdateSkillUsageMessage +import com.pixelized.shared.lwa.protocol.websocket.CampaignMessage +import com.pixelized.shared.lwa.protocol.websocket.UpdateSkillUsageMessage import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine @@ -80,7 +80,8 @@ class CharacterSheetViewModel( fun onUseSkill(skill: CharacterSheetPageUio.Node) { viewModelScope.launch { network.share( - payload = UpdateSkillUsageMessage( + message = UpdateSkillUsageMessage( + timestamp = System.currentTimeMillis(), characterSheetId = argument.characterInstanceId.characterSheetId, skillId = skill.id, used = skill.used.not(), @@ -143,7 +144,8 @@ class CharacterSheetViewModel( suspend fun changeDiminished(dialog: DiminishedStatDialogUio) { val diminished = dialog.value().text.toIntOrNull() ?: 0 network.share( - payload = CampaignMessage.UpdateDiminished( + message = CampaignMessage.UpdateDiminished( + timestamp = System.currentTimeMillis(), prefix = dialog.characterInstanceId.prefix, characterSheetId = dialog.characterInstanceId.characterSheetId, instanceId = dialog.characterInstanceId.instanceId, diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/GameMasterScreen.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/GameMasterScreen.kt index 274c406..2fd3933 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/GameMasterScreen.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/GameMasterScreen.kt @@ -29,9 +29,7 @@ import androidx.compose.material.MaterialTheme import androidx.compose.material.Scaffold import androidx.compose.material.Surface import androidx.compose.material.Switch -import androidx.compose.material.SwitchColors import androidx.compose.material.Text -import androidx.compose.material.TextFieldDefaults import androidx.compose.material.TopAppBar import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add @@ -43,7 +41,6 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.pixelized.desktop.lwa.LocalWindowController @@ -63,6 +60,8 @@ import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__ed import lwacharactersheet.composeapp.generated.resources.game_master__action import lwacharactersheet.composeapp.generated.resources.game_master__title import lwacharactersheet.composeapp.generated.resources.ic_cancel_24dp +import lwacharactersheet.composeapp.generated.resources.ic_visibility_24dp +import lwacharactersheet.composeapp.generated.resources.ic_visibility_off_24dp import org.jetbrains.compose.resources.getString import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.stringResource @@ -77,6 +76,7 @@ fun GameMasterScreen( val characters = viewModel.characters.collectAsState() val gameMaster = viewModel.gameMaster.collectAsState() + val npcVisibility = viewModel.npcVisibility.collectAsState() val tags = viewModel.tags.collectAsState() Surface( @@ -87,6 +87,7 @@ fun GameMasterScreen( filter = viewModel.filter, tags = tags, gameMaster = gameMaster, + npcVisibility = npcVisibility, characters = characters, onTag = viewModel::onTag, onGameMaster = viewModel::onGameMaster, @@ -107,6 +108,11 @@ fun GameMasterScreen( ) } }, + onNpcVisibility = { + scope.launch { + viewModel.onNpcVisibility() + } + }, ) } } @@ -120,16 +126,18 @@ private fun GameMasterContent( filter: LwaTextFieldUio, tags: State>, gameMaster: State, + npcVisibility: State, characters: State>, onGameMaster: (Boolean) -> Unit, onTag: (GMTagUio.TagId) -> Unit, onCharacterAction: (String, GMCharacterUio.Action) -> Unit, onCharacterSheetEdit: (String) -> Unit, onCharacterSheetCreate: () -> Unit, + onNpcVisibility: () -> Unit, ) { val scope = rememberCoroutineScope() - Scaffold( + GameMasterLayout( modifier = modifier, topBar = { TopAppBar( @@ -161,10 +169,8 @@ private fun GameMasterContent( } ) }, - content = { paddingValues -> - Column( - modifier = Modifier.padding(paddingValues = paddingValues) - ) { + content = { + Column { Surface( elevation = 1.dp, ) { @@ -210,7 +216,6 @@ private fun GameMasterContent( items = tags.value, ) { tag -> GMTag( - style = MaterialTheme.lwa.typography.base.caption, tag = tag, onTag = { onTag(tag.id) }, ) @@ -219,7 +224,9 @@ private fun GameMasterContent( } } Box( - modifier = Modifier.fillMaxWidth().weight(1f), + modifier = Modifier + .fillMaxWidth() + .weight(1f), ) { LazyColumn( modifier = Modifier.matchParentSize(), @@ -251,22 +258,71 @@ private fun GameMasterContent( ) } } - IconButton( - modifier = Modifier - .align(alignment = Alignment.BottomEnd) - .padding(all = padding) - .background( - color = MaterialTheme.lwa.colorScheme.base.primary, - shape = CircleShape, - ), - onClick = onCharacterSheetCreate, - ) { - Icon( - imageVector = Icons.Default.Add, - tint = MaterialTheme.lwa.colorScheme.base.onPrimary, - contentDescription = null, - ) - } + } + } + }, + fab = { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(all = padding), + horizontalArrangement = Arrangement.SpaceBetween, + ) { + IconButton( + modifier = Modifier.background( + color = MaterialTheme.lwa.colorScheme.base.primary, + shape = CircleShape, + ), + onClick = onNpcVisibility, + ) { + Icon( + painter = when (npcVisibility.value) { + true -> painterResource(Res.drawable.ic_visibility_off_24dp) + else -> painterResource(Res.drawable.ic_visibility_24dp) + }, + tint = MaterialTheme.lwa.colorScheme.base.onPrimary, + contentDescription = null, + ) + } + IconButton( + modifier = Modifier.background( + color = MaterialTheme.lwa.colorScheme.base.primary, + shape = CircleShape, + ), + onClick = onCharacterSheetCreate, + ) { + Icon( + imageVector = Icons.Default.Add, + tint = MaterialTheme.lwa.colorScheme.base.onPrimary, + contentDescription = null, + ) + } + } + } + ) +} + +@Composable +private fun GameMasterLayout( + modifier: Modifier, + topBar: @Composable () -> Unit, + content: @Composable () -> Unit, + fab: @Composable () -> Unit, +) { + Scaffold( + modifier = modifier, + topBar = topBar, + content = { paddingValues -> + Box( + modifier = Modifier + .fillMaxSize() + .padding(paddingValues = paddingValues) + ) { + content() + Row( + modifier = Modifier.align(alignment = Alignment.BottomStart), + ) { + fab() } } } diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/GameMasterViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/GameMasterViewModel.kt index 8e9e986..9b9824b 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/GameMasterViewModel.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/GameMasterViewModel.kt @@ -4,11 +4,13 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.pixelized.desktop.lwa.repository.campaign.CampaignRepository import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository +import com.pixelized.desktop.lwa.repository.network.NetworkRepository import com.pixelized.desktop.lwa.repository.settings.SettingsRepository import com.pixelized.desktop.lwa.ui.composable.textfield.LwaTextFieldUio import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMCharacterUio import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMTagUio import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMTagUio.TagId +import com.pixelized.shared.lwa.protocol.websocket.GameMasterEvent import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.combine @@ -26,6 +28,7 @@ class GameMasterViewModel( campaignRepository: CampaignRepository, characterSheetRepository: CharacterSheetRepository, private val settingsRepository: SettingsRepository, + private val networkRepository: NetworkRepository, private val factory: GameMasterFactory, private val useCase: GameMasterActionUseCase, ) : ViewModel() { @@ -82,6 +85,14 @@ class GameMasterViewModel( initialValue = false, ) + val npcVisibility = campaignRepository.campaignFlow + .map { it.options.showNpcs } + .stateIn( + scope = viewModelScope, + started = SharingStarted.Eagerly, + initialValue = false, + ) + fun onGameMaster(value: Boolean) { val settings = settingsRepository.settings() settingsRepository.update( @@ -114,4 +125,12 @@ class GameMasterViewModel( it[id] = it.getOrPut(id) { true }.not() } } + + suspend fun onNpcVisibility() { + networkRepository.share( + GameMasterEvent.ToggleNpc( + timestamp = System.currentTimeMillis(), + ) + ) + } } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/items/GMCharacter.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/items/GMCharacter.kt index 521c527..24f5d51 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/items/GMCharacter.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/items/GMCharacter.kt @@ -144,7 +144,6 @@ fun GMCharacter( ) { character.tags.forEach { tag -> GMTag( - style = MaterialTheme.lwa.typography.base.caption, elevation = 4.dp, tag = tag, ) diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/items/GMTagUio.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/items/GMTagUio.kt index eeca5b1..1204be8 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/items/GMTagUio.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/gamemaster/items/GMTagUio.kt @@ -41,7 +41,6 @@ fun GMTag( padding: PaddingValues = GmTagDefault.padding, shape: Shape = CircleShape, elevation: Dp = 2.dp, - style: TextStyle, tag: GMTagUio, onTag: (() -> Unit)? = null, ) { @@ -60,7 +59,7 @@ fun GMTag( modifier = Modifier .clickable(enabled = onTag != null) { onTag?.invoke() } .padding(paddingValues = padding), - style = style, + style = MaterialTheme.lwa.typography.base.caption, color = animatedColor.value, text = tag.label, ) diff --git a/server/src/main/kotlin/com/pixelized/server/lwa/model/campaign/CampaignService.kt b/server/src/main/kotlin/com/pixelized/server/lwa/model/campaign/CampaignService.kt index bea1a98..6db9688 100644 --- a/server/src/main/kotlin/com/pixelized/server/lwa/model/campaign/CampaignService.kt +++ b/server/src/main/kotlin/com/pixelized/server/lwa/model/campaign/CampaignService.kt @@ -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() + ) + ) + ) + } } \ No newline at end of file diff --git a/server/src/main/kotlin/com/pixelized/server/lwa/server/Engine.kt b/server/src/main/kotlin/com/pixelized/server/lwa/server/Engine.kt index 686c650..9bda4df 100644 --- a/server/src/main/kotlin/com/pixelized/server/lwa/server/Engine.kt +++ b/server/src/main/kotlin/com/pixelized/server/lwa/server/Engine.kt @@ -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() + val webSocket = MutableSharedFlow() - 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() + } } } } \ No newline at end of file diff --git a/server/src/main/kotlin/com/pixelized/server/lwa/server/Server.kt b/server/src/main/kotlin/com/pixelized/server/lwa/server/Server.kt index 4a05be3..a5dc028 100644 --- a/server/src/main/kotlin/com/pixelized/server/lwa/server/Server.kt +++ b/server/src/main/kotlin/com/pixelized/server/lwa/server/Server.kt @@ -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(data) + val message = json.decodeFromString(data) // log the message engine.handle(message) // broadcast to clients the message diff --git a/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/alteration/PUT_ActiveAlteration.kt b/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/alteration/PUT_ActiveAlteration.kt index 751a956..dc5edb0 100644 --- a/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/alteration/PUT_ActiveAlteration.kt +++ b/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/alteration/PUT_ActiveAlteration.kt @@ -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 ), ) ) diff --git a/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/campaign/DELETE_Campaign_character.kt b/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/campaign/DELETE_Campaign_character.kt index aa7afc1..a6d17d1 100644 --- a/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/campaign/DELETE_Campaign_character.kt +++ b/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/campaign/DELETE_Campaign_character.kt @@ -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) { diff --git a/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/campaign/DELETE_Campaign_npc.kt b/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/campaign/DELETE_Campaign_npc.kt index 0dd016b..967edb6 100644 --- a/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/campaign/DELETE_Campaign_npc.kt +++ b/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/campaign/DELETE_Campaign_npc.kt @@ -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) { diff --git a/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/campaign/PUT_Campaign_Scene_Name.kt b/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/campaign/PUT_Campaign_Scene_Name.kt index 146f9af..1a73d35 100644 --- a/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/campaign/PUT_Campaign_Scene_Name.kt +++ b/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/campaign/PUT_Campaign_Scene_Name.kt @@ -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(), ) ) } diff --git a/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/campaign/PUT_Campaign_character.kt b/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/campaign/PUT_Campaign_character.kt index e22a35e..e98ade9 100644 --- a/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/campaign/PUT_Campaign_character.kt +++ b/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/campaign/PUT_Campaign_character.kt @@ -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) { diff --git a/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/campaign/PUT_Campaign_npc.kt b/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/campaign/PUT_Campaign_npc.kt index ec7b174..1a58990 100644 --- a/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/campaign/PUT_Campaign_npc.kt +++ b/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/campaign/PUT_Campaign_npc.kt @@ -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) { diff --git a/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/character/DELETE_Character.kt b/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/character/DELETE_Character.kt index 4997dd0..afb6733 100644 --- a/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/character/DELETE_Character.kt +++ b/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/character/DELETE_Character.kt @@ -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( diff --git a/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/character/PUT_Character.kt b/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/character/PUT_Character.kt index 4686b65..044b994 100644 --- a/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/character/PUT_Character.kt +++ b/server/src/main/kotlin/com/pixelized/server/lwa/server/rest/character/PUT_Character.kt @@ -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, + ), ) } } \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/campaign/Campaign.kt b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/campaign/Campaign.kt index 5ab1f30..c7aceaf 100644 --- a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/campaign/Campaign.kt +++ b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/campaign/Campaign.kt @@ -4,6 +4,7 @@ data class Campaign( val characters: Map, val npcs: Map, val scene: Scene, + val options: Options, ) { data class CharacterInstance( val characteristic: Map, @@ -53,11 +54,24 @@ data class Campaign( } } + data class Options( + val showParty: Boolean, + val showNpcs: Boolean, + ) { + companion object { + fun empty() = Options( + showParty = true, + showNpcs = false, + ) + } + } + companion object { val EMPTY = Campaign( characters = emptyMap(), npcs = emptyMap(), scene = Scene.empty(), + options = Options.empty(), ) } } diff --git a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/campaign/CampaignJson.kt b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/campaign/CampaignJson.kt index 0fe01ce..6fc8fe9 100644 --- a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/campaign/CampaignJson.kt +++ b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/campaign/CampaignJson.kt @@ -14,4 +14,7 @@ sealed interface CampaignJson { @Serializable sealed interface SceneJson + + @Serializable + sealed interface OptionJson } \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/campaign/CampaignJsonV1.kt b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/campaign/CampaignJsonV1.kt index 67bb6f7..ea0483f 100644 --- a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/campaign/CampaignJsonV1.kt +++ b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/campaign/CampaignJsonV1.kt @@ -7,6 +7,7 @@ data class CampaignJsonV1( val characters: Map, val npcs: Map, val scene: SceneJsonV1?, + val options: OptionsJsonV1?, ) : CampaignJson { @Serializable @@ -24,4 +25,10 @@ data class CampaignJsonV1( data class SceneJsonV1( val name: String, ) : CampaignJson.SceneJson + + @Serializable + data class OptionsJsonV1( + val showPlayer: Boolean, + val showNpcs: Boolean, + ) : CampaignJson.OptionJson } diff --git a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/campaign/factory/CampaignJsonFactory.kt b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/campaign/factory/CampaignJsonFactory.kt index 017aa3f..a142acd 100644 --- a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/campaign/factory/CampaignJsonFactory.kt +++ b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/campaign/factory/CampaignJsonFactory.kt @@ -58,6 +58,10 @@ class CampaignJsonFactory( .toMap(), scene = CampaignJsonV1.SceneJsonV1( name = data.scene.name + ), + options = CampaignJsonV1.OptionsJsonV1( + showPlayer = data.options.showParty, + showNpcs = data.options.showNpcs, ) ) } diff --git a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/campaign/factory/CampaignJsonV1Factory.kt b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/campaign/factory/CampaignJsonV1Factory.kt index 0695336..02fb187 100644 --- a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/campaign/factory/CampaignJsonV1Factory.kt +++ b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/model/campaign/factory/CampaignJsonV1Factory.kt @@ -26,6 +26,9 @@ class CampaignJsonV1Factory { scene = campaignJson.scene ?.let { convertFromV1(it) } ?: Campaign.Scene.empty(), + options = campaignJson.options + ?.let { convertFromV1(it) } + ?:Campaign.Options.empty() ) } @@ -66,4 +69,13 @@ class CampaignJsonV1Factory { name = sceneJson.name ) } + + fun convertFromV1( + optionsJson: CampaignJsonV1.OptionsJsonV1, + ): Campaign.Options { + return Campaign.Options( + showParty = optionsJson.showPlayer, + showNpcs = optionsJson.showNpcs + ) + } } \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/payload/CampaignMessage.kt b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/CampaignMessage.kt similarity index 67% rename from shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/payload/CampaignMessage.kt rename to shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/CampaignMessage.kt index 00a6525..f651f15 100644 --- a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/payload/CampaignMessage.kt +++ b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/CampaignMessage.kt @@ -1,16 +1,17 @@ -package com.pixelized.shared.lwa.protocol.websocket.payload +package com.pixelized.shared.lwa.protocol.websocket import com.pixelized.shared.lwa.model.campaign.CampaignJsonV1 import kotlinx.serialization.Serializable @Serializable -sealed interface CampaignMessage : MessagePayload { - val prefix: Char - val characterSheetId: String - val instanceId: Int +sealed interface CampaignMessage : SocketMessage, CharacterInstanceIdMessage { + override val prefix: Char + override val characterSheetId: String + override val instanceId: Int @Serializable data class UpdateCharacteristic( + override val timestamp: Long, override val prefix: Char, override val characterSheetId: String, override val instanceId: Int, @@ -20,6 +21,7 @@ sealed interface CampaignMessage : MessagePayload { @Serializable data class UpdateDiminished( + override val timestamp: Long, override val prefix: Char, override val characterSheetId: String, override val instanceId: Int, diff --git a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/CharacterInstanceIdMessage.kt b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/CharacterInstanceIdMessage.kt new file mode 100644 index 0000000..9b1984b --- /dev/null +++ b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/CharacterInstanceIdMessage.kt @@ -0,0 +1,15 @@ +package com.pixelized.shared.lwa.protocol.websocket + +import kotlinx.serialization.Serializable + +@Serializable +sealed interface CharacterSheetIdMessage { + val characterSheetId: String +} + +@Serializable +sealed interface CharacterInstanceIdMessage : CharacterSheetIdMessage { + override val characterSheetId: String + val prefix: Char + val instanceId: Int +} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/GameMasterEvent.kt b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/GameMasterEvent.kt new file mode 100644 index 0000000..85b4ec6 --- /dev/null +++ b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/GameMasterEvent.kt @@ -0,0 +1,17 @@ +package com.pixelized.shared.lwa.protocol.websocket + +import kotlinx.serialization.Serializable + +@Serializable +sealed interface GameMasterEvent : SocketMessage { + + @Serializable + class ToggleNpc( + override val timestamp: Long, + ) : GameMasterEvent + + @Serializable + class TogglePlayer( + override val timestamp: Long, + ) : GameMasterEvent +} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/Message.kt b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/Message.kt deleted file mode 100644 index 518d9aa..0000000 --- a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/Message.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.pixelized.shared.lwa.protocol.websocket - -import com.pixelized.shared.lwa.protocol.websocket.payload.MessagePayload -import kotlinx.serialization.Serializable - -@Serializable -data class Message( - val from: String, - val value: MessagePayload, -) \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/RestSynchronisation.kt b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/RestSynchronisation.kt new file mode 100644 index 0000000..98e0209 --- /dev/null +++ b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/RestSynchronisation.kt @@ -0,0 +1,24 @@ +package com.pixelized.shared.lwa.protocol.websocket + +import kotlinx.serialization.Serializable + +@Serializable +sealed class RestSynchronisation : SocketMessage { + + @Serializable + data class CharacterSheetUpdate( + override val timestamp: Long, + override val characterSheetId: String, + ) : RestSynchronisation(), CharacterSheetIdMessage + + @Serializable + data class CharacterSheetDelete( + override val timestamp: Long, + override val characterSheetId: String, + ) : RestSynchronisation(), CharacterSheetIdMessage + + @Serializable + data class Campaign( + override val timestamp: Long, + ) : RestSynchronisation() +} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/RollMessage.kt b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/RollMessage.kt new file mode 100644 index 0000000..821b696 --- /dev/null +++ b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/RollMessage.kt @@ -0,0 +1,26 @@ +package com.pixelized.shared.lwa.protocol.websocket + +import kotlinx.serialization.Serializable + +@Serializable +data class RollMessage( + override val timestamp: Long, + val uuid: String, + val prefix: Char, + val characterSheetId: String, + val instanceId: Int?, + val skillLabel: String, + val rollValue: Int, + val resultLabel: String? = null, + val rollDifficulty: String? = null, + val rollSuccessLimit: Int? = null, + val critical: Critical? = null, +) : SocketMessage { + enum class Critical { + CRITICAL_SUCCESS, + SPECIAL_SUCCESS, + SUCCESS, + FAILURE, + CRITICAL_FAILURE + } +} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/SocketMessage.kt b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/SocketMessage.kt new file mode 100644 index 0000000..ed29154 --- /dev/null +++ b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/SocketMessage.kt @@ -0,0 +1,8 @@ +package com.pixelized.shared.lwa.protocol.websocket + +import kotlinx.serialization.Serializable + +@Serializable +sealed interface SocketMessage { + val timestamp: Long +} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/ToggleActiveAlteration.kt b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/ToggleActiveAlteration.kt new file mode 100644 index 0000000..23fbb45 --- /dev/null +++ b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/ToggleActiveAlteration.kt @@ -0,0 +1,13 @@ +package com.pixelized.shared.lwa.protocol.websocket + +import kotlinx.serialization.Serializable + +@Serializable +data class ToggleActiveAlteration( + override val timestamp: Long, + override val characterSheetId: String, + override val prefix: Char, + override val instanceId: Int, + val alterationId: String, + val active: Boolean, +) : SocketMessage, CharacterInstanceIdMessage \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/UpdateSkillUsageMessage.kt b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/UpdateSkillUsageMessage.kt new file mode 100644 index 0000000..67a4c01 --- /dev/null +++ b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/UpdateSkillUsageMessage.kt @@ -0,0 +1,11 @@ +package com.pixelized.shared.lwa.protocol.websocket + +import kotlinx.serialization.Serializable + +@Serializable +data class UpdateSkillUsageMessage( + override val timestamp: Long, + override val characterSheetId: String, + val skillId: String, + val used: Boolean, +) : SocketMessage, CharacterSheetIdMessage \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/payload/MessagePayload.kt b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/payload/MessagePayload.kt deleted file mode 100644 index b9eaa8a..0000000 --- a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/payload/MessagePayload.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.pixelized.shared.lwa.protocol.websocket.payload - -import kotlinx.serialization.Serializable - -@Serializable -sealed interface MessagePayload \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/payload/RestSynchronisation.kt b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/payload/RestSynchronisation.kt deleted file mode 100644 index 5d7be8c..0000000 --- a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/payload/RestSynchronisation.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.pixelized.shared.lwa.protocol.websocket.payload - -import kotlinx.serialization.Serializable - -@Serializable -sealed class RestSynchronisation : MessagePayload { - - @Serializable - data class CharacterUpdate( - val id: String, - ) : RestSynchronisation() - - @Serializable - data class CharacterDelete( - val characterId: String, - ) : RestSynchronisation() - - @Serializable - data class ToggleActiveAlteration( - val characterId: String, - val alterationId: String, - val active: Boolean, - ) : RestSynchronisation() - - @Serializable - data object Campaign : RestSynchronisation() -} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/payload/RollMessage.kt b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/payload/RollMessage.kt deleted file mode 100644 index d5e76ad..0000000 --- a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/payload/RollMessage.kt +++ /dev/null @@ -1,43 +0,0 @@ -package com.pixelized.shared.lwa.protocol.websocket.payload - -import kotlinx.serialization.Serializable -import java.util.UUID - -@Serializable -data class RollMessage( - val id: RollId, - val prefix: Char, - val characterSheetId: String, - val instanceId: Int?, - val skillLabel: String, - val rollValue: Int, - val resultLabel: String? = null, - val rollDifficulty: String? = null, - val rollSuccessLimit: Int? = null, - val critical: Critical? = null, -) : MessagePayload { - - @Serializable - data class RollId( - val rollId: String, - val timestamp: Long, - ) { - companion object { - fun create( - rollId: String = UUID.randomUUID().toString(), - timestamp: Long = System.currentTimeMillis(), - ) = RollId( - rollId = rollId, - timestamp = timestamp, - ) - } - } - - enum class Critical { - CRITICAL_SUCCESS, - SPECIAL_SUCCESS, - SUCCESS, - FAILURE, - CRITICAL_FAILURE - } -} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/payload/UpdateSkillUsageMessage.kt b/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/payload/UpdateSkillUsageMessage.kt deleted file mode 100644 index a11c140..0000000 --- a/shared/src/commonMain/kotlin/com/pixelized/shared/lwa/protocol/websocket/payload/UpdateSkillUsageMessage.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.pixelized.shared.lwa.protocol.websocket.payload - -import kotlinx.serialization.Serializable - -@Serializable -data class UpdateSkillUsageMessage( - val characterSheetId: String, - val skillId: String, - val used: Boolean, -) : MessagePayload \ No newline at end of file