Comments (9)
Hey! I think you have the right approach, but there was a bug that made @Serializable sealed interface
s (like NbtTag
) not work correctly out of the box. I'm planning on having that fixed in knbt v0.12, since serializable sealed interfaces are now supported, but it might be a bit.
I can get you a more complete answer later, but something like this might work for now. (this is from memory, so it might not be quite right)
val polymorphicNbtSerializersModule = SerializersModule {
polymorphic(NbtTag::class, NbtTag.serializer()) {
subclass(NbtByte::class, NbtByte.serializer())
subclass(NbtShort::class, NbtShort.serializer())
// ...and all the other NbtTag types
}
}
val json = Json {
// ...
serializersModule = polymorphicNbtSerializersModule
}
I'll play around with it later to get something that working :)
from knbt.
Although on second thought I'm not sure that'll work. The NbtTag serializers require the NbtEncoder/Decoder:
Same as how the JsonElements require the JsonEncoder/Decoder:
from knbt.
So you'd need a custom serializer, which I can help you with.
How do you feel about storing the NBT as a JSON string value? Writing it as SNBT is probably the easiest thing to do
from knbt.
It's complicated, because I'm serializing a data class DataPack
, containing a serializable data class Pack
, containing a property description
which is a NbtTag
(it's for generating the pack.mcmeta
from datapacks). So if I serialize all this to a SNBT, it won't be a valid JSON.
from knbt.
Ah, gotcha! Just got off work so I'm starting to look into it.
Is this the one you're talking about? And changing it from String
to NbtTag
https://github.com/Ayfri/Datapack-DSL/blob/e57be5bb68330216958d23034730ff5616704dd3/src/main/kotlin/DataPack.kt#L16
I haven't done much with data packs personally, but the pack.mcmeta page makes it look like description
is also JSON. Is that right? I might be missing something
from knbt.
Also that's an awesome project! I love what I'm seeing 😁
from knbt.
Thanks !
It can be a string, a NBTList
or a NBTCompound
, as it is considered as a Text Component.
from knbt.
How's this look? Serializing seems to work like a charm. I played around with deserializing for a good two hours and... yeah. It's tricky... trying to figure out the best way to map things around 😬
It seems like you only need to serialize for now though so here's a start:
import kotlinx.serialization.*
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.descriptors.serialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.*
import net.benwoodworth.knbt.*
private object NbtAsJsonTextComponentSerializer : KSerializer<NbtTag> {
@OptIn(ExperimentalSerializationApi::class)
override val descriptor: SerialDescriptor =
SerialDescriptor("TextComponentJsonSerializer", serialDescriptor<JsonElement>())
override fun serialize(encoder: Encoder, value: NbtTag): Unit =
encoder.encodeSerializableValue(JsonElement.serializer(), value.toJsonElement())
override fun deserialize(decoder: Decoder): NbtTag =
throw UnsupportedOperationException("Deserializing not supported")
private fun NbtTag.toJsonElement(): JsonElement = when (this) {
is NbtCompound -> JsonObject(mapValues { it.value.toJsonElement() })
is NbtList<*> -> JsonArray(map { it.toJsonElement() })
is NbtByteArray -> JsonArray(map { JsonPrimitive(it) })
is NbtIntArray -> JsonArray(map { JsonPrimitive(it) })
is NbtLongArray -> JsonArray(map { JsonPrimitive(it) })
is NbtString -> JsonPrimitive(value)
is NbtByte -> when(value) { // Or just convert to number?
0.toByte() -> JsonPrimitive(false)
1.toByte() -> JsonPrimitive(true)
else -> JsonPrimitive(value)
}
is NbtShort -> JsonPrimitive(value)
is NbtInt -> JsonPrimitive(value)
is NbtLong -> JsonPrimitive(value)
is NbtFloat -> JsonPrimitive(value)
is NbtDouble -> JsonPrimitive(value)
}
// private fun JsonElement.toNbtTag(): NbtCompound = when (this) {
// is JsonObject -> NbtCompound(mapValues { (_, value) -> value })
//
// is JsonArray -> // NbtList elements must all be the same type
//
// is JsonPrimitive -> when (val value = contentOrNull) {
// null -> error("$value is not supported in text components")
// else -> NbtString(value)
// }
// }
}
@Serializable
data class Pack(
var packFormat: Int,
@Serializable(NbtAsJsonTextComponentSerializer::class)
var description: NbtTag,
)
from knbt.
Nice, it works well, thank you so much ! Can't wait to have it integrated by default :)
from knbt.
Related Issues (20)
- Serialize unsigned arrays as NbtArrays
- Test fails on mingwX64 HOT 2
- Support `Char` serialization
- Add `NbtTransformingSerializer`
- Add extension methods/properties to Kotlin types for creating Nbt versions of a type.
- Consistency issues with equality in list-like `NbtTag` types
- Re-design root class name NbtCompound-nesting functionality HOT 22
- Refactor `NbtEncoder`/`NbtDecoder` implementations
- Simplify `NbtEncoder`/`NbtDecoder` interfaces
- Strict binary equality for `NbtFloat` and `NbtDouble`
- Investigate `NaN` and infinity values for SNBT HOT 1
- Back `Nbt*Array`s with `List`s, and encode arrays as `NbtList` by default, and require `@NbtArray`
- Change package to com.benwoodworth.knbt :) HOT 1
- Support Java protocol version 764+ with nameless tags HOT 6
- Extra bytes are read when decoding Nbt from stream HOT 4
- Allow the encoding/decoding of end tags at root HOT 2
- Rename `Nbt` to `BinaryNbt`, and `NbtFormat` to `Nbt`, and add `Nbt` companion object for `NbtTag` serialization
- Expose `NbtTagType` in the public API
- Ensure that Java NBT uses "Modified UTF-8"
- Check that SNBT on JS reads/writes floats/doubles correctly
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from knbt.