Minecraft NBT support for kotlinx.serialization

Overview

knbt

Maven Central KDoc Kotlin kotlinx.serialization

An implementation of Minecraft's NBT format for kotlinx.serialization.

Technical information about NBT can be found here.

Using the same version of kotlinx.serialization is recommended since parts of its API required for custom formats are still experimental, and newer versions may have binary-incompatible changes that could break knbt's implementation.

Configuration

val nbt = Nbt {
    variant = Java // Java, Bedrock
    compression = None // None, Gzip, Zlib
    encodeDefaults = false
    ignoreUnknownKeys = false
    serializersModule = EmptySerializersModule
}

Serialization

An Nbt instance can be used to encode/decode @Serializable data. When serializing to/from NBT binary, the data must be a structure with a single named element (as per the NBT spec).

When deserializing, the compression will be automatically detected and decompressed. When serializing, the compression method set in the configuration will be used.

// ByteArray
byteArray = nbt.encodeToByteArray(value)
value = nbt.decodeFromByteArray(byteArray)

// NbtTag
nbtTag = nbt.encodeToNbtTag(value)
value = nbt.decodeFromNbtTag(nbtTag)

// Okio Sink/Source (Multiplatform)
nbt.encodeTo(sink, value)
value = nbt.decodeFrom(source)

// OutputStream/InputStream (JVM)
nbt.encodeTo(outputStream, value)
value = nbt.decodeFrom(inputStream)

@NbtFile

Serializable classes can be marked with @NbtFile to make them suitable for serializing NBT files. The NbtConfiguration's variant and compression will be overridden, and the root tag will be named with tag with the given tagName.

Example usage:

@Serializable
@NbtFile(variant = Java, compression = None, tagName = "root")
class ExampleFile(val string: String, val int: Int)

// Encodes to {root : {string : "Hello, world!", int : 42}}
val file = ExampleFile(string = "Hello, World!", int = 42)
Nbt.encodeToNbtTag(file)

NbtTag classes

The sealed NbtTag interface has the following immutable implementations:

value class NbtByte : NbtTag
value class NbtShort : NbtTag
value class NbtInt : NbtTag
value class NbtLong : NbtTag
value class NbtFloat : NbtTag
value class NbtDouble : NbtTag
value class NbtString : NbtTag
class NbtByteArray : NbtTag, List<Byte>
class NbtIntArray : NbtTag, List<Int>
class NbtLongArray : NbtTag, List<Long>
class NbtList<T : NbtTag> : NbtTag, List<T> // Only contains entries of a single type
class NbtCompound<T : NbtTag> : NbtTag, Map<String, T>

NbtTags can be created with factory/conversion/builder functions:

val nbtByte = 5.toNbtByte()

val nbtIntArray = nbtIntArrayOf(1, 2, 3, 4, 5)

val nbtListOfInts = listOf(1L, 2L, 3L).toNbtList()

val nbtListOfStrings = buildNbtList<NbtString> { 
    add("these")
    add("are")
    add("strings")
}

val nbtCompoundOfInts = mapOf("a" to 1, "b" to 2).toNbtCompound()

// bigtest.nbt (https://wiki.vg/NBT#bigtest.nbt)
val bigtest = buildNbt("Level") {
    put("longTest", 9223372036854775807L)
    put("shortTest", 32767.toShort())
    put("stringTest", "HELLO WORLD THIS IS A TEST STRING ÅÄÖ!")
    put("floatTest", 0.49823147f)
    put("intTest", 2147483647)
    putNbtCompound("nested compound test") {
        putNbtCompound("ham") {
            put("name", "Hampus")
            put("value", 0.75f)
        }
        putNbtCompound("egg") {
            put("name", "Eggbert")
            put("value", 0.5f)
        }
    }
    put("listTest (long)", listOf(11L, 12L, 13L, 14L, 15L).toNbtList())
    putNbtList<NbtCompound<*>>("listTest (compound)") {
        addNbtCompound {
            put("name", "Compound tag #0")
            put("created-on", 1264099775885L)
        }
        addNbtCompound {
            put("name", "Compound tag #1")
            put("created-on", 1264099775885L)
        }
    }
    put("byteTest", 127.toByte())
    put(
        "byteArrayTest (the first 1000 values of (n*n*255+n*7)%100, starting with n=0 (0, 62, 34, 16, 8, ...))",
        ByteArray(1000) { n -> ((n * n * 255 + n * 7) % 100).toByte() }
    )
    put("doubleTest", 0.4931287132182315)
}

Setup

Gradle

plugins {
    kotlin("jvm") version "1.5.0" // or kotlin("multiplatform"), etc.
    //kotlin("plugin.serialization") version "1.5.0"
}

repositories {
    mavenCentral()
    //maven("https://s01.oss.sonatype.org/content/repositories/snapshots/")
}

dependencies {
    implementation("net.benwoodworth.knbt:knbt:$knbt_version")
    //implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.2.0")
}
Comments
  • How to serialize into a Json ?

    How to serialize into a Json ?

    Hi, for a specific reason, I have to serialize an object as a JSON that also contains a NbtTag property, but I can't figure out how to make it works. By having the default Serializer I get the following error :

    Class 'NbtList' is not registered for polymorphic serialization in the scope of 'NbtTag'.
    Mark the base class as 'sealed' or register the serializer explicitly.
    
    opened by Ayfri 9
  • [BUG] Config option `ignoreUnknownKeys` breaks when there are unknown keys at the end

    [BUG] Config option `ignoreUnknownKeys` breaks when there are unknown keys at the end

    I was trying to parse level.dat to get the level name, but it turns out that it doesn't work with the models

    @OptIn(ExperimentalNbtApi::class)
    @NbtRoot(name = "")
    @Serializable
    data class LevelRoot(
        @SerialName("Data")
        val data: LevelData
    )
    
    
    @SerialName("Data")
    @Serializable
    data class LevelData(
        @SerialName("LevelName")
        val levelName: String
    )
    

    and the config

    Nbt {
        variant = NbtVariant.Java
        compression = NbtCompression.Gzip
        ignoreUnknownKeys = true
    }
    

    The following exception + stacktrace is thrown:

    Exception in thread "main" java.lang.IllegalStateException: Unexpected TAG_End
    	at net.benwoodworth.knbt.internal.NbtReaderKt.discardTag(NbtReader.kt:203)
    	at net.benwoodworth.knbt.internal.ClassNbtDecoder.handleUnknownKey(NbtDecoder.kt:253)
    	at net.benwoodworth.knbt.internal.ClassNbtDecoder.decodeElementIndex(NbtDecoder.kt:269)
    	at msw.server.core.model.world.LevelData$$serializer.deserialize(leveldat.kt:17)
    	at msw.server.core.model.world.LevelData$$serializer.deserialize(leveldat.kt:17)
    	at kotlinx.serialization.encoding.Decoder$DefaultImpls.decodeSerializableValue(Decoding.kt:260)
    	at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:16)
    	at net.benwoodworth.knbt.AbstractNbtDecoder.decodeSerializableValue(NbtDecoding.kt:84)
    	at net.benwoodworth.knbt.internal.BaseNbtDecoder.decodeSerializableValue(NbtDecoder.kt:177)
    	at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
    	at net.benwoodworth.knbt.internal.BaseNbtDecoder.decodeSerializableValue(NbtDecoder.kt:180)
    	at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
    	at msw.server.core.model.world.LevelRoot$$serializer.deserialize(leveldat.kt:8)
    	at msw.server.core.model.world.LevelRoot$$serializer.deserialize(leveldat.kt:8)
    	at kotlinx.serialization.encoding.Decoder$DefaultImpls.decodeSerializableValue(Decoding.kt:260)
    	at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:16)
    	at net.benwoodworth.knbt.AbstractNbtDecoder.decodeSerializableValue(NbtDecoding.kt:84)
    	at net.benwoodworth.knbt.internal.BaseNbtDecoder.decodeSerializableValue(NbtDecoder.kt:177)
    	at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
    	at net.benwoodworth.knbt.internal.BaseNbtDecoder.decodeSerializableValue(NbtDecoder.kt:180)
    	at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
    	at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:535)
    	at net.benwoodworth.knbt.NbtRootDeserializer.deserialize(NbtRoot.kt:66)
    	at kotlinx.serialization.encoding.Decoder$DefaultImpls.decodeSerializableValue(Decoding.kt:260)
    	at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:16)
    	at net.benwoodworth.knbt.AbstractNbtDecoder.decodeSerializableValue(NbtDecoding.kt:84)
    	at net.benwoodworth.knbt.internal.BaseNbtDecoder.decodeSerializableValue(NbtDecoder.kt:177)
    	at net.benwoodworth.knbt.NbtFormatKt.decodeFromNbtReader(NbtFormat.kt:67)
    	at net.benwoodworth.knbt.Nbt.decodeFromSource(Nbt.kt:41)
    	at net.benwoodworth.knbt.JvmStreamsKt.decodeFromStream(JvmStreams.kt:35)
    	at [invocation of Nbt.decodeFromStream<LevelRoot>(inputStream)]
    

    I found out that this exception is thrown when

    1. ignoreUnknownKeys is true
    2. the model classes don't cover all keys present in the nbt file
    3. the last key of a compound is unknown

    I started with testing this with level.dat, trying to access [root]/Data/LevelName. That didn't work because there are other keys after LevelName that are not present in the model. Then I tested it with a constructed nbt file that basically just contained

    [root]: {
        Data: {
            LevelName: "test"
        }
    }
    

    This could be deserialized into the models. Then, I added a random key that is not present in the models:

    [root]: {
        Data: {
            ScheduledEvents: []
            LevelName: "test"
        }
    }
    

    This still works, since ignoreUnknownKeys is turned on. However, when I swap the positions of ScheduledEvents and LevelName:

    [root]: {
        Data: {
            LevelName: "test"
            ScheduledEvents: []
        }
    }
    

    The above error is thrown.

    Kotlin 1.5.30 KXS 1.2.2 knbt 0.9.1

    opened by RaphaelTarita 4
  • [FEATURE] A JsonPath-like DSL for reading specific properties from an NBT source

    [FEATURE] A JsonPath-like DSL for reading specific properties from an NBT source

    It'd be cool to have a DSL that allows you to access specifc properties of an arbitrary NBT source without needing a model class. Similar to how KotlinNBT does it or how I plan to do it in my version.

    The DSL definitions for KotlinNBT can be found here. An example of this DSL would be:

    val fibonacci: IntArray = nbt["testCompound"].asTagCompound["fibonacciWithoutZero"].asIntArray
    val message: String = nbt["testList"].asTagList[0].asTagCompound["firstString"].asString
    val timestamp: Long = nbt["timestamp"].asLong
    

    The DSL definitions for KXSmine can be found here. An example of this DSL would be:

    val fibonacci = root.compound("testCompound").intarray("fibonacciWithoutZero").data
    val message = root.list("testList").compoundAt(0).string("firstString").data
    val timestamp = root.long("timestamp").data
    

    The main benefit from such a DSL would be the ability to type-safely access just specific properties without having to write a whole model class for the NBT source you're parsing.

    opened by RaphaelTarita 4
  • Floats are decoded as Doubles on Kolin/JS

    Floats are decoded as Doubles on Kolin/JS

    Seems like an issue with Kotlin/JS itself, since all numbers are stored as Doubles in Javascript: KT-35422

    BinaryNbtReaderTest.Should_decode_uncompressed_bigtest_nbt_to_class_correctly failed:

    Structures are not equal.
    level.floatTest: Expected <0.49823147>, actual <0.4982314705848694>.
    
    bug kotlin/js 
    opened by BenWoodworth 1
  • Support other native platforms

    Support other native platforms

    Currently the published knbt-native can only be used on linux_x64 (since I'm publishing it from my linux machine)

    This should work fine for other platforms, since the only platform-specific dependencies are okio and platform.posix.zlib (which both support most native targets)

    I get this error when trying to use this library on Windows (mingw_x64):

    Execution failed for task ':compileKotlinNative'.
    > Could not resolve all files for configuration ':nativeCompileKlibraries'.
       > Could not resolve net.benwoodworth.knbt:knbt:0.3.0.
         Required by:
             project :
          > No matching variant of net.benwoodworth.knbt:knbt:0.3.0 was found. The consumer was configured to find a usage of 'kotlin-api' of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native', attribute 'org.jetbrains.kotlin.native.target' with value 'mingw_x64' but:
              - Variant 'commonMainMetadataElements' capability net.benwoodworth.knbt:knbt:0.3.0 declares a usage of 'kotlin-api' of a component:
                  - Incompatible because this component declares a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'common' and the consumer needed a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native'
                  - Other compatible attribute:
                      - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'mingw_x64')
              - Variant 'jsApiElements-published' capability net.benwoodworth.knbt:knbt:0.3.0 declares a usage of 'kotlin-api' of a component:
                  - Incompatible because this component declares a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'js' and the consumer needed a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native'
                  - Other compatible attribute:
                      - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'mingw_x64')
              - Variant 'jsRuntimeElements-published' capability net.benwoodworth.knbt:knbt:0.3.0:
                  - Incompatible because this component declares a usage of 'kotlin-runtime' of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'js' and the consumer needed a usage of 'kotlin-api' of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native'
                  - Other compatible attribute:
                      - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'mingw_x64')
              - Variant 'jvmApiElements-published' capability net.benwoodworth.knbt:knbt:0.3.0 declares an API of a component:
                  - Incompatible because this component declares a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm' and the consumer needed a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native'
                  - Other compatible attribute:
                      - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'mingw_x64')
              - Variant 'jvmRuntimeElements-published' capability net.benwoodworth.knbt:knbt:0.3.0 declares a runtime of a component:
                  - Incompatible because this component declares a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm' and the consumer needed a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native'
                  - Other compatible attribute:
                      - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'mingw_x64')
              - Variant 'metadataApiElements' capability net.benwoodworth.knbt:knbt:0.3.0:
                  - Incompatible because this component declares a usage of 'kotlin-metadata' of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'common' and the consumer needed a usage of 'kotlin-api' of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native'
                  - Other compatible attribute:
                      - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'mingw_x64')
              - Variant 'nativeApiElements-published' capability net.benwoodworth.knbt:knbt:0.3.0 declares a usage of 'kotlin-api' of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native':
                  - Incompatible because this component declares a component, as well as attribute 'org.jetbrains.kotlin.native.target' with value 'linux_x64' and the consumer needed a component, as well as attribute 'org.jetbrains.kotlin.native.target' with value 'mingw_x64'
    
    opened by BenWoodworth 0
  • Support Compressed NBT

    Support Compressed NBT

    NBT can either be uncompressed, or compressed with gzip/zlib

    Decoding NBT should automatically work.

    Encoding NBT can use a compression method configured with the NbtConfiguration.

    Kotlin/JVM

    • [x] Gzip compression
    • [x] Gzip decompression
    • [x] Zlib compression
    • [x] Zlib decompression

    Kotlin/JS (pako, zlib ported to JavaScript)

    • [x] Gzip compression
    • [x] Gzip decompression
    • [x] Zlib compression
    • [x] Zlib decompression

    Kotlin/Native (platform.zlib)

    • [x] Gzip compression
    • [x] Gzip decompression
    • [x] Zlib compression
    • [x] Zlib decompression
    kotlin/native kotlin/js spec 
    opened by BenWoodworth 0
  • Consider adding a `@NbtSerialName` annotation

    Consider adding a `@NbtSerialName` annotation

    Would have the same functionality as @SerialName, but takes precedence when serializing NBT

    see: https://github.com/Kotlin/kotlinx.serialization/issues/2104

    Naming considerations:

    (I checked all officially/community supported formats for related @SerialInfo annotation classes)

    opened by BenWoodworth 0
  • Support Enum serialization

    Support Enum serialization

    Minecraft appears to encode all enum-like values as an ordinal, so consider doing the same with enum values instead of throwing an "unsupported" error.

    opened by BenWoodworth 0
  • Loosen constraints on boolean parsing

    Loosen constraints on boolean parsing

    Currently only the bytes 0b and 1b can be read for boolean values, with all others throwing a serialization exception. However, Minecraft is more lenient and parses everything but 0b as true, with no values throwing an exception.

    opened by BenWoodworth 0
  • Add a way to tell for encoder what kind of NBT tag to encode collections as

    Add a way to tell for encoder what kind of NBT tag to encode collections as

    E.g.

    @Serializable
    data class NbtMyIntArray(
        @NbtType(NbtIntArray::class)
        val intArray: List<Int> // Encode as `NbtIntArray` instead of `NbtList<NbtInt>`
    )
    
    opened by BenWoodworth 0
Releases(v0.11.3)
  • v0.11.3(Oct 4, 2022)

  • v0.11.2(Jul 14, 2022)

  • v0.11.1(Oct 12, 2021)

  • v0.11.0(Oct 4, 2021)

    Changes

    • Implemented Stringified NBT deserialization
    • Allow Boolean values to be serialized
      • Serialized with Byte tags: false = 0b, true = 1b
      • Added NbtByte(Boolean) constructor and NbtByte.booleanValue property
      • Added NbtCompoundBuilder.put(name, boolean) and NbtListBuilder.add(boolean) functions
    • Added an nbt property to NbtEncoder and NbtDecoder, so NBT configurations can be used by serializers

    Breaking Changes

    • Made NbtException classes internal (they were accidentally left public)
      • Use SerializationException instead
    Source code(tar.gz)
    Source code(zip)
  • v0.10.1(Sep 24, 2021)

  • v0.10.0(Sep 24, 2021)

    - Important Migration Notice:
      The first breaking change won't cause issues until runtime and requires manual migration
      Find all root @Serializable classes in your project, and make sure to migrate them accordingly
    

    Changes

    • Updated to kotlinx.serialization 1.3.0 and Kotlin 1.5.31
    • Changed kotlinx.serialization dependency from implementation to api
    • Root classes now serialize nested in a compound tag using their @SerialName

    Breaking Changes

    • All root @Serializable classes without @NbtRoot will need to be changed
      • Root classes are now automatically nested in a compound tag as if they had @NbtRoot
      • To migrate, name the inner class with @SerialName("name") and remove the outer class (see below)
    • Removed @NbtRoot in favor of @SerialName
    • Made NbtException internal
    • Removed NbtVariant.BigEndian, .LittleEndian, and .LittleEndianBase128 in favor of .Java, .Bedrock, and .BedrockNetwork

    Fixes


    Example Root Class Migration

    // knbt 0.9
    @Serializable
    class LevelRoot(
        @SerialName("")
        val level: Level
    )
    
    @Serializable
    class Level
        val intValue: Int
    )
    
    // knbt 0.10
    @Serializable
    @SerialName("")
    class Level(
        val intValue: Int
    )
    
    Source code(tar.gz)
    Source code(zip)
  • v0.9.2(Sep 13, 2021)

  • v0.9.1(Sep 13, 2021)

  • v0.9.0(Sep 13, 2021)

    Changes

    • Added a StringifiedNbt format, and moved all SNBT-related APIs in Nbt to it
    • Added an NbtFormat interface that Nbt and StringifiedNbt both implement
    • Require Nbt to be configured, with variant and compression no longer being optional
      • Removed Nbt's companion object with default configuration
    Source code(tar.gz)
    Source code(zip)
  • v0.8.1(Aug 30, 2021)

  • v0.8.0(Aug 30, 2021)

  • v0.7.1(Aug 21, 2021)

  • v0.7.0(Aug 21, 2021)

    Changes

    • Change API to match conventions set by kotlinx.serialization
      • Move NbtTag classes/extensions from net.benwoodworth.knbt.tag to net.benwoodworth.knbt
      • Use NbtTag constructors and value properties instead of conversion functions
        • e.g. NbtInt(val value: Int) instead of Int.toNbtInt() and NbtInt.toInt()
      • Add convenience properties for casting NbtTag to a specific tag types
      • Rename Nbt.encodeTo(...) and .decodeFrom(...) to e.g. .encodeToStream(...)
      • NbtTag.toString() now returns Stringified NBT, instead of the backing Kotlin value's .toString()
        • e.g. NbtByte(1).toString() will return "1b" instead of just "1"
    • Nbt*Array types are now backed by arrays instead of lists
    • Add @BuilderInference to buildNbtList {} so the type parameter can be inferred

    Fixes

    • Stringified NbtCompound entries with empty names ("") will now render their names with quotes

    Breaking changes

    • Deprecated old API that's changed to match kotlinx.serialization's (see above)
    Source code(tar.gz)
    Source code(zip)
  • v0.6.1(Jul 1, 2021)

  • v0.6.0(Jun 23, 2021)

    Changes

    • Made NbtTag polymorphic
    • Allow NbtTags to be serialized without passing NbtTag.serializer()

    Breaking Changes

    • Removed generic type from NbtCompound
    Source code(tar.gz)
    Source code(zip)
  • v0.5.0(Jun 6, 2021)

    Changes

    • Remove deprecated @NbtFile annotation
    • Simplify the way compression level is configured

    Fixes

    • Make NbtCompound.serializer() and NbtList.serializer() public

    Breaking Changes

    • Changed compression level configuration:
      • From Nbt { compression = Gzip { level = # } }
      • To Nbt { compression = Gzip; compressionLevel = # }
    Source code(tar.gz)
    Source code(zip)
  • v0.4.0(Jun 3, 2021)

    Changes

    • Added support for Bedrock Edition variants
    • Made gzip and zlib configurable (compression level)
    • Added NbtCompression.detect(...) functions
    • Added @NbtRoot annotation

    Fixes

    • Use serializerModule when getting serializer from encodeTo/decodeFrom type parameters

    Breaking Changes

    • Changed NbtVariant and NbtCompression from enums to classes
    • Changed default variant from Java to null
    • Changed default compression from None to null
    • variant and compression must be specified for binary encoding/decoding
    • compression is no longer detected automatically when reading
    • Remove @NbtFile in favor of @NbtRoot
    • Other binary-incompatible changes
    Source code(tar.gz)
    Source code(zip)
  • v0.3.1(May 21, 2021)

  • v0.3.0(May 18, 2021)

    Changes

    • Added @NbtFile annotation
    • Added NBT paths/type info to exceptions
    • Added ignoreUnknownKeys to NbtConfiguration

    Fixes

    • Made NbtTag serializers internal instead of private to avoid JVM runtime exceptions

    Breaking Changes

    • Moved Nbt.encodeTo* and .decodeFrom* functions to extension functions
    • Made Nbt*Exception constructors internal
    Source code(tar.gz)
    Source code(zip)
  • v0.2.3(May 14, 2021)

    Changes

    • Support gzip and zlib compression for Kotlin/JS and Kotlin/Native

    Fixes

    • Don't read more bytes than necessary when decoding compressed NBT from Sources/Streams
    Source code(tar.gz)
    Source code(zip)
  • v0.2.2(May 12, 2021)

    Changes

    • Support gzip and zlib decompression for Kotlin/JS and Kotlin/Native

    Fixes

    • Fix missing gzip/zlib trailers when compressing on Kotlin/JVM
    Source code(tar.gz)
    Source code(zip)
  • v0.2.1(May 9, 2021)

  • v0.2.0(May 9, 2021)

    Changes

    • Add support for configurable compression
      • JVM supports reading Gzip/Zlib, and writing Gzip
      • Native and JS don't yet support compression
    Source code(tar.gz)
    Source code(zip)
Owner
Ben Woodworth
Ben Woodworth
Android Parcelable support for the Kotlinx Serialization library.

Android Parcelable support for the Kotlinx Serialization library.

Christopher 50 Nov 20, 2022
CSV and FixedLength Formats for kotlinx-serialization

Module kotlinx-serialization-csv Serialize and deserialize ordered CSV and Fixed Length Format Files with kotlinx-serialization. Source code Docs Inst

Philip Wedemann 12 Dec 16, 2022
Kotlin tooling for generating kotlinx.serialization serializers for serializing a class as a bitmask

kotlinx-serialization-bitmask Kotlin tooling for generating kotlinx.serialization serializers for serializing a class as a bitmask. Example @Serializa

marie 2 May 29, 2022
Type-safe arguments for JetPack Navigation Compose using Kotlinx.Serialization

Navigation Compose Typed Compile-time type-safe arguments for JetPack Navigation Compose library. Based on KotlinX.Serialization. Major features: Comp

Kiwi.com 32 Jan 4, 2023
KotlinX Serialization Standard Serializers (KS3)

KotlinX Serialization Standard Serializers (KS3) This project aims to provide a set of serializers for common types. ⚠️ Consider this project to be Al

Emil Kantis 3 Nov 5, 2022
A tiny Kotlin multiplatform library that assists in saving and restoring objects to and from disk using kotlinx.coroutines, kotlinx.serialisation and okio

Store A tiny Kotlin multiplatform library that assists in saving and restoring objects to and from disk using kotlinx.coroutines, kotlinx.serialisatio

Isuru Rajapakse 98 Jan 3, 2023
Jackson extension for Mojang's NBT format

Jackson NBT Data Format Implements Mojang's NBT format in jackson. Usage Using this format works just like regular jackson, but with the ObjectMapper

Dyescape 3 Sep 10, 2022
A minecraft modification based on Fabric with Yarn Mappings, developed for the newest version of the sandbox game Minecraft.

JupiterClient A minecraft modification based on Fabric with Yarn Mappings, developed for the newest version of the sandbox game Minecraft. Building th

Cedric H. 1 Jun 27, 2022
Create an application with Kotlin/JVM and Kotlin/JS, and explore features around code sharing, serialization, server- and client

Practical Kotlin Multiplatform on the Web 본 저장소는 코틀린 멀티플랫폼 기반 웹 프로그래밍 워크숍(강좌)을 위해 작성된 템플릿 프로젝트가 있는 곳입니다. 워크숍 과정에서 코틀린 멀티플랫폼을 기반으로 프론트엔드(front-end)는 Ko

SpringRunner 14 Nov 5, 2022
Create an application with Kotlin/JVM and Kotlin/JS, and explore features around code sharing, serialization, server- and client

Building a Full Stack Web App with Kotlin Multiplatform 본 저장소는 INFCON 2022에서 코틀린 멀티플랫폼 기반 웹 프로그래밍 핸즈온랩을 위해 작성된 템플릿 프로젝트가 있는 곳입니다. 핸즈온 과정에서 코틀린 멀티플랫폼을

Arawn Park 19 Sep 8, 2022
Adds emoji support to the Minecraft chat.

WeirdChat ?? WeirdChat is a FabricMC mod that adds Emoji support to the Minecraft chat. Instead of completely rewriting the text renderer, Discord emo

Sarah 2 Oct 30, 2022
Automatic CoroutineDispatcher injection and extensions for kotlinx.coroutines

Dispatch Utilities for kotlinx.coroutines which make them type-safe, easier to test, and more expressive. Use the predefined types and factories or de

Rick Busarow 132 Dec 9, 2022
Small Kafka Playground to play around with Test Containers, and KotlinX Coroutines bindings while reading Kafka Definite Guide V2

KafkaPlayground Small playground where I'm playing around with Kafka in Kotlin and the Kafka SDK whilst reading the Kafka book Definite Guide from Con

Simon Vergauwen 34 Dec 30, 2022
An tool to help developer to use Retrofit elegantly while using kotlinx.coroutines.

one An tool to help developer to use Retrofit elegantly while using kotlinx.coroutines. Feature Transform different data structs to one. {errorCode, d

ChengTao 30 Dec 27, 2022
Kotlinx-murmurhash - Kotlin Multiplatform (KMP) library for hashing using MurmurHash

kotlinx-murmurhash Kotlin Multiplatform (KMP) library for MurmurHash, a non-cryp

Gonçalo Silva 23 Dec 27, 2022
Gradle plugin adding a task to run a Paper Minecraft server

Run Paper Run Paper is a Gradle plugin which adds a task to automatically download and run a Paper Minecraft server along with your plugin built by Gr

Jason 64 Dec 29, 2022
An under development minecraft plugin (1.8.8) to learning Kotlin language

CorePlus CorePlus is a minecraft plugin coded with Kotlin language. Still under development CorePlus will be an essential for each minecraft servers !

Gonz 3 Jun 16, 2021
Run Minecraft on the command line

HeadlessForge While headless Minecraft Clients aren't anything new, they come with a drawback. The Minecraft API is missing and you need to add all fu

null 28 Oct 17, 2022
Kotlin utility mod for Minecraft

Lambda is a free, open-source, Minecraft 1.12.2 utility mod providing a visionary system for plugins that allow customizing the clients features thank

Lambda 405 Dec 28, 2022