Add inventory managment to server.
This commit is contained in:
parent
04b203239d
commit
4f33492b23
18 changed files with 499 additions and 7 deletions
|
|
@ -4,6 +4,8 @@ import com.pixelized.server.lwa.model.campaign.CampaignService
|
||||||
import com.pixelized.server.lwa.model.campaign.CampaignStore
|
import com.pixelized.server.lwa.model.campaign.CampaignStore
|
||||||
import com.pixelized.server.lwa.model.character.CharacterSheetService
|
import com.pixelized.server.lwa.model.character.CharacterSheetService
|
||||||
import com.pixelized.server.lwa.model.character.CharacterSheetStore
|
import com.pixelized.server.lwa.model.character.CharacterSheetStore
|
||||||
|
import com.pixelized.server.lwa.model.inventory.InventoryService
|
||||||
|
import com.pixelized.server.lwa.model.inventory.InventoryStore
|
||||||
import com.pixelized.server.lwa.model.item.ItemService
|
import com.pixelized.server.lwa.model.item.ItemService
|
||||||
import com.pixelized.server.lwa.model.item.ItemStore
|
import com.pixelized.server.lwa.model.item.ItemStore
|
||||||
import com.pixelized.server.lwa.model.tag.TagService
|
import com.pixelized.server.lwa.model.tag.TagService
|
||||||
|
|
@ -36,18 +38,20 @@ val engineDependencies
|
||||||
|
|
||||||
val storeDependencies
|
val storeDependencies
|
||||||
get() = module {
|
get() = module {
|
||||||
singleOf(::CharacterSheetStore)
|
|
||||||
singleOf(::CampaignStore)
|
|
||||||
singleOf(::AlterationStore)
|
singleOf(::AlterationStore)
|
||||||
singleOf(::TagStore)
|
singleOf(::CampaignStore)
|
||||||
|
singleOf(::CharacterSheetStore)
|
||||||
|
singleOf(::InventoryStore)
|
||||||
singleOf(::ItemStore)
|
singleOf(::ItemStore)
|
||||||
|
singleOf(::TagStore)
|
||||||
}
|
}
|
||||||
|
|
||||||
val serviceDependencies
|
val serviceDependencies
|
||||||
get() = module {
|
get() = module {
|
||||||
singleOf(::CharacterSheetService)
|
|
||||||
singleOf(::CampaignService)
|
|
||||||
singleOf(::AlterationService)
|
singleOf(::AlterationService)
|
||||||
|
singleOf(::CampaignService)
|
||||||
|
singleOf(::CharacterSheetService)
|
||||||
|
singleOf(::InventoryService)
|
||||||
singleOf(::ItemService)
|
singleOf(::ItemService)
|
||||||
singleOf(::TagService)
|
singleOf(::TagService)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.pixelized.server.lwa.model.inventory
|
||||||
|
|
||||||
|
import com.pixelized.shared.lwa.model.inventory.Inventory
|
||||||
|
import com.pixelized.shared.lwa.model.inventory.InventoryJson
|
||||||
|
import com.pixelized.shared.lwa.model.inventory.factory.InventoryJsonFactory
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.flow.stateIn
|
||||||
|
|
||||||
|
class InventoryService(
|
||||||
|
private val inventoryStore: InventoryStore,
|
||||||
|
private val factory: InventoryJsonFactory,
|
||||||
|
) {
|
||||||
|
private val scope = CoroutineScope(Dispatchers.IO + Job())
|
||||||
|
|
||||||
|
private val inventoryJson = inventoryStore.inventoryFlow()
|
||||||
|
.map { it.mapValues { entry -> factory.convertToJson(inventory = entry.value) } }
|
||||||
|
.stateIn(
|
||||||
|
scope = scope,
|
||||||
|
started = SharingStarted.Eagerly,
|
||||||
|
initialValue = emptyMap()
|
||||||
|
)
|
||||||
|
|
||||||
|
fun inventory(characterSheetId: String): Inventory {
|
||||||
|
return inventoryStore.inventoryFlow().value[characterSheetId]
|
||||||
|
?: Inventory.empty(characterSheetId = characterSheetId)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun inventoryJson(characterSheetId: String): InventoryJson {
|
||||||
|
return inventoryJson.value[characterSheetId]
|
||||||
|
?: factory.convertToJson(Inventory.empty(characterSheetId = characterSheetId))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws
|
||||||
|
fun save(
|
||||||
|
inventoryJson: InventoryJson,
|
||||||
|
create: Boolean,
|
||||||
|
) {
|
||||||
|
inventoryStore.save(
|
||||||
|
inventory = factory.convertFromJson(json = inventoryJson),
|
||||||
|
create = create,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws
|
||||||
|
fun delete(characterSheetId: String) {
|
||||||
|
inventoryStore.delete(characterSheetId = characterSheetId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,158 @@
|
||||||
|
package com.pixelized.server.lwa.model.inventory
|
||||||
|
|
||||||
|
import com.pixelized.server.lwa.server.exception.BusinessException
|
||||||
|
import com.pixelized.server.lwa.server.exception.FileReadException
|
||||||
|
import com.pixelized.server.lwa.server.exception.FileWriteException
|
||||||
|
import com.pixelized.server.lwa.server.exception.JsonCodingException
|
||||||
|
import com.pixelized.server.lwa.server.exception.JsonConversionException
|
||||||
|
import com.pixelized.shared.lwa.model.inventory.Inventory
|
||||||
|
import com.pixelized.shared.lwa.model.inventory.InventoryJson
|
||||||
|
import com.pixelized.shared.lwa.model.inventory.factory.InventoryJsonFactory
|
||||||
|
import com.pixelized.shared.lwa.protocol.rest.APIResponse
|
||||||
|
import com.pixelized.shared.lwa.utils.PathProvider
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.update
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class InventoryStore(
|
||||||
|
private val pathProvider: PathProvider,
|
||||||
|
private val factory: InventoryJsonFactory,
|
||||||
|
private val json: Json,
|
||||||
|
) {
|
||||||
|
private val directory = File(pathProvider.inventoryPath()).also { it.mkdirs() }
|
||||||
|
private val inventoryFlow = MutableStateFlow<Map<String, Inventory>>(value = emptyMap())
|
||||||
|
|
||||||
|
init {
|
||||||
|
// build a coroutine scope for async calls
|
||||||
|
val scope = CoroutineScope(Dispatchers.IO + Job())
|
||||||
|
// load the initial data
|
||||||
|
scope.launch {
|
||||||
|
updateInventoryFlow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun inventoryFlow(): StateFlow<Map<String, Inventory>> = inventoryFlow
|
||||||
|
|
||||||
|
private suspend fun updateInventoryFlow() {
|
||||||
|
inventoryFlow.value = try {
|
||||||
|
load()
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
println(exception.message) // TODO proper exception handling
|
||||||
|
emptyMap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(
|
||||||
|
FileReadException::class,
|
||||||
|
JsonCodingException::class,
|
||||||
|
JsonConversionException::class,
|
||||||
|
)
|
||||||
|
private fun load(
|
||||||
|
directory: File = this.directory,
|
||||||
|
): Map<String, Inventory> {
|
||||||
|
return directory
|
||||||
|
.listFiles()
|
||||||
|
?.mapNotNull { file ->
|
||||||
|
val json = try {
|
||||||
|
file.readText(charset = Charsets.UTF_8)
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
throw FileReadException(root = exception)
|
||||||
|
}
|
||||||
|
// Guard, if the json is blank no character have been save, ignore this file.
|
||||||
|
if (json.isBlank()) {
|
||||||
|
return@mapNotNull null
|
||||||
|
}
|
||||||
|
// decode the file
|
||||||
|
val data = try {
|
||||||
|
this.json.decodeFromString<InventoryJson>(json)
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
throw JsonCodingException(root = exception)
|
||||||
|
}
|
||||||
|
// parse the json string.
|
||||||
|
val inventory = try {
|
||||||
|
factory.convertFromJson(data)
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
throw JsonConversionException(root = exception)
|
||||||
|
}
|
||||||
|
file.name to inventory
|
||||||
|
}
|
||||||
|
?.toMap()
|
||||||
|
?: emptyMap()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(
|
||||||
|
BusinessException::class,
|
||||||
|
JsonConversionException::class,
|
||||||
|
JsonCodingException::class,
|
||||||
|
FileWriteException::class,
|
||||||
|
)
|
||||||
|
fun save(
|
||||||
|
inventory: Inventory,
|
||||||
|
create: Boolean,
|
||||||
|
) {
|
||||||
|
val file = inventoryFile(id = inventory.characterSheetId)
|
||||||
|
|
||||||
|
if (create && file.exists()) {
|
||||||
|
throw BusinessException(message = "Inventory already exist, creation is impossible.")
|
||||||
|
}
|
||||||
|
|
||||||
|
val json = try {
|
||||||
|
factory.convertToJson(inventory = inventory)
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
throw JsonConversionException(root = exception)
|
||||||
|
}
|
||||||
|
|
||||||
|
val data = try {
|
||||||
|
this.json.encodeToString(json)
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
throw JsonCodingException(root = exception)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
file.writeText(
|
||||||
|
text = data,
|
||||||
|
charset = Charsets.UTF_8,
|
||||||
|
)
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
throw FileWriteException(root = exception)
|
||||||
|
}
|
||||||
|
|
||||||
|
inventoryFlow.update { flow ->
|
||||||
|
flow.toMutableMap().also { data ->
|
||||||
|
data[inventory.characterSheetId] = inventory
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(BusinessException::class)
|
||||||
|
fun delete(characterSheetId: String) {
|
||||||
|
val file = inventoryFile(id = characterSheetId)
|
||||||
|
|
||||||
|
if (file.exists().not()) {
|
||||||
|
throw BusinessException(
|
||||||
|
message = "Inventory file with id:$characterSheetId doesn't not exist.",
|
||||||
|
code = APIResponse.ErrorCode.CharacterSheetId
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.delete().not()) {
|
||||||
|
throw BusinessException(
|
||||||
|
message = "Inventory file have not been deleted for unknown reason.",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
inventoryFlow.update { characters ->
|
||||||
|
characters.toMutableMap().also { data -> data.remove(characterSheetId) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun inventoryFile(id: String): File {
|
||||||
|
return File("${pathProvider.inventoryPath()}${id}.json")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -27,7 +27,6 @@ class ItemStore(
|
||||||
private val json: Json,
|
private val json: Json,
|
||||||
) {
|
) {
|
||||||
private val directory = File(pathProvider.itemsPath()).also { it.mkdirs() }
|
private val directory = File(pathProvider.itemsPath()).also { it.mkdirs() }
|
||||||
|
|
||||||
private val itemFlow = MutableStateFlow<List<Item>>(emptyList())
|
private val itemFlow = MutableStateFlow<List<Item>>(emptyList())
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package com.pixelized.server.lwa.server
|
||||||
import com.pixelized.server.lwa.model.alteration.AlterationService
|
import com.pixelized.server.lwa.model.alteration.AlterationService
|
||||||
import com.pixelized.server.lwa.model.campaign.CampaignService
|
import com.pixelized.server.lwa.model.campaign.CampaignService
|
||||||
import com.pixelized.server.lwa.model.character.CharacterSheetService
|
import com.pixelized.server.lwa.model.character.CharacterSheetService
|
||||||
|
import com.pixelized.server.lwa.model.inventory.InventoryService
|
||||||
import com.pixelized.server.lwa.model.item.ItemService
|
import com.pixelized.server.lwa.model.item.ItemService
|
||||||
import com.pixelized.server.lwa.model.tag.TagService
|
import com.pixelized.server.lwa.model.tag.TagService
|
||||||
import com.pixelized.shared.lwa.model.campaign.factory.CampaignJsonFactory
|
import com.pixelized.shared.lwa.model.campaign.factory.CampaignJsonFactory
|
||||||
|
|
@ -19,6 +20,7 @@ class Engine(
|
||||||
val campaignService: CampaignService,
|
val campaignService: CampaignService,
|
||||||
val alterationService: AlterationService,
|
val alterationService: AlterationService,
|
||||||
val itemService: ItemService,
|
val itemService: ItemService,
|
||||||
|
val inventoryService: InventoryService,
|
||||||
val tagService: TagService,
|
val tagService: TagService,
|
||||||
val campaignJsonFactory: CampaignJsonFactory,
|
val campaignJsonFactory: CampaignJsonFactory,
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,9 @@ import com.pixelized.server.lwa.server.rest.character.putCharacterAlteration
|
||||||
import com.pixelized.server.lwa.server.rest.character.putCharacterDamage
|
import com.pixelized.server.lwa.server.rest.character.putCharacterDamage
|
||||||
import com.pixelized.server.lwa.server.rest.character.putCharacterDiminished
|
import com.pixelized.server.lwa.server.rest.character.putCharacterDiminished
|
||||||
import com.pixelized.server.lwa.server.rest.character.putCharacterFatigue
|
import com.pixelized.server.lwa.server.rest.character.putCharacterFatigue
|
||||||
|
import com.pixelized.server.lwa.server.rest.inventory.deleteInventory
|
||||||
|
import com.pixelized.server.lwa.server.rest.inventory.getInventory
|
||||||
|
import com.pixelized.server.lwa.server.rest.inventory.putInventory
|
||||||
import com.pixelized.server.lwa.server.rest.item.deleteItem
|
import com.pixelized.server.lwa.server.rest.item.deleteItem
|
||||||
import com.pixelized.server.lwa.server.rest.item.getItem
|
import com.pixelized.server.lwa.server.rest.item.getItem
|
||||||
import com.pixelized.server.lwa.server.rest.item.getItems
|
import com.pixelized.server.lwa.server.rest.item.getItems
|
||||||
|
|
@ -246,6 +249,20 @@ class LocalServer {
|
||||||
body = engine.getItemTags(),
|
body = engine.getItemTags(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
route(path = "inventory") {
|
||||||
|
get(
|
||||||
|
path = "/detail",
|
||||||
|
body = engine.getInventory(),
|
||||||
|
)
|
||||||
|
put(
|
||||||
|
path = "/update",
|
||||||
|
body = engine.putInventory()
|
||||||
|
)
|
||||||
|
delete(
|
||||||
|
path = "/delete",
|
||||||
|
body = engine.deleteInventory()
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.pixelized.server.lwa.server.rest.inventory
|
||||||
|
|
||||||
|
import com.pixelized.server.lwa.server.Engine
|
||||||
|
import com.pixelized.server.lwa.utils.extentions.characterSheetId
|
||||||
|
import com.pixelized.server.lwa.utils.extentions.exception
|
||||||
|
import com.pixelized.shared.lwa.protocol.rest.APIResponse
|
||||||
|
import com.pixelized.shared.lwa.protocol.websocket.ApiSynchronisation
|
||||||
|
import io.ktor.server.response.respond
|
||||||
|
import io.ktor.server.routing.RoutingContext
|
||||||
|
|
||||||
|
fun Engine.deleteInventory(): suspend RoutingContext.() -> Unit {
|
||||||
|
return {
|
||||||
|
try {
|
||||||
|
// get the query parameter
|
||||||
|
val characterSheetId = call.queryParameters.characterSheetId
|
||||||
|
// delete the alteration.
|
||||||
|
inventoryService.delete(
|
||||||
|
characterSheetId = characterSheetId,
|
||||||
|
)
|
||||||
|
// API & WebSocket responses.
|
||||||
|
call.respond(
|
||||||
|
message = APIResponse.success(),
|
||||||
|
)
|
||||||
|
webSocket.emit(
|
||||||
|
value = ApiSynchronisation.InventoryDelete(
|
||||||
|
timestamp = System.currentTimeMillis(),
|
||||||
|
characterSheetId = characterSheetId,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
call.exception(
|
||||||
|
exception = exception,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.pixelized.server.lwa.server.rest.inventory
|
||||||
|
|
||||||
|
import com.pixelized.server.lwa.server.Engine
|
||||||
|
import com.pixelized.server.lwa.utils.extentions.characterSheetId
|
||||||
|
import com.pixelized.server.lwa.utils.extentions.exception
|
||||||
|
import com.pixelized.shared.lwa.protocol.rest.APIResponse
|
||||||
|
import io.ktor.server.response.respond
|
||||||
|
import io.ktor.server.routing.RoutingContext
|
||||||
|
|
||||||
|
fun Engine.getInventory(): suspend RoutingContext.() -> Unit {
|
||||||
|
return {
|
||||||
|
try {
|
||||||
|
// get the query parameter
|
||||||
|
val characterSheetId = call.queryParameters.characterSheetId
|
||||||
|
// get the character inventory
|
||||||
|
val inventory = inventoryService.inventoryJson(
|
||||||
|
characterSheetId = characterSheetId,
|
||||||
|
)
|
||||||
|
// send it back to the user.
|
||||||
|
call.respond(
|
||||||
|
message = APIResponse.success(
|
||||||
|
data = inventory
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
call.exception(
|
||||||
|
exception = exception
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.pixelized.server.lwa.server.rest.inventory
|
||||||
|
|
||||||
|
import com.pixelized.server.lwa.server.Engine
|
||||||
|
import com.pixelized.server.lwa.utils.extentions.characterSheetId
|
||||||
|
import com.pixelized.server.lwa.utils.extentions.create
|
||||||
|
import com.pixelized.server.lwa.utils.extentions.exception
|
||||||
|
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetJson
|
||||||
|
import com.pixelized.shared.lwa.model.inventory.InventoryJson
|
||||||
|
import com.pixelized.shared.lwa.protocol.rest.APIResponse
|
||||||
|
import com.pixelized.shared.lwa.protocol.websocket.ApiSynchronisation
|
||||||
|
import io.ktor.server.request.receive
|
||||||
|
import io.ktor.server.response.respond
|
||||||
|
import io.ktor.server.routing.RoutingContext
|
||||||
|
|
||||||
|
fun Engine.putInventory(): suspend RoutingContext.() -> Unit {
|
||||||
|
return {
|
||||||
|
try {
|
||||||
|
// get the query parameter
|
||||||
|
val form = call.receive<InventoryJson>()
|
||||||
|
val create = call.queryParameters.create
|
||||||
|
// get the character inventory
|
||||||
|
inventoryService.save(
|
||||||
|
inventoryJson = form,
|
||||||
|
create = create,
|
||||||
|
)
|
||||||
|
// send it back to the user.
|
||||||
|
call.respond(
|
||||||
|
message = APIResponse.success()
|
||||||
|
)
|
||||||
|
webSocket.emit(
|
||||||
|
value = ApiSynchronisation.InventoryUpdate(
|
||||||
|
timestamp = System.currentTimeMillis(),
|
||||||
|
characterSheetId = form.characterSheetId,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
call.exception(
|
||||||
|
exception = exception
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -12,7 +12,7 @@ fun Engine.deleteItem(): suspend RoutingContext.() -> Unit {
|
||||||
return {
|
return {
|
||||||
try {
|
try {
|
||||||
// get the query parameter
|
// get the query parameter
|
||||||
val itemId = call.parameters.itemId
|
val itemId = call.queryParameters.itemId
|
||||||
// delete the alteration.
|
// delete the alteration.
|
||||||
itemService.delete(
|
itemService.delete(
|
||||||
itemId = itemId
|
itemId = itemId
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ import com.pixelized.shared.lwa.model.campaign.factory.CampaignJsonV1Factory
|
||||||
import com.pixelized.shared.lwa.model.campaign.factory.CampaignJsonV2Factory
|
import com.pixelized.shared.lwa.model.campaign.factory.CampaignJsonV2Factory
|
||||||
import com.pixelized.shared.lwa.model.characterSheet.factory.CharacterSheetJsonFactory
|
import com.pixelized.shared.lwa.model.characterSheet.factory.CharacterSheetJsonFactory
|
||||||
import com.pixelized.shared.lwa.model.characterSheet.factory.CharacterSheetJsonV1Factory
|
import com.pixelized.shared.lwa.model.characterSheet.factory.CharacterSheetJsonV1Factory
|
||||||
|
import com.pixelized.shared.lwa.model.inventory.factory.InventoryJsonFactory
|
||||||
|
import com.pixelized.shared.lwa.model.inventory.factory.InventoryJsonFactoryV1
|
||||||
import com.pixelized.shared.lwa.model.item.factory.ItemJsonFactory
|
import com.pixelized.shared.lwa.model.item.factory.ItemJsonFactory
|
||||||
import com.pixelized.shared.lwa.model.item.factory.ItemJsonFactoryV1
|
import com.pixelized.shared.lwa.model.item.factory.ItemJsonFactoryV1
|
||||||
import com.pixelized.shared.lwa.model.tag.TagJsonFactory
|
import com.pixelized.shared.lwa.model.tag.TagJsonFactory
|
||||||
|
|
@ -52,6 +54,8 @@ val factoryDependencies
|
||||||
factoryOf(::TagJsonFactory)
|
factoryOf(::TagJsonFactory)
|
||||||
factoryOf(::ItemJsonFactory)
|
factoryOf(::ItemJsonFactory)
|
||||||
factoryOf(::ItemJsonFactoryV1)
|
factoryOf(::ItemJsonFactoryV1)
|
||||||
|
factoryOf(::InventoryJsonFactory)
|
||||||
|
factoryOf(::InventoryJsonFactoryV1)
|
||||||
}
|
}
|
||||||
|
|
||||||
val parserDependencies
|
val parserDependencies
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.pixelized.shared.lwa.model.inventory
|
||||||
|
|
||||||
|
data class Inventory(
|
||||||
|
val characterSheetId: String,
|
||||||
|
val purse: Purse,
|
||||||
|
val items: List<Item>,
|
||||||
|
) {
|
||||||
|
data class Purse(
|
||||||
|
val gold: Int,
|
||||||
|
val silver: Int,
|
||||||
|
val copper: Int,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class Item(
|
||||||
|
val itemId: String,
|
||||||
|
val count: Int,
|
||||||
|
)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun empty(characterSheetId: String) = Inventory(
|
||||||
|
characterSheetId = characterSheetId,
|
||||||
|
purse = Purse(
|
||||||
|
gold = 0,
|
||||||
|
silver = 0,
|
||||||
|
copper = 0,
|
||||||
|
),
|
||||||
|
items = emptyList(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.pixelized.shared.lwa.model.inventory
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
sealed interface InventoryJson {
|
||||||
|
val characterSheetId: String
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.pixelized.shared.lwa.model.inventory
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class InventoryJsonV1(
|
||||||
|
override val characterSheetId: String,
|
||||||
|
val purse: PurseJson,
|
||||||
|
val items: List<ItemJson>,
|
||||||
|
) : InventoryJson {
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class PurseJson(
|
||||||
|
val gold: Int,
|
||||||
|
val silver: Int,
|
||||||
|
val copper: Int,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class ItemJson(
|
||||||
|
val itemId: String,
|
||||||
|
val count: Int,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.pixelized.shared.lwa.model.inventory.factory
|
||||||
|
|
||||||
|
import com.pixelized.shared.lwa.model.inventory.Inventory
|
||||||
|
import com.pixelized.shared.lwa.model.inventory.InventoryJson
|
||||||
|
import com.pixelized.shared.lwa.model.inventory.InventoryJsonV1
|
||||||
|
|
||||||
|
class InventoryJsonFactory(
|
||||||
|
private val v1: InventoryJsonFactoryV1,
|
||||||
|
) {
|
||||||
|
fun convertFromJson(json: InventoryJson): Inventory {
|
||||||
|
return when (json) {
|
||||||
|
is InventoryJsonV1 -> v1.convertFromJson(json = json)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun convertToJson(inventory: Inventory): InventoryJson {
|
||||||
|
return v1.convertToJson(inventory = inventory)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
package com.pixelized.shared.lwa.model.inventory.factory
|
||||||
|
|
||||||
|
import com.pixelized.shared.lwa.model.inventory.Inventory
|
||||||
|
import com.pixelized.shared.lwa.model.inventory.InventoryJsonV1
|
||||||
|
|
||||||
|
class InventoryJsonFactoryV1 {
|
||||||
|
|
||||||
|
fun convertFromJson(json: InventoryJsonV1): Inventory {
|
||||||
|
return Inventory(
|
||||||
|
characterSheetId = json.characterSheetId,
|
||||||
|
purse = Inventory.Purse(
|
||||||
|
gold = json.purse.gold,
|
||||||
|
silver = json.purse.silver,
|
||||||
|
copper = json.purse.copper,
|
||||||
|
),
|
||||||
|
items = json.items.map {
|
||||||
|
Inventory.Item(
|
||||||
|
itemId = it.itemId,
|
||||||
|
count = it.count,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun convertToJson(inventory: Inventory): InventoryJsonV1 {
|
||||||
|
return InventoryJsonV1(
|
||||||
|
characterSheetId = inventory.characterSheetId,
|
||||||
|
purse = InventoryJsonV1.PurseJson(
|
||||||
|
gold = inventory.purse.gold,
|
||||||
|
silver = inventory.purse.silver,
|
||||||
|
copper = inventory.purse.copper,
|
||||||
|
),
|
||||||
|
items = inventory.items.map {
|
||||||
|
InventoryJsonV1.ItemJson(
|
||||||
|
itemId = it.itemId,
|
||||||
|
count = it.count,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -49,4 +49,19 @@ sealed interface ApiSynchronisation : SocketMessage {
|
||||||
override val timestamp: Long,
|
override val timestamp: Long,
|
||||||
val itemId: String,
|
val itemId: String,
|
||||||
) : ItemApiSynchronisation
|
) : ItemApiSynchronisation
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
sealed interface InventoryApiSynchronisation : ApiSynchronisation, CharacterSheetIdMessage
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class InventoryUpdate(
|
||||||
|
override val timestamp: Long,
|
||||||
|
override val characterSheetId: String,
|
||||||
|
) : InventoryApiSynchronisation
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class InventoryDelete(
|
||||||
|
override val timestamp: Long,
|
||||||
|
override val characterSheetId: String,
|
||||||
|
) : InventoryApiSynchronisation
|
||||||
}
|
}
|
||||||
|
|
@ -73,4 +73,14 @@ class PathProvider(
|
||||||
OperatingSystem.Macintosh -> "${storePath(os = os, app = app)}tags/"
|
OperatingSystem.Macintosh -> "${storePath(os = os, app = app)}tags/"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun inventoryPath(
|
||||||
|
os: OperatingSystem = this.operatingSystem,
|
||||||
|
app: String = this.appName,
|
||||||
|
): String {
|
||||||
|
return when (os) {
|
||||||
|
OperatingSystem.Windows -> "${storePath(os = os, app = app)}inventory\\"
|
||||||
|
OperatingSystem.Macintosh -> "${storePath(os = os, app = app)}inventory/"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue