From 5e29072fcf881cddd670bf5c76c634c194206ade Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Thu, 29 Dec 2022 16:32:24 +0700 Subject: [PATCH] =?UTF-8?q?=D0=91=D0=BE=D0=BB=D1=8C=D1=88=D0=B5=20=D1=81?= =?UTF-8?q?=D0=B2=D0=BE=D0=B9=D1=81=D1=82=D0=B2=20=D1=83=20=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D1=82=D0=BE=D1=82=D0=B8=D0=BF=D0=B0=20=D0=BF=D1=80=D0=B5?= =?UTF-8?q?=D0=B4=D0=BC=D0=B5=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kstarbound/defs/item/ItemDefinition.kt | 96 ++++++++++++++++++- .../kstarbound/io/KConcreteTypeAdapter.kt | 78 ++++++++------- 2 files changed, 141 insertions(+), 33 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/ItemDefinition.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/ItemDefinition.kt index e127f287..c9b566a0 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/ItemDefinition.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/defs/item/ItemDefinition.kt @@ -3,6 +3,8 @@ package ru.dbotthepony.kstarbound.defs.item import com.google.gson.GsonBuilder import ru.dbotthepony.kstarbound.io.KConcreteTypeAdapter import ru.dbotthepony.kstarbound.registerTypeAdapter +import ru.dbotthepony.kvector.vector.ndouble.Vector2d +import ru.dbotthepony.kvector.vector.nint.Vector2i data class ItemDefinition( val itemName: String, @@ -12,8 +14,71 @@ data class ItemDefinition( val inventoryIcon: String? = null, val description: String = "...", val shortdescription: String = "...", - val itemTags: List = listOf() + val itemTags: List = listOf(), + val learnBlueprintsOnPickup: List = listOf(), + val maxStack: Long = 9999L, + val eventCategory: String? = null, + val consumeOnPickup: Boolean = false, + val pickupQuestTemplates: List = listOf(), + + /** + * Используется в костях-ископаемых + */ + val race: String? = null, + val displayImage: String? = null, + val displayoffset: Vector2d? = null, + + /** + * Используется в костях-ископаемых + */ + val fossilSetName: String? = null, + + /** + * Используется в костях-ископаемых + */ + val setIndex: Int? = null, + + /** + * Используется в костях-ископаемых + */ + val setCount: Int? = null, + + /** + * Используется в костях-ископаемых + */ + val setCollectables: Map? = null, + + /** + * Используется в костях-ископаемых + */ + val completeFossilIcon: String? = null, + + /** + * Используется в костях-ископаемых + */ + val completeFossilObject: String? = null, + + /** + * Используется в костях-ископаемых + */ + val completeSetDescriptions: FossilSetDescription? = null, + + /** + * Заставляет SAIL болтать + */ + val radioMessagesOnPickup: List = listOf(), + + /** + * Топливо корабля + */ + val fuelAmount: Long? = null, ) { + data class FossilSetDescription( + val price: Long = 0L, + val shortdescription: String = "...", + val description: String = "..." + ) + companion object { val ADAPTER = KConcreteTypeAdapter.Builder(ItemDefinition::class) .plain(ItemDefinition::itemName) @@ -23,11 +88,40 @@ data class ItemDefinition( .plain(ItemDefinition::inventoryIcon) .plain(ItemDefinition::description) .plain(ItemDefinition::shortdescription) + .list(ItemDefinition::itemTags) + .list(ItemDefinition::learnBlueprintsOnPickup) + + .plain(ItemDefinition::maxStack) + .plain(ItemDefinition::eventCategory) + .plain(ItemDefinition::consumeOnPickup) + .list(ItemDefinition::pickupQuestTemplates) + + .plain(ItemDefinition::race) + .plain(ItemDefinition::displayImage) + .plain(ItemDefinition::displayoffset) + .plain(ItemDefinition::fossilSetName) + .plain(ItemDefinition::setIndex) + .plain(ItemDefinition::setCount) + .map(ItemDefinition::setCollectables, String::class) + .plain(ItemDefinition::completeFossilIcon) + .plain(ItemDefinition::completeFossilObject) + + .plain(ItemDefinition::completeSetDescriptions) + .list(ItemDefinition::radioMessagesOnPickup) + .plain(ItemDefinition::fuelAmount) + + .build() + + val FOSSIL_ADAPTER = KConcreteTypeAdapter.Builder(FossilSetDescription::class) + .plain(FossilSetDescription::price) + .plain(FossilSetDescription::shortdescription) + .plain(FossilSetDescription::description) .build() fun registerGson(gsonBuilder: GsonBuilder) { gsonBuilder.registerTypeAdapter(ADAPTER) + gsonBuilder.registerTypeAdapter(FOSSIL_ADAPTER) } } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/io/KConcreteTypeAdapter.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/io/KConcreteTypeAdapter.kt index e510432e..5580d987 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/io/KConcreteTypeAdapter.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/io/KConcreteTypeAdapter.kt @@ -2,8 +2,8 @@ package ru.dbotthepony.kstarbound.io import com.google.common.collect.ImmutableList import com.google.common.collect.ImmutableMap +import com.google.common.collect.Interner import com.google.common.collect.Interners -import com.google.gson.GsonBuilder import com.google.gson.JsonSyntaxException import com.google.gson.TypeAdapter import com.google.gson.internal.bind.TypeAdapters @@ -18,19 +18,19 @@ import ru.dbotthepony.kstarbound.Starbound import ru.dbotthepony.kstarbound.getValue import ru.dbotthepony.kstarbound.setValue import java.lang.reflect.Constructor -import java.util.BitSet import kotlin.jvm.internal.DefaultConstructorMarker +import kotlin.properties.Delegates import kotlin.reflect.* import kotlin.reflect.full.isSuperclassOf import kotlin.reflect.full.isSupertypeOf import kotlin.reflect.full.memberProperties @Suppress("unchecked_cast") -private fun resolveBound(bound: Class): TypeAdapter { +private fun resolveBound(bound: Class, stringAdapter: TypeAdapter): TypeAdapter { return when (bound) { Float::class.java -> TypeAdapters.FLOAT as TypeAdapter Double::class.java -> TypeAdapters.DOUBLE as TypeAdapter - String::class.java -> TypeAdapters.STRING as TypeAdapter + String::class.java -> stringAdapter as TypeAdapter Int::class.java -> TypeAdapters.INTEGER as TypeAdapter Long::class.java -> TypeAdapters.LONG as TypeAdapter Boolean::class.java -> TypeAdapters.BOOLEAN as TypeAdapter @@ -38,10 +38,8 @@ private fun resolveBound(bound: Class): TypeAdapter { } } -class ListAdapter(private val bound: Class) : TypeAdapter>() { - private val resolvedBound by lazy { - resolveBound(bound) - } +private class ListAdapter(private val bound: Class, private val stringAdapter: TypeAdapter) : TypeAdapter>() { + private val resolvedBound by lazy { resolveBound(bound, stringAdapter) } override fun write(out: JsonWriter, value: List) { out.beginArray() @@ -72,14 +70,9 @@ class ListAdapter(private val bound: Class) : TypeAdapter>() { } } -class MapAdapter(private val boundKey: Class, private val boundValue: Class) : TypeAdapter>() { - private val resolvedKey by lazy { - resolveBound(boundKey) - } - - private val resolvedValue by lazy { - resolveBound(boundValue) - } +private class MapAdapter(private val boundKey: Class, private val boundValue: Class, private val stringAdapter: TypeAdapter) : TypeAdapter>() { + private val resolvedKey by lazy { resolveBound(boundKey, stringAdapter) } + private val resolvedValue by lazy { resolveBound(boundValue, stringAdapter) } override fun write(out: JsonWriter, value: Map) { out.beginArray() @@ -117,10 +110,8 @@ class MapAdapter(private val boundKey: Class, private val boundValue: C } } -class StringMapAdapter(private val bound: Class) : TypeAdapter>() { - private val resolvedBound by lazy { - resolveBound(bound) - } +private class StringMapAdapter(private val bound: Class, private val stringAdapter: TypeAdapter, private val interner: () -> Interner) : TypeAdapter>() { + private val resolvedBound by lazy { resolveBound(bound, stringAdapter) } override fun write(out: JsonWriter, value: Map) { val resolvedBound = resolvedBound @@ -143,7 +134,7 @@ class StringMapAdapter(private val bound: Class) : TypeAdapter(private val bound: Class) : TypeAdapter(private val bound: Class) : TypeAdapter() { - private val resolved by lazy { resolveBound(bound) } + private val resolved by lazy { resolveBound(bound, TypeAdapters.STRING) } override fun write(out: JsonWriter, value: T) { resolved.write(out, value) @@ -441,6 +432,17 @@ class KConcreteTypeAdapter( */ class Builder(val clazz: KClass) { private val types = ArrayList, TypeAdapter<*>>>() + private var interner by Delegates.notNull>() + + private val internedStringAdapter: TypeAdapter = object : TypeAdapter() { + override fun write(out: JsonWriter, value: String) { + return TypeAdapters.STRING.write(out, value) + } + + override fun read(`in`: JsonReader): String { + return interner.intern(TypeAdapters.STRING.read(`in`)) + } + } /** * Добавляет поле с определённым адаптером @@ -467,7 +469,7 @@ class KConcreteTypeAdapter( } else if (classifier.isSuperclassOf(Long::class)) { types.add(field to TypeAdapters.LONG) } else if (classifier.isSuperclassOf(String::class)) { - types.add(field to TypeAdapters.STRING) + types.add(field to internedStringAdapter) } else if (classifier.isSuperclassOf(Boolean::class)) { types.add(field to TypeAdapters.BOOLEAN) } else { @@ -498,7 +500,7 @@ class KConcreteTypeAdapter( * Список неизменяем (создаётся объект [ImmutableList]) */ fun list(field: KProperty1?>, type: Class): Builder { - types.add(field to ListAdapter(type)) + types.add(field to ListAdapter(type, internedStringAdapter)) return this } @@ -517,7 +519,7 @@ class KConcreteTypeAdapter( * Таблица неизменяема (создаётся объект [ImmutableMap]) */ fun map(field: KProperty1>, keyType: Class, valueType: Class): Builder { - types.add(field to MapAdapter(keyType, valueType)) + types.add(field to MapAdapter(keyType, valueType, internedStringAdapter)) return this } @@ -526,8 +528,8 @@ class KConcreteTypeAdapter( * * Таблица неизменяема (создаётся объект [ImmutableMap]) */ - fun map(field: KProperty1>, keyType: KClass, valueType: KClass): Builder { - types.add(field to MapAdapter(keyType.java, valueType.java)) + fun map(field: KProperty1?>, keyType: KClass, valueType: KClass): Builder { + types.add(field to MapAdapter(keyType.java, valueType.java, internedStringAdapter)) return this } @@ -536,8 +538,8 @@ class KConcreteTypeAdapter( * * Таблица неизменяема (создаётся объект [ImmutableMap]) */ - fun map(field: KProperty1>, valueType: Class): Builder { - types.add(field to StringMapAdapter(valueType)) + fun map(field: KProperty1?>, valueType: Class): Builder { + types.add(field to StringMapAdapter(valueType, internedStringAdapter, ::interner)) return this } @@ -546,17 +548,29 @@ class KConcreteTypeAdapter( * * Таблица неизменяема (создаётся объект [ImmutableMap]) */ - fun map(field: KProperty1>, valueType: KClass): Builder { - types.add(field to StringMapAdapter(valueType.java)) + fun map(field: KProperty1?>, valueType: KClass): Builder { + types.add(field to StringMapAdapter(valueType.java, internedStringAdapter, ::interner)) return this } fun build(asList: Boolean = false): KConcreteTypeAdapter { - return KConcreteTypeAdapter(clazz, ImmutableList.copyOf(types), asList = asList) + return KConcreteTypeAdapter(clazz, ImmutableList.copyOf(types), asList = asList).also { + interner = it.internedStrings + } } } companion object { private val LOGGER = LogManager.getLogger() + + /*fun simple(clazz: KClass, asList: Boolean = false): KConcreteTypeAdapter { + val builder = Builder(clazz) + + for (argument in clazz.primaryConstructor!!.parameters) { + builder.plain(argument.) + } + + return builder.build(asList = asList) + }*/ } }