Move android research type to codecs
This commit is contained in:
parent
e39bb8e1ab
commit
3117349757
@ -1,11 +1,14 @@
|
|||||||
package ru.dbotthepony.mc.otm.android
|
package ru.dbotthepony.mc.otm.android
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArraySet
|
import it.unimi.dsi.fastutil.objects.ObjectArraySet
|
||||||
import net.minecraft.data.CachedOutput
|
import net.minecraft.data.CachedOutput
|
||||||
import net.minecraft.data.DataProvider
|
import net.minecraft.data.DataProvider
|
||||||
import net.minecraft.data.PackOutput
|
import net.minecraft.data.PackOutput
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
import net.minecraftforge.data.event.GatherDataEvent
|
import net.minecraftforge.data.event.GatherDataEvent
|
||||||
|
import ru.dbotthepony.mc.otm.core.toJson
|
||||||
|
import ru.dbotthepony.mc.otm.core.toJsonStrict
|
||||||
import ru.dbotthepony.mc.otm.core.util.WriteOnce
|
import ru.dbotthepony.mc.otm.core.util.WriteOnce
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
import java.util.LinkedList
|
import java.util.LinkedList
|
||||||
@ -56,7 +59,7 @@ open class AndroidResearchDataProvider() : DataProvider {
|
|||||||
|
|
||||||
addEverything {
|
addEverything {
|
||||||
if (set.add(it.id)) {
|
if (set.add(it.id)) {
|
||||||
futures.add(DataProvider.saveStable(output, it.toJson(), pathProvider.json(it.id)))
|
futures.add(DataProvider.saveStable(output, AndroidResearchType.CODEC.toJsonStrict(it).also { (it as JsonObject).remove("id") }, pathProvider.json(it.id)))
|
||||||
AndroidResearchManager.put(it)
|
AndroidResearchManager.put(it)
|
||||||
added.add(it)
|
added.add(it)
|
||||||
} else {
|
} else {
|
||||||
|
@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableMap
|
|||||||
import com.google.gson.GsonBuilder
|
import com.google.gson.GsonBuilder
|
||||||
import com.google.gson.JsonElement
|
import com.google.gson.JsonElement
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
|
import com.google.gson.JsonSyntaxException
|
||||||
import net.minecraft.client.server.IntegratedServer
|
import net.minecraft.client.server.IntegratedServer
|
||||||
import net.minecraft.network.FriendlyByteBuf
|
import net.minecraft.network.FriendlyByteBuf
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
@ -22,6 +23,13 @@ import ru.dbotthepony.mc.otm.NULLABLE_MINECRAFT_SERVER
|
|||||||
import ru.dbotthepony.mc.otm.SERVER_IS_LIVE
|
import ru.dbotthepony.mc.otm.SERVER_IS_LIVE
|
||||||
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||||
import ru.dbotthepony.mc.otm.client.minecraft
|
import ru.dbotthepony.mc.otm.client.minecraft
|
||||||
|
import ru.dbotthepony.mc.otm.core.fromJsonStrict
|
||||||
|
import ru.dbotthepony.mc.otm.core.fromNetwork
|
||||||
|
import ru.dbotthepony.mc.otm.core.set
|
||||||
|
import ru.dbotthepony.mc.otm.core.toJsonStrict
|
||||||
|
import ru.dbotthepony.mc.otm.core.toNetwork
|
||||||
|
import ru.dbotthepony.mc.otm.core.util.readJson
|
||||||
|
import ru.dbotthepony.mc.otm.matter.MatterManager
|
||||||
import ru.dbotthepony.mc.otm.network.MatteryPacket
|
import ru.dbotthepony.mc.otm.network.MatteryPacket
|
||||||
import ru.dbotthepony.mc.otm.network.RegistryNetworkChannel
|
import ru.dbotthepony.mc.otm.network.RegistryNetworkChannel
|
||||||
import ru.dbotthepony.mc.otm.network.enqueueWork
|
import ru.dbotthepony.mc.otm.network.enqueueWork
|
||||||
@ -67,7 +75,13 @@ object AndroidResearchManager : SimpleJsonResourceReloadListener(GsonBuilder().s
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.put(k, AndroidResearchType.fromJson(v, k))
|
v["id"] = k.toString()
|
||||||
|
|
||||||
|
try {
|
||||||
|
builder.put(k, AndroidResearchType.CODEC.fromJsonStrict(v))
|
||||||
|
} catch(err: RuntimeException) {
|
||||||
|
throw JsonSyntaxException("Caught an exception while decoding android research $k", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
researchMap = builder.build()
|
researchMap = builder.build()
|
||||||
@ -101,7 +115,8 @@ object AndroidResearchManager : SimpleJsonResourceReloadListener(GsonBuilder().s
|
|||||||
|
|
||||||
class SyncPacket(val collection: Collection<AndroidResearchType>) : MatteryPacket {
|
class SyncPacket(val collection: Collection<AndroidResearchType>) : MatteryPacket {
|
||||||
override fun write(buff: FriendlyByteBuf) {
|
override fun write(buff: FriendlyByteBuf) {
|
||||||
buff.writeCollection(collection) { a, b -> b.toNetwork(a) }
|
buff.writeCollection(collection) { a, b -> AndroidResearchType.CODEC.toNetwork(a, b) }
|
||||||
|
LOGGER.debug("Constructed android research registry packet, ${buff.writerIndex()} bytes in size")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||||
@ -130,6 +145,7 @@ object AndroidResearchManager : SimpleJsonResourceReloadListener(GsonBuilder().s
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun readSyncPacket(buff: FriendlyByteBuf): SyncPacket {
|
fun readSyncPacket(buff: FriendlyByteBuf): SyncPacket {
|
||||||
return SyncPacket(buff.readCollection({ LinkedList() }, AndroidResearchType.Companion::fromNetwork))
|
LOGGER.info("Received android research registry packet, ${buff.readableBytes()} bytes in size")
|
||||||
|
return SyncPacket(buff.readCollection({ LinkedList() }, { AndroidResearchType.CODEC.fromNetwork(it) }))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,12 @@ import com.google.gson.JsonObject
|
|||||||
import com.google.gson.JsonPrimitive
|
import com.google.gson.JsonPrimitive
|
||||||
import com.google.gson.JsonSyntaxException
|
import com.google.gson.JsonSyntaxException
|
||||||
import com.google.gson.internal.bind.TypeAdapters
|
import com.google.gson.internal.bind.TypeAdapters
|
||||||
|
import com.mojang.datafixers.util.Either
|
||||||
|
import com.mojang.serialization.Codec
|
||||||
|
import com.mojang.serialization.JsonOps
|
||||||
|
import com.mojang.serialization.codecs.ListCodec
|
||||||
|
import com.mojang.serialization.codecs.PairCodec
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
|
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
|
||||||
import net.minecraft.network.FriendlyByteBuf
|
import net.minecraft.network.FriendlyByteBuf
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
@ -33,11 +39,18 @@ import ru.dbotthepony.mc.otm.core.fromJsonStrict
|
|||||||
import ru.dbotthepony.mc.otm.core.toJsonStrict
|
import ru.dbotthepony.mc.otm.core.toJsonStrict
|
||||||
import ru.dbotthepony.mc.otm.core.util.readJson
|
import ru.dbotthepony.mc.otm.core.util.readJson
|
||||||
import ru.dbotthepony.mc.otm.core.util.writeJson
|
import ru.dbotthepony.mc.otm.core.util.writeJson
|
||||||
|
import ru.dbotthepony.mc.otm.data.ComponentCodec
|
||||||
|
import ru.dbotthepony.mc.otm.data.IngredientCodec
|
||||||
|
import ru.dbotthepony.mc.otm.data.JsonElementCodec
|
||||||
|
import ru.dbotthepony.mc.otm.data.simpleCodec
|
||||||
import ru.dbotthepony.mc.otm.isClient
|
import ru.dbotthepony.mc.otm.isClient
|
||||||
import java.util.LinkedList
|
import java.util.LinkedList
|
||||||
|
import java.util.Optional
|
||||||
|
import java.util.function.Function
|
||||||
import java.util.stream.Stream
|
import java.util.stream.Stream
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
import kotlin.collections.HashSet
|
import kotlin.collections.HashSet
|
||||||
|
import kotlin.jvm.optionals.getOrNull
|
||||||
|
|
||||||
private fun findPrerequisites(
|
private fun findPrerequisites(
|
||||||
initial: Collection<AndroidResearchType>,
|
initial: Collection<AndroidResearchType>,
|
||||||
@ -97,6 +110,25 @@ class AndroidResearchType(
|
|||||||
val itemIcon: Item? = null,
|
val itemIcon: Item? = null,
|
||||||
iconText: Component? = null,
|
iconText: Component? = null,
|
||||||
) {
|
) {
|
||||||
|
private constructor(
|
||||||
|
id: ResourceLocation,
|
||||||
|
prerequisites: Collection<Reference>,
|
||||||
|
blockedBy: Collection<Reference>,
|
||||||
|
|
||||||
|
items: Collection<Pair<Ingredient, Int>>,
|
||||||
|
results: Collection<AndroidResearchResult>,
|
||||||
|
|
||||||
|
description: Collection<AndroidResearchDescription>,
|
||||||
|
|
||||||
|
experienceLevels: Int,
|
||||||
|
customName: Optional<Component>,
|
||||||
|
|
||||||
|
// ok
|
||||||
|
skinIcon: Optional<JsonObject>,
|
||||||
|
itemIcon: Optional<Item>,
|
||||||
|
iconText: Optional<Component>,
|
||||||
|
) : this(id, prerequisites, blockedBy, items.stream().map { Pair(it.first, it.second) }.toList(), results, description, experienceLevels, customName.getOrNull(), skinIcon.getOrNull(), itemIcon.getOrNull(), iconText.getOrNull())
|
||||||
|
|
||||||
private val iconTextValue = iconText?.copy()
|
private val iconTextValue = iconText?.copy()
|
||||||
val iconText get() = iconTextValue?.copy()
|
val iconText get() = iconTextValue?.copy()
|
||||||
|
|
||||||
@ -110,38 +142,21 @@ class AndroidResearchType(
|
|||||||
|
|
||||||
data class Reference(
|
data class Reference(
|
||||||
val id: ResourceLocation,
|
val id: ResourceLocation,
|
||||||
val isRigid: Boolean
|
val optional: Boolean = false
|
||||||
) {
|
) {
|
||||||
fun toJson(): JsonObject {
|
|
||||||
return JsonObject().also {
|
|
||||||
it["id"] = JsonPrimitive(id.toString())
|
|
||||||
it["is_rigid"] = JsonPrimitive(isRigid)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun toNetwork(buff: FriendlyByteBuf) {
|
|
||||||
buff.writeUtf(id.toString())
|
|
||||||
buff.writeBoolean(isRigid)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun fromNetwork(buff: FriendlyByteBuf): Reference {
|
val CODEC: Codec<Reference> by lazy {
|
||||||
return Reference(
|
Codec
|
||||||
ResourceLocation(buff.readUtf()),
|
.either(ResourceLocation.CODEC, RecordCodecBuilder.create<Reference> {
|
||||||
buff.readBoolean()
|
it.group(
|
||||||
)
|
ResourceLocation.CODEC.fieldOf("id").forGetter(Reference::id),
|
||||||
}
|
Codec.BOOL.optionalFieldOf("optional", false).forGetter(Reference::optional)
|
||||||
|
).apply(it, ::Reference)
|
||||||
fun fromJson(value: JsonElement): Reference {
|
})
|
||||||
if (value is JsonPrimitive) {
|
.xmap(
|
||||||
return Reference(ResourceLocation(value.asString), true)
|
{ c -> c.map(::Reference, Function.identity()) },
|
||||||
} else if (value is JsonObject) {
|
{ c -> if (c.optional) Either.right(c) else Either.left(c.id) }
|
||||||
return Reference(
|
)
|
||||||
ResourceLocation((value["id"] as? JsonPrimitive ?: throw JsonSyntaxException("Invalid `id` value")).asString),
|
|
||||||
(value["is_rigid"] as JsonPrimitive?)?.asBoolean ?: true)
|
|
||||||
} else {
|
|
||||||
throw JsonSyntaxException("Unknown element type ${value::class.qualifiedName}")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -174,11 +189,11 @@ class AndroidResearchType(
|
|||||||
val blockedBy: List<Reference> = ImmutableList.copyOf(blockedBy)
|
val blockedBy: List<Reference> = ImmutableList.copyOf(blockedBy)
|
||||||
|
|
||||||
val resolvedPrerequisites: List<AndroidResearchType> by lazy {
|
val resolvedPrerequisites: List<AndroidResearchType> by lazy {
|
||||||
ImmutableList.copyOf(this.prerequisites.mapNotNull { AndroidResearchManager[it.id].also { e -> if (e == null && it.isRigid) throw NoSuchElementException("Unable to find research ${it.id}") } })
|
ImmutableList.copyOf(this.prerequisites.mapNotNull { AndroidResearchManager[it.id].also { e -> if (e == null && it.optional) throw NoSuchElementException("Unable to find research ${it.id}") } })
|
||||||
}
|
}
|
||||||
|
|
||||||
val resolvedBlockedBy: List<AndroidResearchType> by lazy {
|
val resolvedBlockedBy: List<AndroidResearchType> by lazy {
|
||||||
ImmutableList.copyOf(this.blockedBy.mapNotNull { AndroidResearchManager[it.id].also { e -> if (e == null && it.isRigid) throw NoSuchElementException("Unable to find research ${it.id}") } })
|
ImmutableList.copyOf(this.blockedBy.mapNotNull { AndroidResearchManager[it.id].also { e -> if (e == null && it.optional) throw NoSuchElementException("Unable to find research ${it.id}") } })
|
||||||
}
|
}
|
||||||
|
|
||||||
private val definedItems: List<Pair<Ingredient, Int>> = ImmutableList.copyOf(items)
|
private val definedItems: List<Pair<Ingredient, Int>> = ImmutableList.copyOf(items)
|
||||||
@ -380,141 +395,35 @@ class AndroidResearchType(
|
|||||||
return customName?.copy() ?: MutableComponent.create(displayContents)
|
return customName?.copy() ?: MutableComponent.create(displayContents)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toJson(): JsonElement {
|
|
||||||
return JsonObject().also {
|
|
||||||
it["prerequisites"] = JsonArray().also { for (value in prerequisites) it.add(value.toJson()) }
|
|
||||||
it["blocked_by"] = JsonArray().also { for (value in blockedBy) it.add(value.toJson()) }
|
|
||||||
it["required_items"] = JsonArray().also { for (item in definedItems) it.add(JsonObject().also { it["count"] = JsonPrimitive(item.second); it["ingredient"] = item.first.toJson() }) }
|
|
||||||
it["results"] = JsonArray().also { for (result in results) it.add(AndroidResearchResult.CODEC.toJsonStrict(result)) }
|
|
||||||
it["description"] = JsonArray().also { for (line in description) it.add(AndroidResearchDescription.CODEC.toJsonStrict(line)) }
|
|
||||||
it["experience"] = JsonPrimitive(experienceLevels)
|
|
||||||
|
|
||||||
if (skinIcon != null) {
|
|
||||||
it["skin_icon"] = skinIcon
|
|
||||||
}
|
|
||||||
|
|
||||||
if (itemIcon != null) {
|
|
||||||
it["item_icon"] = JsonPrimitive(itemIcon.registryName!!.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iconTextValue != null) {
|
|
||||||
it["icon_text"] = Component.Serializer.toJsonTree(iconTextValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (customName != null) {
|
|
||||||
it["custom_name"] = Component.Serializer.toJsonTree(customName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun validate() {
|
fun validate() {
|
||||||
resolvedBlockedBy
|
resolvedBlockedBy
|
||||||
resolvedPrerequisites
|
resolvedPrerequisites
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toNetwork(buff: FriendlyByteBuf) {
|
|
||||||
buff.writeUtf(id.toString())
|
|
||||||
buff.writeCollection(prerequisites) { a, b -> b.toNetwork(a) }
|
|
||||||
buff.writeCollection(blockedBy) { a, b -> b.toNetwork(a) }
|
|
||||||
buff.writeCollection(definedItems) { a, b -> b.first.toNetwork(a); a.writeVarInt(b.second) }
|
|
||||||
buff.writeCollection(results) { a, b -> a.writeJson(AndroidResearchResult.CODEC.toJsonStrict(b)) }
|
|
||||||
buff.writeCollection(description) { a, b -> a.writeJson(AndroidResearchDescription.CODEC.toJsonStrict(b)) }
|
|
||||||
buff.writeVarInt(experienceLevels)
|
|
||||||
|
|
||||||
buff.writeBoolean(customName != null)
|
|
||||||
if (customName != null) buff.writeComponent(customName)
|
|
||||||
|
|
||||||
buff.writeBoolean(iconTextValue != null)
|
|
||||||
if (iconTextValue != null) buff.writeComponent(iconTextValue)
|
|
||||||
|
|
||||||
buff.writeBoolean(skinIcon != null)
|
|
||||||
if (skinIcon != null) buff.writeUtf(skinIcon.toString())
|
|
||||||
|
|
||||||
buff.writeBoolean(itemIcon != null)
|
|
||||||
if (itemIcon != null) buff.writeUtf(itemIcon.registryName!!.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun fromNetwork(buff: FriendlyByteBuf): AndroidResearchType {
|
val CODEC: Codec<AndroidResearchType> by lazy {
|
||||||
val id = ResourceLocation(buff.readUtf())
|
RecordCodecBuilder.create {
|
||||||
val prerequisites = buff.readCollection({ LinkedList() }, Reference::fromNetwork)
|
it.group(
|
||||||
val blockedBy = buff.readCollection({ LinkedList() }, Reference::fromNetwork)
|
ResourceLocation.CODEC.fieldOf("id").forGetter(AndroidResearchType::id),
|
||||||
val items = buff.readCollection({ LinkedList() }, { Ingredient.fromNetwork(it) to it.readVarInt() })
|
ListCodec(Reference.CODEC).fieldOf("prerequisites").forGetter(AndroidResearchType::prerequisites),
|
||||||
val results = buff.readCollection({ LinkedList() }, { AndroidResearchResult.CODEC.fromJsonStrict(it.readJson()) })
|
ListCodec(Reference.CODEC).fieldOf("blockedBy").forGetter(AndroidResearchType::blockedBy),
|
||||||
val description = buff.readCollection({ LinkedList() }, { AndroidResearchDescription.CODEC.fromJsonStrict(it.readJson()) })
|
ListCodec(
|
||||||
val experienceLevels = buff.readVarInt()
|
RecordCodecBuilder.create<Pair<Ingredient, Int>> {
|
||||||
|
it.group(
|
||||||
val customName = if (buff.readBoolean()) {
|
IngredientCodec.fieldOf("item").forGetter { it.first },
|
||||||
buff.readComponent()
|
Codec.intRange(1, Int.MAX_VALUE).optionalFieldOf("count", 1).forGetter { it.second }
|
||||||
} else {
|
).apply(it, ::Pair)
|
||||||
null
|
}
|
||||||
|
).fieldOf("items").forGetter { it.definedItems },
|
||||||
|
ListCodec(AndroidResearchResult.CODEC).fieldOf("results").forGetter(AndroidResearchType::results),
|
||||||
|
ListCodec(AndroidResearchDescription.CODEC).fieldOf("description").forGetter(AndroidResearchType::description),
|
||||||
|
Codec.intRange(0, Int.MAX_VALUE).fieldOf("experienceLevels").forGetter(AndroidResearchType::experienceLevels),
|
||||||
|
ComponentCodec.optionalFieldOf("customName").forGetter { Optional.ofNullable(it.customName) },
|
||||||
|
JsonElementCodec.xmap({ it as? JsonObject ?: throw JsonSyntaxException("Not a json object: $it") }, { it }).optionalFieldOf("skinIcon").forGetter { Optional.ofNullable(it.skinIcon) },
|
||||||
|
ForgeRegistries.ITEMS.codec.optionalFieldOf("itemIcon").forGetter { Optional.ofNullable(it.itemIcon) },
|
||||||
|
ComponentCodec.optionalFieldOf("iconTextValue").forGetter { Optional.ofNullable(it.iconTextValue) },
|
||||||
|
).apply(it, ::AndroidResearchType)
|
||||||
}
|
}
|
||||||
|
|
||||||
val iconTextValue = if (buff.readBoolean()) {
|
|
||||||
buff.readComponent()
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
val skinIcon = if (buff.readBoolean()) {
|
|
||||||
TypeAdapters.JSON_ELEMENT.fromJson(buff.readUtf()) as JsonObject
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
val itemIcon = if (buff.readBoolean()) {
|
|
||||||
ForgeRegistries.ITEMS.getValue(ResourceLocation(buff.readUtf()))?.let { if (it == Items.AIR) null else it }
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
return AndroidResearchType(
|
|
||||||
id = id,
|
|
||||||
prerequisites = prerequisites,
|
|
||||||
blockedBy = blockedBy,
|
|
||||||
items = items,
|
|
||||||
results = results,
|
|
||||||
description = description,
|
|
||||||
experienceLevels = experienceLevels,
|
|
||||||
customName = customName,
|
|
||||||
iconText = iconTextValue,
|
|
||||||
skinIcon = skinIcon,
|
|
||||||
itemIcon = itemIcon,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun fromJson(value: JsonElement, id: ResourceLocation): AndroidResearchType {
|
|
||||||
if (value !is JsonObject) {
|
|
||||||
throw JsonSyntaxException("Android research type must be of Json Object")
|
|
||||||
}
|
|
||||||
|
|
||||||
val prerequisites = value["prerequisites"] as JsonArray? ?: JsonArray()
|
|
||||||
val blocked_by = value["blocked_by"] as JsonArray? ?: JsonArray()
|
|
||||||
val items = value["required_items"] as JsonArray? ?: JsonArray()
|
|
||||||
val features = value["feature_result"] as JsonArray? ?: JsonArray()
|
|
||||||
val description = value["description"] as JsonArray? ?: JsonArray()
|
|
||||||
val experience = value["experience"]?.asInt ?: 0
|
|
||||||
val customName = value["custom_name"]?.let(Component.Serializer::fromJson)
|
|
||||||
val iconText = value["icon_text"]?.let(Component.Serializer::fromJson)
|
|
||||||
val skinIcon = value["skin_icon"] as JsonObject?
|
|
||||||
val itemIcon = value["item_icon"]?.let { ForgeRegistries.ITEMS.getValue(ResourceLocation(it.asString)).let { if (it == Items.AIR) null else it } }
|
|
||||||
|
|
||||||
return AndroidResearchType(
|
|
||||||
id = id,
|
|
||||||
prerequisites = prerequisites.stream().map { Reference.fromJson(it) }.toList(),
|
|
||||||
blockedBy = blocked_by.stream().map { Reference.fromJson(it) }.toList(),
|
|
||||||
results = features.stream().map { AndroidResearchResult.CODEC.fromJsonStrict(it) }.toList(),
|
|
||||||
items = items.stream()
|
|
||||||
.map { it as? JsonObject ?: throw JsonSyntaxException("One of items is not an JsonObject") }
|
|
||||||
.map { Ingredient.fromJson(it["ingredient"] ?: throw JsonSyntaxException("Missing ingredient key")) to (it["count"]?.asInt ?: throw JsonSyntaxException("Missing count key")) }
|
|
||||||
.toList(),
|
|
||||||
description = description.stream().map { AndroidResearchDescription.CODEC.fromJsonStrict(it) }.toList(),
|
|
||||||
experienceLevels = experience,
|
|
||||||
customName = customName,
|
|
||||||
iconText = iconText,
|
|
||||||
skinIcon = skinIcon,
|
|
||||||
itemIcon = itemIcon,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,8 @@ import net.minecraft.world.level.material.Fluid
|
|||||||
import net.minecraft.world.phys.Vec3
|
import net.minecraft.world.phys.Vec3
|
||||||
import net.minecraftforge.registries.ForgeRegistries
|
import net.minecraftforge.registries.ForgeRegistries
|
||||||
import net.minecraftforge.registries.IForgeRegistry
|
import net.minecraftforge.registries.IForgeRegistry
|
||||||
|
import ru.dbotthepony.mc.otm.core.util.readJson
|
||||||
|
import ru.dbotthepony.mc.otm.core.util.writeJson
|
||||||
|
|
||||||
// because doing it inline is ugly
|
// because doing it inline is ugly
|
||||||
fun <V : Any> Codec<V>.fromJson(value: JsonElement): V? {
|
fun <V : Any> Codec<V>.fromJson(value: JsonElement): V? {
|
||||||
@ -60,6 +62,14 @@ fun <V : Any> Codec<V>.toNbtStrict(value: V, prefix: Tag = NbtOps.INSTANCE.empty
|
|||||||
return encode(value, NbtOps.INSTANCE, prefix).get().map({ it }, { throw RuntimeException("Error encoding element: ${it.message()}") })
|
return encode(value, NbtOps.INSTANCE, prefix).get().map({ it }, { throw RuntimeException("Error encoding element: ${it.message()}") })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <V : Any> Codec<V>.toNetwork(buff: FriendlyByteBuf, value: V) {
|
||||||
|
buff.writeJson(toJsonStrict(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <V : Any> Codec<V>.fromNetwork(buff: FriendlyByteBuf): V {
|
||||||
|
return fromJsonStrict(buff.readJson())
|
||||||
|
}
|
||||||
|
|
||||||
// 1.19 being 1.19
|
// 1.19 being 1.19
|
||||||
fun TranslatableComponent(key: String, vararg values: Any): MutableComponent = MutableComponent.create(TranslatableContents(key, null, values))
|
fun TranslatableComponent(key: String, vararg values: Any): MutableComponent = MutableComponent.create(TranslatableContents(key, null, values))
|
||||||
fun TextComponent(value: String): MutableComponent = MutableComponent.create(LiteralContents(value))
|
fun TextComponent(value: String): MutableComponent = MutableComponent.create(LiteralContents(value))
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.data
|
||||||
|
|
||||||
|
import com.google.gson.JsonSyntaxException
|
||||||
|
import com.mojang.datafixers.util.Pair
|
||||||
|
import com.mojang.serialization.Codec
|
||||||
|
import com.mojang.serialization.DataResult
|
||||||
|
import com.mojang.serialization.DynamicOps
|
||||||
|
import com.mojang.serialization.JsonOps
|
||||||
|
import net.minecraft.world.item.crafting.Ingredient
|
||||||
|
|
||||||
|
object IngredientCodec : Codec<Ingredient> {
|
||||||
|
override fun <T : Any> encode(input: Ingredient, ops: DynamicOps<T>, prefix: T): DataResult<T> {
|
||||||
|
return DataResult.success(JsonOps.INSTANCE.convertTo(ops, input.toJson()))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T : Any> decode(ops: DynamicOps<T>, input: T): DataResult<Pair<Ingredient, T>> {
|
||||||
|
try {
|
||||||
|
return DataResult.success(Pair(Ingredient.fromJson(ops.convertTo(JsonOps.INSTANCE, input)), ops.empty()))
|
||||||
|
} catch (err: JsonSyntaxException) {
|
||||||
|
return DataResult.error { "Error decoding Ingredient: ${err.message}" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.data
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement
|
||||||
|
import com.mojang.datafixers.util.Pair
|
||||||
|
import com.mojang.serialization.Codec
|
||||||
|
import com.mojang.serialization.DataResult
|
||||||
|
import com.mojang.serialization.DynamicOps
|
||||||
|
import com.mojang.serialization.JsonOps
|
||||||
|
|
||||||
|
object JsonElementCodec : Codec<JsonElement> {
|
||||||
|
override fun <T : Any> encode(input: JsonElement, ops: DynamicOps<T>, prefix: T): DataResult<T> {
|
||||||
|
return DataResult.success(JsonOps.INSTANCE.convertTo(ops, input))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T : Any> decode(ops: DynamicOps<T>, input: T): DataResult<Pair<JsonElement, T>> {
|
||||||
|
return DataResult.success(Pair(ops.convertTo(JsonOps.INSTANCE, input), ops.empty()))
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user