mirror of
https://gitlab.com/cable-mc/cobblemon.git
synced 2026-10-20 14:16:26 -04:00
26.1.2 backport of dataregistry
Signed-off-by: Polymeta <4726322-polymeta@users.noreply.gitlab.com>
This commit is contained in:
@@ -12,6 +12,7 @@ import com.cobblemon.mod.common.api.net.NetworkPacket
|
||||
import com.mojang.brigadier.arguments.ArgumentType
|
||||
import kotlin.reflect.KClass
|
||||
import net.minecraft.commands.synchronization.ArgumentTypeInfo
|
||||
import net.minecraft.core.HolderLookup
|
||||
import net.minecraft.resources.ResourceKey
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.MinecraftServer
|
||||
@@ -168,12 +169,16 @@ interface CobblemonImplementation {
|
||||
* TODO
|
||||
*
|
||||
* @param identifier
|
||||
* @param reloader
|
||||
* @param reloaderFactory
|
||||
* @param type
|
||||
* @param dependencies
|
||||
*/
|
||||
fun registerResourceReloader(identifier: ResourceLocation, reloader: PreparableReloadListener, type: PackType, dependencies: Collection<ResourceLocation>)
|
||||
|
||||
fun registerResourceReloader(
|
||||
identifier: ResourceLocation,
|
||||
type: PackType,
|
||||
dependencies: Collection<ResourceLocation>,
|
||||
reloaderFactory: (HolderLookup.Provider) -> PreparableReloadListener
|
||||
)
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.data
|
||||
|
||||
import com.cobblemon.mod.common.util.endsWith
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import net.minecraft.core.HolderLookup
|
||||
import java.io.BufferedReader
|
||||
import java.io.File
|
||||
import java.util.concurrent.ExecutionException
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.packs.PackType
|
||||
import net.minecraft.server.packs.resources.ResourceManager
|
||||
|
||||
/**
|
||||
* A [DataRegistry] that consumes JSON files.
|
||||
* Every deserialized instance is attached to an [Identifier].
|
||||
* For example a file under data/mymod/[resourcePath]/entry.json would be backed by the identifier modid:entry.
|
||||
*
|
||||
* @param T The type of the data consumed by this registry.
|
||||
*
|
||||
* @author Licious
|
||||
* @since August 5th, 2022
|
||||
*/
|
||||
interface ServerJsonDataRegistry<T> : DataRegistry {
|
||||
|
||||
/**
|
||||
* The [TypeToken] of type [T].
|
||||
*/
|
||||
val typeToken: TypeToken<T>
|
||||
|
||||
/**
|
||||
* The folder location for the data this registry will consume.
|
||||
*/
|
||||
val resourcePath: String
|
||||
|
||||
override val type: PackType
|
||||
get() = PackType.SERVER_DATA
|
||||
|
||||
override fun reload(manager: ResourceManager) {
|
||||
//NO-OP, handled by reload(manager, registry)
|
||||
}
|
||||
|
||||
fun reload(manager: ResourceManager, registry: HolderLookup.Provider) {
|
||||
val gson = setupParser(registry)
|
||||
val data = hashMapOf<ResourceLocation, T>()
|
||||
manager.listResources(resourcePath) { path -> path.endsWith(JSON_EXTENSION) }.forEach { (identifier, resource) ->
|
||||
if (identifier.namespace == "pixelmon") {
|
||||
return@forEach
|
||||
}
|
||||
|
||||
resource.open().use { stream ->
|
||||
stream.bufferedReader().use { reader ->
|
||||
val resolvedIdentifier = ResourceLocation.fromNamespaceAndPath(identifier.namespace, File(identifier.path).nameWithoutExtension)
|
||||
data[resolvedIdentifier] = parse(reader, resolvedIdentifier, gson)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reload(data, registry)
|
||||
}
|
||||
|
||||
fun parse(reader: BufferedReader, identifier: ResourceLocation, gson: Gson): T {
|
||||
return try {
|
||||
gson.fromJson(reader, typeToken.type)
|
||||
} catch (exception: Exception) {
|
||||
throw ExecutionException("Error loading JSON for data: $identifier", exception)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the creation of [Gson] instances which have adapters that are registry-aware, e.g. [com.cobblemon.mod.common.pokemon.evolution.adapters.LegacyItemConditionWrapperAdapter]
|
||||
*/
|
||||
fun setupParser(registry: HolderLookup.Provider): Gson
|
||||
|
||||
/**
|
||||
* Reloads this registry from the deserialized data.
|
||||
*
|
||||
* @param data A map of the data associating an instance to the respective identifier from the [ResourceManager].
|
||||
*/
|
||||
fun reload(data: Map<ResourceLocation, T>, registry: HolderLookup.Provider)
|
||||
|
||||
companion object {
|
||||
const val JSON_EXTENSION = ".json"
|
||||
}
|
||||
}
|
||||
+24
-20
@@ -10,7 +10,7 @@ package com.cobblemon.mod.common.api.interaction
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.api.conditional.RegistryLikeCondition
|
||||
import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.data.ServerJsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||
import com.cobblemon.mod.common.api.pokemon.requirement.Requirement
|
||||
@@ -26,6 +26,7 @@ import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import net.minecraft.advancements.critereon.ItemPredicate
|
||||
import net.minecraft.core.HolderLookup
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.server.packs.PackType
|
||||
@@ -36,28 +37,31 @@ import net.minecraft.world.level.block.Block
|
||||
import net.minecraft.world.level.levelgen.structure.Structure
|
||||
import net.minecraft.world.level.material.Fluid
|
||||
|
||||
object PokemonInteractions : JsonDataRegistry<PokemonInteractionSet> {
|
||||
object PokemonInteractions : ServerJsonDataRegistry<PokemonInteractionSet> {
|
||||
override val id = cobblemonResource("pokemon_interactions")
|
||||
override val type = PackType.SERVER_DATA
|
||||
override fun setupParser(registry: HolderLookup.Provider): Gson {
|
||||
return GsonBuilder()
|
||||
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
|
||||
.registerTypeAdapter(PokemonProperties::class.java, pokemonPropertiesShortAdapter)
|
||||
.registerTypeAdapter(ItemPredicate::class.java, LegacyItemConditionWrapperAdapter(registry))
|
||||
.registerTypeAdapter(Requirement::class.java, CobblemonRequirementAdapter)
|
||||
.registerTypeAdapter(InteractionEffect::class.java, InteractionEffectAdapter)
|
||||
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
|
||||
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Biome::class.java).type, BiomeLikeConditionAdapter)
|
||||
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Block::class.java).type, BlockLikeConditionAdapter)
|
||||
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Item::class.java).type, ItemLikeConditionAdapter)
|
||||
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Structure::class.java).type, StructureLikeConditionAdapter)
|
||||
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Fluid::class.java).type, FluidLikeConditionAdapter)
|
||||
.registerTypeAdapter(IntRange::class.java, IntRangeAdapter)
|
||||
.registerTypeAdapterFactory(LowerCaseEnumTypeAdapterFactory())
|
||||
.setPrettyPrinting()
|
||||
.create()
|
||||
}
|
||||
|
||||
override val observable = SimpleObservable<PokemonInteractions>()
|
||||
override val typeToken: TypeToken<PokemonInteractionSet> = TypeToken.get(PokemonInteractionSet::class.java)
|
||||
override val resourcePath = "pokemon_interactions"
|
||||
override val gson: Gson = GsonBuilder()
|
||||
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
|
||||
.registerTypeAdapter(PokemonProperties::class.java, pokemonPropertiesShortAdapter)
|
||||
.registerTypeAdapter(ItemPredicate::class.java, LegacyItemConditionWrapperAdapter)
|
||||
.registerTypeAdapter(Requirement::class.java, CobblemonRequirementAdapter)
|
||||
.registerTypeAdapter(InteractionEffect::class.java, InteractionEffectAdapter)
|
||||
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
|
||||
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Biome::class.java).type, BiomeLikeConditionAdapter)
|
||||
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Block::class.java).type, BlockLikeConditionAdapter)
|
||||
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Item::class.java).type, ItemLikeConditionAdapter)
|
||||
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Structure::class.java).type, StructureLikeConditionAdapter)
|
||||
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Fluid::class.java).type, FluidLikeConditionAdapter)
|
||||
.registerTypeAdapter(IntRange::class.java, IntRangeAdapter)
|
||||
.registerTypeAdapterFactory(LowerCaseEnumTypeAdapterFactory())
|
||||
.setPrettyPrinting()
|
||||
.create()
|
||||
|
||||
val interactions = mutableListOf<PokemonInteractionSet>()
|
||||
|
||||
@@ -65,7 +69,7 @@ object PokemonInteractions : JsonDataRegistry<PokemonInteractionSet> {
|
||||
PokemonInteractionsSyncPacket(interactions).sendToPlayer(player)
|
||||
}
|
||||
|
||||
override fun reload(data: Map<ResourceLocation, PokemonInteractionSet>) {
|
||||
override fun reload(data: Map<ResourceLocation, PokemonInteractionSet>, registry: HolderLookup.Provider) {
|
||||
interactions.clear()
|
||||
val split = data.entries
|
||||
.partition {
|
||||
@@ -87,4 +91,4 @@ object PokemonInteractions : JsonDataRegistry<PokemonInteractionSet> {
|
||||
.flatMap { it.interactions }
|
||||
.firstOrNull(interactionCheck)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import com.cobblemon.mod.common.api.berry.Berries
|
||||
import com.cobblemon.mod.common.api.cooking.Seasonings
|
||||
import com.cobblemon.mod.common.api.data.DataProvider
|
||||
import com.cobblemon.mod.common.api.data.DataRegistry
|
||||
import com.cobblemon.mod.common.api.data.ServerJsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.dialogue.Dialogues
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents
|
||||
import com.cobblemon.mod.common.api.fishing.PokeRods
|
||||
@@ -51,6 +52,7 @@ import com.cobblemon.mod.common.pokemon.properties.PropertiesCompletionProvider
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.ifClient
|
||||
import com.cobblemon.mod.common.util.server
|
||||
import net.minecraft.core.HolderLookup
|
||||
import java.util.UUID
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
@@ -71,8 +73,8 @@ object CobblemonDataProvider : DataProvider {
|
||||
|
||||
// client is public only so we can use it cross-module. maybe a more elegant solution exists, but this works
|
||||
@ApiStatus.Internal
|
||||
val clientResourceReloader: PreparableReloadListener = SimpleResourceReloader(PackType.CLIENT_RESOURCES)
|
||||
private val serverResourceReloader: PreparableReloadListener = SimpleResourceReloader(PackType.SERVER_DATA)
|
||||
val clientResourceReloader: PreparableReloadListener = ClientResourceReloader()
|
||||
private val serverResourceReloader: PreparableReloadListener = ServerResourceReloader()
|
||||
|
||||
fun registerDefaults() {
|
||||
this.register(CobblemonScripts, reloadable = true)
|
||||
@@ -126,8 +128,10 @@ object CobblemonDataProvider : DataProvider {
|
||||
}
|
||||
|
||||
ifClient {
|
||||
Cobblemon.implementation.registerResourceReloader(cobblemonResource("client_resources"), PackType.CLIENT_RESOURCES, emptyList()) { ClientResourceReloader() }
|
||||
Cobblemon.implementation.registerResourceReloader(cobblemonResource("client_resources"), clientResourceReloader, PackType.CLIENT_RESOURCES, emptyList())
|
||||
}
|
||||
Cobblemon.implementation.registerResourceReloader(cobblemonResource("data_resources"), PackType.SERVER_DATA, emptyList()) { ServerResourceReloader(it) }
|
||||
Cobblemon.implementation.registerResourceReloader(cobblemonResource("data_resources"), serverResourceReloader, PackType.SERVER_DATA, emptyList())
|
||||
}
|
||||
|
||||
@@ -167,11 +171,22 @@ object CobblemonDataProvider : DataProvider {
|
||||
}
|
||||
}
|
||||
|
||||
private class SimpleResourceReloader(private val type: PackType) : ResourceManagerReloadListener {
|
||||
private class ClientResourceReloader : ResourceManagerReloadListener {
|
||||
override fun onResourceManagerReload(manager: ResourceManager) {
|
||||
registries.filter { it.type == PackType.CLIENT_RESOURCES }.forEach { it.reload(manager) }
|
||||
}
|
||||
}
|
||||
|
||||
private class ServerResourceReloader(private val registryAccess: HolderLookup.Provider) : ResourceManagerReloadListener {
|
||||
override fun onResourceManagerReload(manager: ResourceManager) {
|
||||
// Check for a server running, this is due to the create a world screen triggering datapack reloads, these are fine to happen as many times as needed as players may be in the process of adding their datapacks.
|
||||
val reloadAllowed = server()?.isReady != true
|
||||
registries.filter { it.type == this.type && (reloadAllowed || it in reloadableRegistries) }
|
||||
registries
|
||||
.filter { it.type == PackType.SERVER_DATA && (reloadAllowed || it in reloadableRegistries) }
|
||||
.filterIsInstance<ServerJsonDataRegistry<*>>()
|
||||
.forEach { it.reload(manager, registryAccess) }
|
||||
registries
|
||||
.filter { it.type == PackType.SERVER_DATA && (reloadAllowed || it in reloadableRegistries) }
|
||||
.forEach { it.reload(manager) }
|
||||
}
|
||||
}
|
||||
|
||||
+14
-7
@@ -9,6 +9,7 @@
|
||||
package com.cobblemon.mod.common.pokemon.evolution.adapters
|
||||
|
||||
import com.cobblemon.mod.common.util.adapters.CodecBackedAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.RegistryAccessResolver
|
||||
import com.google.gson.JsonDeserializationContext
|
||||
import com.google.gson.JsonDeserializer
|
||||
import com.google.gson.JsonElement
|
||||
@@ -19,6 +20,7 @@ import net.minecraft.advancements.critereon.ItemCustomDataPredicate
|
||||
import net.minecraft.advancements.critereon.ItemPredicate
|
||||
import net.minecraft.advancements.critereon.ItemSubPredicates
|
||||
import net.minecraft.advancements.critereon.NbtPredicate
|
||||
import net.minecraft.core.HolderLookup
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
@@ -26,13 +28,16 @@ import net.minecraft.tags.TagKey
|
||||
import java.lang.reflect.Type
|
||||
|
||||
// This is an ugly adapter because breaking changes are scary and people would ;(
|
||||
object LegacyItemConditionWrapperAdapter : JsonDeserializer<ItemPredicate>, JsonSerializer<ItemPredicate> {
|
||||
class LegacyItemConditionWrapperAdapter(val registryAccess: HolderLookup.Provider = RegistryAccessResolver.getAccess())
|
||||
: JsonDeserializer<ItemPredicate>, JsonSerializer<ItemPredicate> {
|
||||
|
||||
private const val TAG_PREFIX = "#"
|
||||
private const val LEGACY_ITEM = "item"
|
||||
private const val LEGACY_NBT = "nbt"
|
||||
companion object {
|
||||
private const val TAG_PREFIX = "#"
|
||||
private const val LEGACY_ITEM = "item"
|
||||
private const val LEGACY_NBT = "nbt"
|
||||
}
|
||||
|
||||
private val codecAdapter = CodecBackedAdapter(ItemPredicate.CODEC)
|
||||
private val codecAdapter = CodecBackedAdapter(ItemPredicate.CODEC, registryAccess)
|
||||
|
||||
override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): ItemPredicate {
|
||||
if (json.isJsonPrimitive) {
|
||||
@@ -64,7 +69,9 @@ object LegacyItemConditionWrapperAdapter : JsonDeserializer<ItemPredicate>, Json
|
||||
{ id ->
|
||||
if (isTag) {
|
||||
val tag = TagKey.create(Registries.ITEM, id)
|
||||
builder.of(tag)
|
||||
registryAccess.lookup(Registries.ITEM)
|
||||
.map { builder.of(tag) }
|
||||
.orElseGet { builder }
|
||||
} else {
|
||||
BuiltInRegistries.ITEM.getOptional(id)
|
||||
.map { builder.of(it) }
|
||||
@@ -75,4 +82,4 @@ object LegacyItemConditionWrapperAdapter : JsonDeserializer<ItemPredicate>, Json
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,16 +10,19 @@ package com.cobblemon.mod.common.util.adapters
|
||||
|
||||
import com.google.gson.*
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.JsonOps
|
||||
import net.minecraft.core.HolderLookup
|
||||
import net.minecraft.resources.RegistryOps
|
||||
import java.lang.reflect.Type
|
||||
|
||||
class CodecBackedAdapter<T>(val codec: Codec<T>) : JsonDeserializer<T>, JsonSerializer<T> {
|
||||
class CodecBackedAdapter<T>(val codec: Codec<T>, val registryAccess: HolderLookup.Provider = RegistryAccessResolver.getAccess()) : JsonDeserializer<T>, JsonSerializer<T> {
|
||||
|
||||
override fun deserialize(
|
||||
jElement: JsonElement,
|
||||
typeOfT: Type,
|
||||
context: JsonDeserializationContext
|
||||
): T {
|
||||
val ops = RegistryOpsProvider.getOpsWithDefaultFallback()
|
||||
val ops = RegistryOps.create(JsonOps.INSTANCE, registryAccess)
|
||||
val result = ops.withDecoder(codec).apply(jElement)
|
||||
return result.result().orElseThrow {
|
||||
IllegalStateException("Failed to deserialize $jElement: ${result.error().orElse(null)}")
|
||||
@@ -31,7 +34,7 @@ class CodecBackedAdapter<T>(val codec: Codec<T>) : JsonDeserializer<T>, JsonSeri
|
||||
typeOfSrc: Type?,
|
||||
context: JsonSerializationContext?
|
||||
): JsonElement {
|
||||
val ops = RegistryOpsProvider.getOpsWithDefaultFallback()
|
||||
val ops = RegistryOps.create(JsonOps.INSTANCE, registryAccess)
|
||||
val result = ops.withEncoder(codec).apply(src)
|
||||
return result.result().orElseThrow {
|
||||
IllegalStateException("Failed to serialize $src: ${result.error().orElse(null)}")
|
||||
|
||||
+13
-7
@@ -15,27 +15,33 @@ import com.google.gson.JsonElement
|
||||
import com.mojang.serialization.DynamicOps
|
||||
import com.mojang.serialization.JsonOps
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.core.RegistryAccess
|
||||
import net.minecraft.resources.RegistryOps
|
||||
|
||||
/**
|
||||
* Utility for obtaining RegistryOps with the correct client/server registry access.
|
||||
* Used when manually encoding/decoding registry-backed values (e.g., items, predicates).
|
||||
* Utility for getting RegistryAccess with the correct client/server registry access.
|
||||
* Used when as a fallback when manually encoding/decoding registry-backed values (e.g., items, predicates).
|
||||
*/
|
||||
object RegistryOpsProvider {
|
||||
fun getOpsWithDefaultFallback(): DynamicOps<JsonElement> {
|
||||
object RegistryAccessResolver {
|
||||
fun getAccess(): RegistryAccess {
|
||||
try {
|
||||
Cobblemon.implementation
|
||||
} catch (e: UninitializedPropertyAccessException) {
|
||||
return RegistryAccess.EMPTY
|
||||
}
|
||||
if (Cobblemon.implementation.environment() == Environment.CLIENT) {
|
||||
val minecraft = Minecraft.getInstance()
|
||||
if (minecraft != null && minecraft.level != null)
|
||||
return RegistryOps.create(JsonOps.INSTANCE, minecraft.level!!.registryAccess())
|
||||
return minecraft.level!!.registryAccess()
|
||||
}
|
||||
|
||||
|
||||
if (Cobblemon.implementation.environment() == Environment.SERVER) {
|
||||
val server = server()
|
||||
if (server != null)
|
||||
return RegistryOps.create(JsonOps.INSTANCE, server.registryAccess())
|
||||
return server.registryAccess()
|
||||
}
|
||||
|
||||
return JsonOps.INSTANCE
|
||||
return RegistryAccess.EMPTY
|
||||
}
|
||||
}
|
||||
@@ -59,7 +59,9 @@ import net.fabricmc.fabric.impl.resource.loader.ResourceManagerHelperImpl
|
||||
import net.fabricmc.loader.api.FabricLoader
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.commands.synchronization.ArgumentTypeInfo
|
||||
import net.minecraft.core.HolderLookup
|
||||
import net.minecraft.core.Registry
|
||||
import net.minecraft.core.RegistryAccess
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.network.syncher.EntityDataSerializers
|
||||
import net.minecraft.resources.ResourceKey
|
||||
@@ -345,8 +347,52 @@ object CobblemonFabric : CobblemonImplementation {
|
||||
}
|
||||
}
|
||||
|
||||
override fun registerResourceReloader(identifier: ResourceLocation, reloader: PreparableReloadListener, type: PackType, dependencies: Collection<ResourceLocation>) {
|
||||
ResourceManagerHelper.get(type).registerReloadListener(CobblemonReloadListener(identifier, reloader, dependencies))
|
||||
override fun registerResourceReloader(
|
||||
identifier: ResourceLocation,
|
||||
type: PackType,
|
||||
dependencies: Collection<ResourceLocation>,
|
||||
reloaderFactory: (HolderLookup.Provider) -> PreparableReloadListener
|
||||
) {
|
||||
if (type == PackType.SERVER_DATA) {
|
||||
val resourceLoader = ResourceManagerHelper.get(PackType.CLIENT_RESOURCES)
|
||||
resourceLoader.registerReloadListener(identifier, { object : IdentifiableResourceReloadListener {
|
||||
override fun reload(
|
||||
synchronizer: PreparableReloadListener.PreparationBarrier,
|
||||
manager: ResourceManager,
|
||||
prepareProfiler: ProfilerFiller,
|
||||
applyProfiler: ProfilerFiller,
|
||||
prepareExecutor: Executor,
|
||||
applyExecutor: Executor
|
||||
): CompletableFuture<Void> {
|
||||
return reloaderFactory.invoke(it).reload(synchronizer,
|
||||
manager, prepareProfiler, applyProfiler,
|
||||
prepareExecutor, applyExecutor)
|
||||
}
|
||||
|
||||
override fun getFabricId() = identifier
|
||||
|
||||
}})
|
||||
}
|
||||
else {
|
||||
val resourceLoader = ResourceManagerHelper.get(PackType.CLIENT_RESOURCES)
|
||||
resourceLoader.registerReloadListener(object : IdentifiableResourceReloadListener {
|
||||
override fun reload(
|
||||
synchronizer: PreparableReloadListener.PreparationBarrier,
|
||||
manager: ResourceManager,
|
||||
prepareProfiler: ProfilerFiller,
|
||||
applyProfiler: ProfilerFiller,
|
||||
prepareExecutor: Executor,
|
||||
applyExecutor: Executor
|
||||
): CompletableFuture<Void> {
|
||||
return reloaderFactory.invoke(RegistryAccess.EMPTY).reload(synchronizer,
|
||||
manager, prepareProfiler, applyProfiler,
|
||||
prepareExecutor, applyExecutor)
|
||||
}
|
||||
|
||||
override fun getFabricId() = identifier
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun server(): MinecraftServer? = if (this.environment() == Environment.CLIENT) Minecraft.getInstance().singleplayerServer else this.server
|
||||
|
||||
@@ -38,6 +38,8 @@ import com.cobblemon.mod.neoforge.worldgen.CobblemonBiomeModifiers
|
||||
import com.mojang.brigadier.arguments.ArgumentType
|
||||
import net.minecraft.commands.synchronization.ArgumentTypeInfo
|
||||
import net.minecraft.commands.synchronization.ArgumentTypeInfos
|
||||
import net.minecraft.core.HolderLookup
|
||||
import net.minecraft.core.RegistryAccess
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.resources.ResourceKey
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
@@ -92,11 +94,16 @@ import kotlin.reflect.KClass
|
||||
|
||||
@Mod(Cobblemon.MODID)
|
||||
class CobblemonNeoForge : CobblemonImplementation {
|
||||
private data class QueuedReloadListener(
|
||||
val identifier: ResourceLocation,
|
||||
val listener: (HolderLookup.Provider) -> PreparableReloadListener,
|
||||
val dependencies: Collection<ResourceLocation>
|
||||
)
|
||||
override val modAPI = ModAPI.NEOFORGE
|
||||
private val hasBeenSynced = hashSetOf<UUID>()
|
||||
|
||||
private val commandArgumentTypes = DeferredRegister.create(Registries.COMMAND_ARGUMENT_TYPE, Cobblemon.MODID)
|
||||
private val reloadableResources = arrayListOf<PreparableReloadListener>()
|
||||
private val reloadableResources = arrayListOf<QueuedReloadListener>()
|
||||
private val queuedWork = arrayListOf<() -> Unit>()
|
||||
|
||||
override val networkManager = CobblemonNeoForgeNetworkManager
|
||||
@@ -438,13 +445,21 @@ class CobblemonNeoForge : CobblemonImplementation {
|
||||
}
|
||||
}
|
||||
|
||||
override fun registerResourceReloader(identifier: ResourceLocation, reloader: PreparableReloadListener, type: PackType, dependencies: Collection<ResourceLocation>) {
|
||||
if (type == PackType.SERVER_DATA)
|
||||
this.reloadableResources += reloader
|
||||
override fun registerResourceReloader(
|
||||
identifier: ResourceLocation,
|
||||
type: PackType,
|
||||
dependencies: Collection<ResourceLocation>,
|
||||
reloaderFactory: (HolderLookup.Provider) -> PreparableReloadListener
|
||||
) {
|
||||
if (type == PackType.SERVER_DATA) {
|
||||
this.reloadableResources += QueuedReloadListener(identifier, reloaderFactory, dependencies)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onReload(e: AddReloadListenerEvent) {
|
||||
this.reloadableResources.forEach(e::addListener)
|
||||
this.reloadableResources.forEach { queued ->
|
||||
e.addListener(queued.listener.invoke(e.serverResources.registryLookup))
|
||||
}
|
||||
}
|
||||
|
||||
override fun server(): MinecraftServer? = ServerLifecycleHooks.getCurrentServer()
|
||||
|
||||
Reference in New Issue
Block a user