From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Thu, 20 Jun 2024 09:40:57 -0700 Subject: [PATCH] Tag Lifecycle Events == AT == public net/minecraft/tags/TagEntry id public net/minecraft/tags/TagEntry tag public net/minecraft/tags/TagEntry required diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProviderImpl.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProviderImpl.java index b11346e04bb16c3238f32deb87dbd680e261d4d2..996bac2fab8fb927d184fb62e043454e877727a6 100644 --- a/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProviderImpl.java +++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProviderImpl.java @@ -13,6 +13,8 @@ public final class LifecycleEventTypeProviderImpl implements LifecycleEventTypeP return (LifecycleEventTypeProviderImpl) LifecycleEventTypeProvider.provider(); } + private final PaperTagEventTypeProvider provider = new PaperTagEventTypeProvider(); + @Override public LifecycleEventType.Monitorable monitor(final String name, final Class ownerType) { return new MonitorableLifecycleEventType<>(name, ownerType); @@ -22,4 +24,9 @@ public final class LifecycleEventTypeProviderImpl implements LifecycleEventTypeP public LifecycleEventType.Prioritizable prioritized(final String name, final Class ownerType) { return new PrioritizableLifecycleEventType.Simple<>(name, ownerType); } + + @Override + public PaperTagEventTypeProvider tagProvider() { + return this.provider; + } } diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/PaperTagEventTypeProvider.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/PaperTagEventTypeProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..1cf4a3caa8d630e95eb569eef2cd577bba1a97a9 --- /dev/null +++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/PaperTagEventTypeProvider.java @@ -0,0 +1,24 @@ +package io.papermc.paper.plugin.lifecycle.event.types; + +import io.papermc.paper.plugin.bootstrap.BootstrapContext; +import io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent; +import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.tag.PaperTagListenerManager; +import io.papermc.paper.tag.PostFlattenTagRegistrar; +import io.papermc.paper.tag.PreFlattenTagRegistrar; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.framework.qual.DefaultQualifier; + +@DefaultQualifier(NonNull.class) +public class PaperTagEventTypeProvider implements TagEventTypeProvider { + + @Override + public PrioritizableLifecycleEventType.Simple>> preFlatten(final RegistryKey registryKey) { + return PaperTagListenerManager.INSTANCE.getPreFlattenType(registryKey); + } + + @Override + public PrioritizableLifecycleEventType.Simple>> postFlatten(final RegistryKey registryKey) { + return PaperTagListenerManager.INSTANCE.getPostFlattenType(registryKey); + } +} diff --git a/src/main/java/io/papermc/paper/tag/PaperPostFlattenTagRegistrar.java b/src/main/java/io/papermc/paper/tag/PaperPostFlattenTagRegistrar.java new file mode 100644 index 0000000000000000000000000000000000000000..2596586fd7e2546cd18cf6ac36a4eb5cf8d00359 --- /dev/null +++ b/src/main/java/io/papermc/paper/tag/PaperPostFlattenTagRegistrar.java @@ -0,0 +1,119 @@ +package io.papermc.paper.tag; + +import com.google.common.collect.Collections2; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import io.papermc.paper.adventure.PaperAdventure; +import io.papermc.paper.plugin.bootstrap.BootstrapContext; +import io.papermc.paper.plugin.lifecycle.event.registrar.PaperRegistrar; +import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.TypedKey; +import io.papermc.paper.registry.tag.TagKey; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Optional; +import java.util.function.Function; +import net.minecraft.resources.ResourceLocation; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.framework.qual.DefaultQualifier; + +@SuppressWarnings("BoundedWildcard") +@DefaultQualifier(NonNull.class) +public class PaperPostFlattenTagRegistrar implements PaperRegistrar, PostFlattenTagRegistrar { + + public final Map> tags; + private final Function> fromIdConverter; + private final Function toIdConverter; + private final RegistryKey registryKey; + + public PaperPostFlattenTagRegistrar( + final Map> tags, + final TagEventConfig config + ) { + this.tags = tags; + this.fromIdConverter = config.fromIdConverter(); + this.toIdConverter = config.toIdConverter(); + this.registryKey = config.apiRegistryKey(); + } + + @Override + public void setCurrentContext(final @Nullable BootstrapContext owner) { + } + + @Override + public RegistryKey registryKey() { + return this.registryKey; + } + + @Override + public Map, Collection>> getAllTags() { + final ImmutableMap.Builder, Collection>> tags = ImmutableMap.builderWithExpectedSize(this.tags.size()); + for (final Map.Entry> entry : this.tags.entrySet()) { + final TagKey key = TagKey.create(this.registryKey, CraftNamespacedKey.fromMinecraft(entry.getKey())); + tags.put(key, this.convert(entry.getValue())); + } + return tags.build(); + } + + private List> convert(final List nms) { + return Collections.unmodifiableList( + Lists.transform(nms, m -> this.convert(this.toIdConverter.apply(m))) + ); + } + + private TypedKey convert(final ResourceLocation location) { + return TypedKey.create(this.registryKey, CraftNamespacedKey.fromMinecraft(location)); + } + + private M convert(final TypedKey key) { + final Optional optional = this.fromIdConverter.apply(PaperAdventure.asVanilla(key.key())); + if (optional.isEmpty()) { + throw new IllegalArgumentException(key + " doesn't exist"); + } + return optional.get(); + } + + @Override + public boolean hasTag(final TagKey tagKey) { + return this.tags.containsKey(PaperAdventure.asVanilla(tagKey.key())); + } + + private List getNmsTag(final TagKey tagKey, final boolean create) { + final ResourceLocation vanillaKey = PaperAdventure.asVanilla(tagKey.key()); + List tag = this.tags.get(vanillaKey); + if (tag == null) { + if (create) { + tag = this.tags.computeIfAbsent(vanillaKey, k -> new ArrayList<>()); + } else { + throw new NoSuchElementException("Tag " + tagKey + " is not present"); + } + } + return tag; + } + + @Override + public Collection> getTag(final TagKey tagKey) { + return this.convert(this.getNmsTag(tagKey, false)); + } + + @Override + public void addToTag(final TagKey tagKey, final Collection> values) { + final List nmsTag = new ArrayList<>(this.getNmsTag(tagKey, true)); + for (final TypedKey key : values) { + nmsTag.add(this.convert(key)); + } + this.tags.put(PaperAdventure.asVanilla(tagKey.key()), nmsTag); + } + + @Override + public void setTag(final TagKey tagKey, final Collection> values) { + final List newList = List.copyOf(Collections2.transform(values, this::convert)); + this.tags.put(PaperAdventure.asVanilla(tagKey.key()), newList); + } +} diff --git a/src/main/java/io/papermc/paper/tag/PaperPreFlattenTagRegistrar.java b/src/main/java/io/papermc/paper/tag/PaperPreFlattenTagRegistrar.java new file mode 100644 index 0000000000000000000000000000000000000000..44111b55eaa6d1cc93e2c556b23bb5c97953caac --- /dev/null +++ b/src/main/java/io/papermc/paper/tag/PaperPreFlattenTagRegistrar.java @@ -0,0 +1,128 @@ +package io.papermc.paper.tag; + +import com.google.common.base.Preconditions; +import com.google.common.collect.Collections2; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import io.papermc.paper.adventure.PaperAdventure; +import io.papermc.paper.plugin.bootstrap.BootstrapContext; +import io.papermc.paper.plugin.lifecycle.event.registrar.PaperRegistrar; +import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.tag.TagKey; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagLoader; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.framework.qual.DefaultQualifier; + +@SuppressWarnings("BoundedWildcard") +@DefaultQualifier(NonNull.class) +public class PaperPreFlattenTagRegistrar implements PaperRegistrar, PreFlattenTagRegistrar { + + public final Map> tags; + private final RegistryKey registryKey; + + private @Nullable BootstrapContext owner; + + public PaperPreFlattenTagRegistrar( + final Map> tags, + final TagEventConfig config + ) { + this.tags = new HashMap<>(tags); + this.registryKey = config.apiRegistryKey(); + } + + @Override + public void setCurrentContext(final @Nullable BootstrapContext owner) { + this.owner = owner; + } + + @Override + public RegistryKey registryKey() { + return this.registryKey; + } + + @Override + public Map, Collection>> getAllTags() { + final ImmutableMap.Builder, Collection>> builder = ImmutableMap.builderWithExpectedSize(this.tags.size()); + for (final Map.Entry> entry : this.tags.entrySet()) { + final TagKey key = TagKey.create(this.registryKey, CraftNamespacedKey.fromMinecraft(entry.getKey())); + builder.put(key, convert(entry.getValue())); + } + return builder.build(); + } + + private static List> convert(final List nmsEntries) { + return Collections.unmodifiableList(Lists.transform(nmsEntries, PaperPreFlattenTagRegistrar::convert)); + } + + private static io.papermc.paper.tag.TagEntry convert(final TagLoader.EntryWithSource nmsEntry) { + return new TagEntryImpl<>(CraftNamespacedKey.fromMinecraft(nmsEntry.entry().id), nmsEntry.entry().tag, nmsEntry.entry().required); + } + + private TagLoader.EntryWithSource convert(final TagEntry entry) { + Preconditions.checkState(this.owner != null, "Owner is not set"); + final ResourceLocation vanilla = PaperAdventure.asVanilla(entry.key()); + final net.minecraft.tags.TagEntry nmsEntry; + if (entry.isTag()) { + if (entry.isRequired()) { + nmsEntry = net.minecraft.tags.TagEntry.tag(vanilla); + } else { + nmsEntry = net.minecraft.tags.TagEntry.optionalTag(vanilla); + } + } else { + if (entry.isRequired()) { + nmsEntry = net.minecraft.tags.TagEntry.element(vanilla); + } else { + nmsEntry = net.minecraft.tags.TagEntry.optionalElement(vanilla); + } + } + return new TagLoader.EntryWithSource(nmsEntry, this.owner.getPluginMeta().getDisplayName()); + } + + @Override + public boolean hasTag(final TagKey tagKey) { + return this.tags.containsKey(PaperAdventure.asVanilla(tagKey.key())); + } + + private List getNmsTag(final TagKey tagKey, boolean create) { + final ResourceLocation vanillaKey = PaperAdventure.asVanilla(tagKey.key()); + List tag = this.tags.get(vanillaKey); + if (tag == null) { + if (create) { + tag = this.tags.computeIfAbsent(vanillaKey, k -> new ArrayList<>()); + } else { + throw new NoSuchElementException("Tag " + tagKey + " is not present"); + } + } + return tag; + } + + @Override + public List> getTag(final TagKey tagKey) { + return convert(this.getNmsTag(tagKey, false)); + } + + @Override + public void addToTag(final TagKey tagKey, final Collection> entries) { + final List nmsTag = new ArrayList<>(this.getNmsTag(tagKey, true)); + for (final TagEntry tagEntry : entries) { + nmsTag.add(this.convert(tagEntry)); + } + this.tags.put(PaperAdventure.asVanilla(tagKey.key()), nmsTag); + } + + @Override + public void setTag(final TagKey tagKey, final Collection> entries) { + final List newList = List.copyOf(Collections2.transform(entries, this::convert)); + this.tags.put(PaperAdventure.asVanilla(tagKey.key()), newList); + } +} diff --git a/src/main/java/io/papermc/paper/tag/PaperTagListenerManager.java b/src/main/java/io/papermc/paper/tag/PaperTagListenerManager.java new file mode 100644 index 0000000000000000000000000000000000000000..e1ffb7f1df667dd9f92c00ff94b791feb1f14eed --- /dev/null +++ b/src/main/java/io/papermc/paper/tag/PaperTagListenerManager.java @@ -0,0 +1,105 @@ +package io.papermc.paper.tag; + +import io.papermc.paper.plugin.bootstrap.BootstrapContext; +import io.papermc.paper.plugin.lifecycle.event.LifecycleEventRunner; +import io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent; +import io.papermc.paper.plugin.lifecycle.event.types.AbstractLifecycleEventType; +import io.papermc.paper.plugin.lifecycle.event.types.PrioritizableLifecycleEventType; +import io.papermc.paper.registry.PaperRegistries; +import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.event.RegistryEventMap; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import net.minecraft.core.Holder; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagLoader; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.framework.qual.DefaultQualifier; + +@DefaultQualifier(NonNull.class) +public class PaperTagListenerManager { + + public static final String PRE_FLATTEN_EVENT_NAME = "pre-flatten"; + public static final String POST_FLATTEN_EVENT_NAME = "post-flatten"; + + public static final PaperTagListenerManager INSTANCE = new PaperTagListenerManager(); + + public final RegistryEventMap preFlatten = new RegistryEventMap(PRE_FLATTEN_EVENT_NAME); + public final RegistryEventMap postFlatten = new RegistryEventMap(POST_FLATTEN_EVENT_NAME); + + private PaperTagListenerManager() { + } + + public Map> firePreFlattenEvent( + final Map> initial, + final @Nullable TagEventConfig config + ) { + if (config == null || config.preFlatten() == null || !config.preFlatten().hasHandlers()) { + return initial; + } + final PaperPreFlattenTagRegistrar registrar = new PaperPreFlattenTagRegistrar<>(initial, config); + LifecycleEventRunner.INSTANCE.callReloadableRegistrarEvent( + config.preFlatten(), + registrar, + BootstrapContext.class, + config.cause() + ); + return Map.copyOf(registrar.tags); + } + + public Map> firePostFlattenEvent( + final Map> initial, + final @Nullable TagEventConfig config + ) { + if (config == null || config.postFlatten() == null || !config.postFlatten().hasHandlers()) { + return initial; + } + final PaperPostFlattenTagRegistrar registrar = new PaperPostFlattenTagRegistrar<>(initial, config); + LifecycleEventRunner.INSTANCE.callReloadableRegistrarEvent( + config.postFlatten(), + registrar, + BootstrapContext.class, + config.cause() + ); + return Map.copyOf(registrar.tags); + } + + public @Nullable TagEventConfig, B> createEventConfig(final Registry registry, final ReloadableRegistrarEvent.Cause cause) { + if (PaperRegistries.getEntry(registry.key()) == null) { + // TODO probably should be able to modify every registry + return null; + } + final RegistryKey registryKey = PaperRegistries.registryFromNms(registry.key()); + @Nullable AbstractLifecycleEventType>, ?> preFlatten = null; + if (this.preFlatten.hasHandlers(registryKey)) { + preFlatten = (AbstractLifecycleEventType>, ?>) this.preFlatten.>>getEventType(registryKey); + } + @Nullable AbstractLifecycleEventType>, ?> postFlatten = null; + if (this.postFlatten.hasHandlers(registryKey)) { + postFlatten = (AbstractLifecycleEventType>, ?>) this.postFlatten.>>getEventType(registryKey); + } + return new TagEventConfig<>( + preFlatten, + postFlatten, + cause, + registry::get, + h -> ((Holder.Reference) h).key().location(), + PaperRegistries.registryFromNms(registry.key()) + ); + } + + public PrioritizableLifecycleEventType.Simple>> getPreFlattenType(final RegistryKey registryKey) { + return this.preFlatten.getOrCreate(registryKey, (ignored, name) -> { + return new PrioritizableLifecycleEventType.Simple<>(name, BootstrapContext.class); + }); + } + + public PrioritizableLifecycleEventType.Simple>> getPostFlattenType(final RegistryKey registryKey) { + return this.postFlatten.getOrCreate(registryKey, (ignored, name) -> { + return new PrioritizableLifecycleEventType.Simple<>(name, BootstrapContext.class); + }); + } +} diff --git a/src/main/java/io/papermc/paper/tag/TagEventConfig.java b/src/main/java/io/papermc/paper/tag/TagEventConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..d6d4bfc6f45d646afeace422a038c670e10aaf80 --- /dev/null +++ b/src/main/java/io/papermc/paper/tag/TagEventConfig.java @@ -0,0 +1,23 @@ +package io.papermc.paper.tag; + +import io.papermc.paper.plugin.bootstrap.BootstrapContext; +import io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent; +import io.papermc.paper.plugin.lifecycle.event.types.AbstractLifecycleEventType; +import io.papermc.paper.registry.RegistryKey; +import java.util.Optional; +import java.util.function.Function; +import net.minecraft.resources.ResourceLocation; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.framework.qual.DefaultQualifier; + +@DefaultQualifier(NonNull.class) +public record TagEventConfig( + @Nullable AbstractLifecycleEventType>, ?> preFlatten, + @Nullable AbstractLifecycleEventType>, ?> postFlatten, + ReloadableRegistrarEvent.Cause cause, + Function> fromIdConverter, + Function toIdConverter, + RegistryKey apiRegistryKey +) { +} diff --git a/src/main/java/net/minecraft/resources/RegistryDataLoader.java b/src/main/java/net/minecraft/resources/RegistryDataLoader.java index 1aaa18b91a13cffac5f3d03fbae207f8ea91d3c7..21c90a4f6e84ef447fd4653feb3eb64b0ecb378c 100644 --- a/src/main/java/net/minecraft/resources/RegistryDataLoader.java +++ b/src/main/java/net/minecraft/resources/RegistryDataLoader.java @@ -276,7 +276,7 @@ public class RegistryDataLoader { } io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.runFreezeListeners(registry.key(), conversions); // Paper - run pre-freeze listeners - TagLoader.loadTagsForRegistry(resourceManager, registry); + TagLoader.loadTagsForRegistry(resourceManager, registry, io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.INITIAL); // Paper - tag lifecycle - add cause } static void loadContentsFromNetwork( diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 430ef84d5984819bbea0c406122d5c6cc04284d2..682417e20459ffd576e494e1a279c477589103ba 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -2230,7 +2230,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoopmap(resourcepackrepository::getPack).filter(Objects::nonNull).map(Pack::open).collect(ImmutableList.toImmutableList()); // CraftBukkit - decompile error // Paper - decompile error // todo: is this needed anymore? }, this).thenCompose((immutablelist) -> { MultiPackResourceManager resourcemanager = new MultiPackResourceManager(PackType.SERVER_DATA, immutablelist); - List> list = TagLoader.loadTagsForExistingRegistries(resourcemanager, this.registries.compositeAccess()); + List> list = TagLoader.loadTagsForExistingRegistries(resourcemanager, this.registries.compositeAccess(), io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.RELOAD); // Paper - tag lifecycle - add cause return ReloadableServerResources.loadResources(resourcemanager, this.registries, list, this.worldData.enabledFeatures(), this.isDedicatedServer() ? Commands.CommandSelection.DEDICATED : Commands.CommandSelection.INTEGRATED, this.getFunctionCompilationLevel(), this.executor, this).whenComplete((datapackresources, throwable) -> { if (throwable != null) { diff --git a/src/main/java/net/minecraft/server/ReloadableServerRegistries.java b/src/main/java/net/minecraft/server/ReloadableServerRegistries.java index f4d25d1aed5bcd3b8119ac7356a9cccc9d4ff54c..ceb5b58cca257e6f7e73f4236662e0f4ae7ae036 100644 --- a/src/main/java/net/minecraft/server/ReloadableServerRegistries.java +++ b/src/main/java/net/minecraft/server/ReloadableServerRegistries.java @@ -69,7 +69,7 @@ public class ReloadableServerRegistries { Map map = new HashMap<>(); SimpleJsonResourceReloadListener.scanDirectory(resourceManager, type.registryKey(), ops, type.codec(), map); map.forEach((id, value) -> io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.registerWithListeners(writableRegistry, ResourceKey.create(type.registryKey(), id), value, DEFAULT_REGISTRATION_INFO, conversions)); // Paper - register with listeners - TagLoader.loadTagsForRegistry(resourceManager, writableRegistry); + TagLoader.loadTagsForRegistry(resourceManager, writableRegistry, io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.RELOAD); // Paper - tag life cycle - reload return writableRegistry; }, prepareExecutor); } diff --git a/src/main/java/net/minecraft/server/ServerFunctionLibrary.java b/src/main/java/net/minecraft/server/ServerFunctionLibrary.java index 7128f01308b60163afa9355b79cb4129b630663d..fa5d4bfd52eb36e48fc811dbbdc1341204cf171d 100644 --- a/src/main/java/net/minecraft/server/ServerFunctionLibrary.java +++ b/src/main/java/net/minecraft/server/ServerFunctionLibrary.java @@ -113,7 +113,7 @@ public class ServerFunctionLibrary implements PreparableReloadListener { return null; }).join()); this.functions = builder.build(); - this.tags = this.tagsLoader.build((Map>)intermediate.getFirst()); + this.tags = this.tagsLoader.build((Map>)intermediate.getFirst(), null); // Paper - command function tags are not implemented yet }, applyExecutor ); diff --git a/src/main/java/net/minecraft/server/WorldLoader.java b/src/main/java/net/minecraft/server/WorldLoader.java index f21ccc50f2d507afe1e0af394321020cb5667e60..fad1cc1be3d1b84acacde8736129b970824f48b8 100644 --- a/src/main/java/net/minecraft/server/WorldLoader.java +++ b/src/main/java/net/minecraft/server/WorldLoader.java @@ -37,7 +37,7 @@ public class WorldLoader { CloseableResourceManager closeableResourceManager = pair.getSecond(); LayeredRegistryAccess layeredRegistryAccess = RegistryLayer.createRegistryAccess(); List> list = TagLoader.loadTagsForExistingRegistries( - closeableResourceManager, layeredRegistryAccess.getLayer(RegistryLayer.STATIC) + closeableResourceManager, layeredRegistryAccess.getLayer(RegistryLayer.STATIC), io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.INITIAL // Paper - tag lifecycle - add cause ); RegistryAccess.Frozen frozen = layeredRegistryAccess.getAccessForLoading(RegistryLayer.WORLDGEN); List> list2 = TagLoader.buildUpdatedLookups(frozen, list); diff --git a/src/main/java/net/minecraft/tags/TagLoader.java b/src/main/java/net/minecraft/tags/TagLoader.java index 8d742805f7b44b832b532d4ee6d313c0d7659e1d..a81b2b47b909b3858046d2b152d31b2cfc5d5fe4 100644 --- a/src/main/java/net/minecraft/tags/TagLoader.java +++ b/src/main/java/net/minecraft/tags/TagLoader.java @@ -86,7 +86,10 @@ public class TagLoader { return list.isEmpty() ? Either.right(List.copyOf(sequencedSet)) : Either.left(list); } - public Map> build(Map> tags) { + // Paper start - fire tag registrar events + public Map> build(Map> tags, @Nullable io.papermc.paper.tag.TagEventConfig eventConfig) { + tags = io.papermc.paper.tag.PaperTagListenerManager.INSTANCE.firePreFlattenEvent(tags, eventConfig); + // Paper end - fire tag registrar event final Map> map = new HashMap<>(); TagEntry.Lookup lookup = new TagEntry.Lookup() { @Nullable @@ -114,7 +117,7 @@ public class TagLoader { ) .ifRight(values -> map.put(id, (List)values)) ); - return map; + return io.papermc.paper.tag.PaperTagListenerManager.INSTANCE.firePostFlattenEvent(map, eventConfig); // Paper - fire tag registrar events } public static void loadTagsFromNetwork(TagNetworkSerialization.NetworkPayload tags, WritableRegistry registry) { @@ -122,28 +125,38 @@ public class TagLoader { } public static List> loadTagsForExistingRegistries(ResourceManager resourceManager, RegistryAccess registryManager) { + // Paper start - tag lifecycle - add cause + return loadTagsForExistingRegistries(resourceManager, registryManager, io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.INITIAL); + } + public static List> loadTagsForExistingRegistries(ResourceManager resourceManager, RegistryAccess registryManager, io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause cause) { + // Paper end - tag lifecycle - add cause return registryManager.registries() - .map(registry -> loadPendingTags(resourceManager, registry.value())) + .map(registry -> loadPendingTags(resourceManager, registry.value(), cause)) // Paper - tag lifecycle - add cause .flatMap(Optional::stream) .collect(Collectors.toUnmodifiableList()); } public static void loadTagsForRegistry(ResourceManager resourceManager, WritableRegistry registry) { + // Paper start - tag lifecycle - add registrar event cause + loadTagsForRegistry(resourceManager, registry, io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.INITIAL); + } + public static void loadTagsForRegistry(ResourceManager resourceManager, WritableRegistry registry, io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause cause) { + // Paper end - tag lifecycle - add registrar event cause ResourceKey> resourceKey = registry.key(); TagLoader> tagLoader = new TagLoader<>(TagLoader.ElementLookup.fromWritableRegistry(registry), Registries.tagsDirPath(resourceKey)); - tagLoader.build(tagLoader.load(resourceManager)).forEach((id, entries) -> registry.bindTag(TagKey.create(resourceKey, id), (List>)entries)); + tagLoader.build(tagLoader.load(resourceManager), io.papermc.paper.tag.PaperTagListenerManager.INSTANCE.createEventConfig(registry, cause)).forEach((id, entries) -> registry.bindTag(TagKey.create(resourceKey, id), (List>)entries)); // Paper - tag lifecycle - add registrar event cause } private static Map, List>> wrapTags(ResourceKey> registryRef, Map>> tags) { return tags.entrySet().stream().collect(Collectors.toUnmodifiableMap(entry -> TagKey.create(registryRef, entry.getKey()), Entry::getValue)); } - private static Optional> loadPendingTags(ResourceManager resourceManager, Registry registry) { + private static Optional> loadPendingTags(ResourceManager resourceManager, Registry registry, io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause cause) { // Paper - add registrar event cause ResourceKey> resourceKey = registry.key(); TagLoader> tagLoader = new TagLoader<>( (TagLoader.ElementLookup>)TagLoader.ElementLookup.fromFrozenRegistry(registry), Registries.tagsDirPath(resourceKey) ); - TagLoader.LoadResult loadResult = new TagLoader.LoadResult<>(resourceKey, wrapTags(registry.key(), tagLoader.build(tagLoader.load(resourceManager)))); + TagLoader.LoadResult loadResult = new TagLoader.LoadResult<>(resourceKey, wrapTags(registry.key(), tagLoader.build(tagLoader.load(resourceManager), io.papermc.paper.tag.PaperTagListenerManager.INSTANCE.createEventConfig(registry, cause)))); // Paper - add registrar event cause return loadResult.tags().isEmpty() ? Optional.empty() : Optional.of(registry.prepareTagReload(loadResult)); }