diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/StarboundJsonAdapters.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/StarboundJsonAdapters.kt index fd392719..c47b199e 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/StarboundJsonAdapters.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/StarboundJsonAdapters.kt @@ -52,14 +52,18 @@ import ru.dbotthepony.kstarbound.io.json.Vector2fTypeAdapter import ru.dbotthepony.kstarbound.io.json.Vector2iTypeAdapter import ru.dbotthepony.kstarbound.io.json.Vector4iTypeAdapter import ru.dbotthepony.kstarbound.io.json.builder.EnumAdapter +import ru.dbotthepony.kstarbound.io.json.factory.ArrayListAdapterFactory import ru.dbotthepony.kstarbound.io.json.factory.ImmutableCollectionAdapterFactory import ru.dbotthepony.kstarbound.math.PolyTypeAdapter fun addStarboundJsonAdapters(builder: GsonBuilder) { with(builder) { - // ImmutableList, и прочее + // ImmutableList, ImmutableSet, ImmutableMap registerTypeAdapterFactory(ImmutableCollectionAdapterFactory) + // ArrayList + registerTypeAdapterFactory(ArrayListAdapterFactory) + registerTypeAdapter(ColorTypeAdapter.nullSafe()) // математические классы diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/ArmorItemPrototype.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/ArmorItemPrototype.kt index 4141bdb4..d0e9fb7c 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/ArmorItemPrototype.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/ArmorItemPrototype.kt @@ -1,5 +1,6 @@ package ru.dbotthepony.kstarbound.defs.item +import com.google.common.collect.ImmutableList import ru.dbotthepony.kstarbound.Starbound import ru.dbotthepony.kstarbound.defs.util.enrollMap import ru.dbotthepony.kstarbound.io.json.builder.BuilderAdapter @@ -9,13 +10,13 @@ import ru.dbotthepony.kstarbound.io.json.neverNull import ru.dbotthepony.kstarbound.util.NotNullVar class ArmorItemPrototype : ItemPrototype(), IArmorItemDefinition { - override var colorOptions: List> = listOf() + override var colorOptions: ImmutableList> = ImmutableList.of() override var maleFrames: IArmorItemDefinition.ArmorFrames by NotNullVar() override var femaleFrames: IArmorItemDefinition.ArmorFrames by NotNullVar() override var level: Double = 1.0 - override var leveledStatusEffects: List = listOf() + override var leveledStatusEffects: ImmutableList = ImmutableList.of() - override var scripts: List = listOf() + override var scripts: ImmutableList = ImmutableList.of() override var scriptDelta: Int = 1 override var armorType: ArmorPieceType by NotNullVar() @@ -60,7 +61,7 @@ class ArmorItemPrototype : ItemPrototype(), IArmorItemDefinition { companion object { val ADAPTER = BuilderAdapter.Builder(::ArmorItemPrototype) .also { addFields(it as BuilderAdapter.Builder) } // безопасность: свойства родительского класса объявлены как final - .add(ArmorItemPrototype::colorOptions, Starbound.NULLABLE_STRING_ADAPTER.neverNull().asJsonObject().asList()) + .auto(ArmorItemPrototype::colorOptions) .auto(ArmorItemPrototype::maleFrames) .auto(ArmorItemPrototype::femaleFrames) .auto(ArmorItemPrototype::level) diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/CurrencyItemPrototype.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/CurrencyItemPrototype.kt index 6bf524a3..1a5b1b00 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/CurrencyItemPrototype.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/CurrencyItemPrototype.kt @@ -1,13 +1,14 @@ package ru.dbotthepony.kstarbound.defs.item +import com.google.common.collect.ImmutableList import ru.dbotthepony.kstarbound.defs.util.enrollMap import ru.dbotthepony.kstarbound.io.json.builder.BuilderAdapter import ru.dbotthepony.kstarbound.util.NotNullVar class CurrencyItemPrototype : ItemPrototype(), ICurrencyItemDefinition { - override var pickupSoundsSmall: List = listOf() - override var pickupSoundsMedium: List = listOf() - override var pickupSoundsLarge: List = listOf() + override var pickupSoundsSmall: ImmutableList = ImmutableList.of() + override var pickupSoundsMedium: ImmutableList = ImmutableList.of() + override var pickupSoundsLarge: ImmutableList = ImmutableList.of() override var smallStackLimit: Long by NotNullVar() override var mediumStackLimit: Long by NotNullVar() override var currency: String by NotNullVar() diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/ItemPrototype.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/ItemPrototype.kt index 014f8225..1bbb75c0 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/ItemPrototype.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/ItemPrototype.kt @@ -14,16 +14,16 @@ open class ItemPrototype : IItemDefinition, INativeJsonHolder { final override var price: Long = 0L final override var rarity: ItemRarity = ItemRarity.COMMON final override var category: String? = null - final override var inventoryIcon: ArrayList? = null - final override var itemTags: ArrayList = ArrayList() - final override var learnBlueprintsOnPickup: ArrayList = ArrayList() + final override var inventoryIcon: ImmutableList? = null + final override var itemTags: ImmutableList = ImmutableList.of() + final override var learnBlueprintsOnPickup: ImmutableList = ImmutableList.of() final override var maxStack: Long = 9999L final override var eventCategory: String? = null final override var consumeOnPickup: Boolean = false - final override var pickupQuestTemplates: ArrayList = ArrayList() + final override var pickupQuestTemplates: ImmutableList = ImmutableList.of() final override var tooltipKind: ItemTooltipKind = ItemTooltipKind.NORMAL final override var twoHanded: Boolean = false - final override var radioMessagesOnPickup: ArrayList = ArrayList() + final override var radioMessagesOnPickup: ImmutableList = ImmutableList.of() final override var fuelAmount: Long? = null var descriptionData: ThingDescription by NotNullVar() diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/builder/BuilderAdapter.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/builder/BuilderAdapter.kt index 34589ff1..43b24d8c 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/builder/BuilderAdapter.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/builder/BuilderAdapter.kt @@ -218,7 +218,7 @@ class BuilderAdapter private constructor( @OptIn(ExperimentalStdlibApi::class) override fun create(gson: Gson, type: TypeToken): TypeAdapter? { - if (type.isAssignableFrom(factoryReturnType)) { + if (type.rawType == factoryReturnType) { return build(gson) as TypeAdapter } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/factory/ArrayListAdapterFactory.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/factory/ArrayListAdapterFactory.kt new file mode 100644 index 00000000..bd1a825d --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/factory/ArrayListAdapterFactory.kt @@ -0,0 +1,17 @@ +package ru.dbotthepony.kstarbound.io.json.factory + +import com.google.gson.Gson +import com.google.gson.TypeAdapter +import com.google.gson.TypeAdapterFactory +import com.google.gson.reflect.TypeToken +import java.lang.reflect.ParameterizedType + +object ArrayListAdapterFactory : TypeAdapterFactory { + override fun create(gson: Gson, type: TypeToken): TypeAdapter? { + if (ArrayList::class.java.isAssignableFrom(type.rawType) && type.type is ParameterizedType) { + return ArrayListTypeAdapter(gson.getAdapter(TypeToken.get((type.type as ParameterizedType).actualTypeArguments[0]))).nullSafe() as TypeAdapter + } + + return null + } +} diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/factory/ArrayListTypeAdapter.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/factory/ArrayListTypeAdapter.kt new file mode 100644 index 00000000..8a1d6064 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/io/json/factory/ArrayListTypeAdapter.kt @@ -0,0 +1,45 @@ +package ru.dbotthepony.kstarbound.io.json.factory + +import com.google.gson.TypeAdapter +import com.google.gson.stream.JsonReader +import com.google.gson.stream.JsonToken +import com.google.gson.stream.JsonWriter +import java.util.ArrayList + +class ArrayListTypeAdapter(val elementAdapter: TypeAdapter) : TypeAdapter>() { + override fun write(out: JsonWriter, value: ArrayList) { + if (value.size == 1) { + elementAdapter.write(out, value[0]) + return + } + + out.beginArray() + + for (v in value) { + elementAdapter.write(out, v) + } + + out.endArray() + } + + override fun read(reader: JsonReader): ArrayList { + if (reader.peek() != JsonToken.BEGIN_ARRAY) { + // не массив, возможно упрощение структуры "a": [value] -> "a": value + val list = ArrayList(1) + list.add(elementAdapter.read(reader)) + return list + } + + reader.beginArray() + + val list = ArrayList() + + while (reader.peek() != JsonToken.END_ARRAY) { + list.add(elementAdapter.read(reader)) + } + + reader.endArray() + + return list + } +}