1.21.6 dev

Co-authored-by: Bjarne Koll <git@lynxplay.dev>
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
Co-authored-by: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
Co-authored-by: Noah van der Aa <ndvdaa@gmail.com>
Co-authored-by: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
This commit is contained in:
Bjarne Koll
2025-05-28 13:23:32 +02:00
committed by Nassim Jahnke
parent 39203a65e0
commit a24f9b204c
788 changed files with 41006 additions and 6324 deletions

View File

@ -1,6 +1,5 @@
package io.papermc.generator;
import com.google.common.util.concurrent.MoreExecutors;
import com.mojang.logging.LogUtils;
import io.papermc.generator.rewriter.registration.PaperPatternSourceSetRewriter;
import io.papermc.generator.rewriter.registration.PatternSourceSetRewriter;
@ -48,7 +47,7 @@ public class Main implements Callable<Integer> {
@CommandLine.Option(names = {"--sourceset"}, required = true)
Path sourceSet;
@CommandLine.Option(names = {"-cp", "--classpath"}, split = ":", required = true)
@CommandLine.Option(names = {"-cp", "--classpath"}, split = "[;:]", required = true)
Set<Path> classpath;
@CommandLine.Option(names = {"--rewrite"})
@ -84,11 +83,11 @@ public class Main implements Callable<Integer> {
resourceManager,
layers,
pendingTags,
FeatureFlags.VANILLA_SET,
FeatureFlags.REGISTRY.allFlags(),
Commands.CommandSelection.DEDICATED,
0,
MoreExecutors.directExecutor(),
MoreExecutors.directExecutor()
Commands.LEVEL_GAMEMASTERS,
Runnable::run,
Runnable::run
).whenComplete((result, ex) -> {
if (ex != null) {
resourceManager.close();

View File

@ -6,6 +6,7 @@ import io.papermc.generator.rewriter.registration.PatternSourceSetRewriter;
import io.papermc.generator.rewriter.types.Types;
import io.papermc.generator.rewriter.types.registry.EnumRegistryRewriter;
import io.papermc.generator.rewriter.types.registry.FeatureFlagRewriter;
import io.papermc.generator.rewriter.types.registry.PaperFeatureFlagMapping;
import io.papermc.generator.rewriter.types.registry.RegistryFieldRewriter;
import io.papermc.generator.rewriter.types.registry.RegistryTagRewriter;
import io.papermc.generator.rewriter.types.registry.TagRewriter;
@ -17,7 +18,6 @@ import io.papermc.generator.rewriter.types.simple.EntityTypeRewriter;
import io.papermc.generator.rewriter.types.simple.MapPaletteRewriter;
import io.papermc.generator.rewriter.types.simple.MaterialRewriter;
import io.papermc.generator.rewriter.types.simple.MemoryKeyRewriter;
import io.papermc.generator.rewriter.types.registry.PaperFeatureFlagMapping;
import io.papermc.generator.rewriter.types.simple.StatisticRewriter;
import io.papermc.generator.rewriter.types.simple.trial.VillagerProfessionRewriter;
import io.papermc.generator.types.goal.MobGoalNames;
@ -25,14 +25,15 @@ import io.papermc.generator.utils.Formatting;
import io.papermc.paper.datacomponent.item.consumable.ItemUseAnimation;
import io.papermc.typewriter.preset.EnumCloneRewriter;
import io.papermc.typewriter.preset.model.EnumValue;
import java.util.Map;
import java.util.function.Consumer;
import io.papermc.typewriter.replace.SearchMetadata;
import io.papermc.typewriter.replace.SearchReplaceRewriter;
import java.util.Map;
import java.util.function.Consumer;
import javax.lang.model.SourceVersion;
import net.kyori.adventure.text.format.NamedTextColor;
import net.minecraft.core.Holder;
import net.minecraft.core.registries.Registries;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.item.Rarity;
import org.bukkit.Art;
@ -43,12 +44,14 @@ import org.bukkit.JukeboxSong;
import org.bukkit.Material;
import org.bukkit.MusicInstrument;
import org.bukkit.Sound;
import org.bukkit.SoundCategory;
import org.bukkit.Statistic;
import org.bukkit.Tag;
import org.bukkit.block.Biome;
import org.bukkit.block.BlockType;
import org.bukkit.block.banner.PatternType;
import org.bukkit.damage.DamageType;
import org.bukkit.entity.Armadillo;
import org.bukkit.entity.Boat;
import org.bukkit.entity.Cat;
import org.bukkit.entity.Chicken;
@ -67,7 +70,6 @@ import org.bukkit.entity.memory.MemoryKey;
import org.bukkit.generator.structure.Structure;
import org.bukkit.generator.structure.StructureType;
import org.bukkit.inventory.ItemRarity;
import org.bukkit.inventory.ItemType;
import org.bukkit.inventory.meta.trim.TrimMaterial;
import org.bukkit.inventory.meta.trim.TrimPattern;
import org.bukkit.inventory.recipe.CookingBookCategory;
@ -124,6 +126,8 @@ public final class Rewriters {
.register("BoatStatus", Boat.Status.class, new EnumCloneRewriter<>(net.minecraft.world.entity.vehicle.Boat.Status.class))
.register("FoxType", Fox.Type.class, new EnumCloneRewriter<>(net.minecraft.world.entity.animal.Fox.Variant.class))
.register("SalmonVariant", Salmon.Variant.class, new EnumCloneRewriter<>(net.minecraft.world.entity.animal.Salmon.Variant.class))
.register("ArmadilloState", Armadillo.State.class, new EnumCloneRewriter<>(net.minecraft.world.entity.animal.armadillo.Armadillo.ArmadilloState.class))
.register("SoundCategory", SoundCategory.class, new EnumCloneRewriter<>(SoundSource.class))
.register("ItemUseAnimation", ItemUseAnimation.class, new EnumCloneRewriter<>(net.minecraft.world.item.ItemUseAnimation.class))
.register("ItemRarity", ItemRarity.class, new EnumCloneRewriter<>(Rarity.class) {
@Override
@ -181,7 +185,6 @@ public final class Rewriters {
.register("CowVariant", Cow.Variant.class, new RegistryFieldRewriter<>(Registries.COW_VARIANT, "getVariant"))
.register("PigVariant", Pig.Variant.class, new RegistryFieldRewriter<>(Registries.PIG_VARIANT, "getVariant"))
.register("MemoryKey", MemoryKey.class, new MemoryKeyRewriter())
// .register("DataComponentTypes", DataComponentTypes.class, new DataComponentTypesRewriter()) - disable for now
// .register("ItemType", ItemType.class, new ItemTypeRewriter()) - disable for now, lynx want the generic type
.register("BlockType", BlockType.class, new BlockTypeRewriter())
.register("FeatureFlag", FeatureFlag.class, new FeatureFlagRewriter())
@ -203,11 +206,11 @@ public final class Rewriters {
holder("CraftPotionUtil#extendable", new CraftPotionUtilRewriter("long"))
))
.register("PaperFeatureFlagProviderImpl#FLAGS", Types.PAPER_FEATURE_FLAG_PROVIDER_IMPL, new PaperFeatureFlagMapping())
.register("MobGoalHelper#bukkitMap", Types.MOB_GOAL_HELPER, new SearchReplaceRewriter() {
.register("MobGoalHelper#BUKKIT_BRIDGE", Types.MOB_GOAL_HELPER, new SearchReplaceRewriter() {
@Override
protected void insert(SearchMetadata metadata, StringBuilder builder) {
for (Map.Entry<Class<? extends Mob>, Class<? extends org.bukkit.entity.Mob>> entry : MobGoalNames.bukkitMap.entrySet()) {
builder.append(metadata.indent()).append("bukkitMap.put(%s.class, %s.class);".formatted(
for (Map.Entry<Class<? extends Mob>, Class<? extends org.bukkit.entity.Mob>> entry : MobGoalNames.BUKKIT_BRIDGE.entrySet()) {
builder.append(metadata.indent()).append("map.put(%s.class, %s.class);".formatted(
entry.getKey().getCanonicalName(), this.importCollector.getShortName(entry.getValue())
));
builder.append('\n');

View File

@ -11,7 +11,11 @@ import io.papermc.paper.registry.data.DamageTypeRegistryEntry;
import io.papermc.paper.registry.data.EnchantmentRegistryEntry;
import io.papermc.paper.registry.data.FrogVariantRegistryEntry;
import io.papermc.paper.registry.data.GameEventRegistryEntry;
import io.papermc.paper.registry.data.JukeboxSongRegistryEntry;
import io.papermc.paper.registry.data.PaintingVariantRegistryEntry;
import io.papermc.paper.registry.data.PigVariantRegistryEntry;
import io.papermc.paper.registry.data.SoundEventRegistryEntry;
import io.papermc.paper.registry.data.WolfVariantRegistryEntry;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
@ -24,8 +28,6 @@ import java.util.Objects;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import io.papermc.paper.registry.data.PigVariantRegistryEntry;
import io.papermc.paper.registry.data.WolfVariantRegistryEntry;
import net.minecraft.core.Registry;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.particles.ParticleTypes;
@ -146,7 +148,7 @@ public final class RegistryEntries {
);
public static final List<RegistryEntry<?>> BUILT_IN = List.of(
entry(Registries.GAME_EVENT, net.minecraft.world.level.gameevent.GameEvent.class, GameEvent.class).apiRegistryBuilder(GameEventRegistryEntry.Builder.class, "PaperGameEventRegistryEntry.PaperBuilder"),
entry(Registries.GAME_EVENT, net.minecraft.world.level.gameevent.GameEvent.class, GameEvent.class).writableApiRegistryBuilder(GameEventRegistryEntry.Builder.class, "PaperGameEventRegistryEntry.PaperBuilder"),
entry(Registries.STRUCTURE_TYPE, net.minecraft.world.level.levelgen.structure.StructureType.class, StructureType.class),
entry(Registries.MOB_EFFECT, MobEffects.class, PotionEffectType.class),
entry(Registries.BLOCK, Blocks.class, BlockType.class),
@ -157,7 +159,7 @@ public final class RegistryEntries {
entry(Registries.MENU, net.minecraft.world.inventory.MenuType.class, MenuType.class),
entry(Registries.ATTRIBUTE, Attributes.class, Attribute.class).serializationUpdater("ATTRIBUTE_RENAME"),
entry(Registries.FLUID, Fluids.class, Fluid.class),
entry(Registries.SOUND_EVENT, SoundEvents.class, Sound.class).allowDirect().apiRegistryField("SOUNDS"),
entry(Registries.SOUND_EVENT, SoundEvents.class, Sound.class).allowDirect().apiRegistryField("SOUNDS").apiRegistryBuilder(SoundEventRegistryEntry.Builder.class, "PaperSoundEventRegistryEntry.PaperBuilder", RegistryEntry.RegistryModificationApiSupport.NONE),
entry(Registries.DATA_COMPONENT_TYPE, DataComponents.class, DataComponentType.class, "Paper").preload(DataComponentTypes.class).apiAccessName("of")
);
@ -166,19 +168,19 @@ public final class RegistryEntries {
entry(Registries.STRUCTURE, BuiltinStructures.class, Structure.class).delayed(),
entry(Registries.TRIM_MATERIAL, TrimMaterials.class, TrimMaterial.class).allowDirect().delayed(),
entry(Registries.TRIM_PATTERN, TrimPatterns.class, TrimPattern.class).allowDirect().delayed(),
entry(Registries.DAMAGE_TYPE, DamageTypes.class, DamageType.class).apiRegistryBuilder(DamageTypeRegistryEntry.Builder.class, "PaperDamageTypeRegistryEntry.PaperBuilder").delayed(),
entry(Registries.WOLF_VARIANT, WolfVariants.class, Wolf.Variant.class).apiRegistryBuilder(WolfVariantRegistryEntry.Builder.class, "PaperWolfVariantRegistryEntry.PaperBuilder").delayed(),
entry(Registries.DAMAGE_TYPE, DamageTypes.class, DamageType.class).writableApiRegistryBuilder(DamageTypeRegistryEntry.Builder.class, "PaperDamageTypeRegistryEntry.PaperBuilder").delayed(),
entry(Registries.WOLF_VARIANT, WolfVariants.class, Wolf.Variant.class).writableApiRegistryBuilder(WolfVariantRegistryEntry.Builder.class, "PaperWolfVariantRegistryEntry.PaperBuilder").delayed(),
entry(Registries.WOLF_SOUND_VARIANT, WolfSoundVariants.class, Wolf.SoundVariant.class),
entry(Registries.ENCHANTMENT, Enchantments.class, Enchantment.class).apiRegistryBuilder(EnchantmentRegistryEntry.Builder.class, "PaperEnchantmentRegistryEntry.PaperBuilder").serializationUpdater("ENCHANTMENT_RENAME").delayed(),
entry(Registries.JUKEBOX_SONG, JukeboxSongs.class, JukeboxSong.class).delayed(),
entry(Registries.BANNER_PATTERN, BannerPatterns.class, PatternType.class).allowDirect().apiRegistryBuilder(BannerPatternRegistryEntry.Builder.class, "PaperBannerPatternRegistryEntry.PaperBuilder").delayed(),
entry(Registries.PAINTING_VARIANT, PaintingVariants.class, Art.class).allowDirect().apiRegistryBuilder(PaintingVariantRegistryEntry.Builder.class, "PaperPaintingVariantRegistryEntry.PaperBuilder").apiRegistryField("ART").delayed(),
entry(Registries.ENCHANTMENT, Enchantments.class, Enchantment.class).writableApiRegistryBuilder(EnchantmentRegistryEntry.Builder.class, "PaperEnchantmentRegistryEntry.PaperBuilder").serializationUpdater("ENCHANTMENT_RENAME").delayed(),
entry(Registries.JUKEBOX_SONG, JukeboxSongs.class, JukeboxSong.class).writableApiRegistryBuilder(JukeboxSongRegistryEntry.Builder.class, "PaperJukeboxSongRegistryEntry.PaperBuilder").delayed(),
entry(Registries.BANNER_PATTERN, BannerPatterns.class, PatternType.class).allowDirect().writableApiRegistryBuilder(BannerPatternRegistryEntry.Builder.class, "PaperBannerPatternRegistryEntry.PaperBuilder").delayed(),
entry(Registries.PAINTING_VARIANT, PaintingVariants.class, Art.class).writableApiRegistryBuilder(PaintingVariantRegistryEntry.Builder.class, "PaperPaintingVariantRegistryEntry.PaperBuilder").apiRegistryField("ART").delayed(),
entry(Registries.INSTRUMENT, Instruments.class, MusicInstrument.class).allowDirect().delayed(),
entry(Registries.CAT_VARIANT, CatVariants.class, Cat.Type.class).apiRegistryBuilder(CatTypeRegistryEntry.Builder.class, "PaperCatTypeRegistryEntry.PaperBuilder").delayed(),
entry(Registries.FROG_VARIANT, FrogVariants.class, Frog.Variant.class).apiRegistryBuilder(FrogVariantRegistryEntry.Builder.class, "PaperFrogVariantRegistryEntry.PaperBuilder").delayed(),
entry(Registries.CHICKEN_VARIANT, ChickenVariants.class, Chicken.Variant.class).apiRegistryBuilder(ChickenVariantRegistryEntry.Builder.class, "PaperChickenVariantRegistryEntry.PaperBuilder"),
entry(Registries.COW_VARIANT, CowVariants.class, Cow.Variant.class).apiRegistryBuilder(CowVariantRegistryEntry.Builder.class, "PaperCowVariantRegistryEntry.PaperBuilder"),
entry(Registries.PIG_VARIANT, PigVariants.class, Pig.Variant.class).apiRegistryBuilder(PigVariantRegistryEntry.Builder.class, "PaperPigVariantRegistryEntry.PaperBuilder")
entry(Registries.CAT_VARIANT, CatVariants.class, Cat.Type.class).writableApiRegistryBuilder(CatTypeRegistryEntry.Builder.class, "PaperCatTypeRegistryEntry.PaperBuilder").delayed(),
entry(Registries.FROG_VARIANT, FrogVariants.class, Frog.Variant.class).writableApiRegistryBuilder(FrogVariantRegistryEntry.Builder.class, "PaperFrogVariantRegistryEntry.PaperBuilder").delayed(),
entry(Registries.CHICKEN_VARIANT, ChickenVariants.class, Chicken.Variant.class).writableApiRegistryBuilder(ChickenVariantRegistryEntry.Builder.class, "PaperChickenVariantRegistryEntry.PaperBuilder"),
entry(Registries.COW_VARIANT, CowVariants.class, Cow.Variant.class).writableApiRegistryBuilder(CowVariantRegistryEntry.Builder.class, "PaperCowVariantRegistryEntry.PaperBuilder"),
entry(Registries.PIG_VARIANT, PigVariants.class, Pig.Variant.class).writableApiRegistryBuilder(PigVariantRegistryEntry.Builder.class, "PaperPigVariantRegistryEntry.PaperBuilder")
);
public static final List<RegistryEntry<?>> API_ONLY = List.of(

View File

@ -33,6 +33,7 @@ public final class RegistryEntry<T> {
private Class<?> preloadClass;
private final String implClass;
private @Nullable RegistryModificationApiSupport modificationApiSupport;
private @Nullable Class<?> apiRegistryBuilder;
private @Nullable String apiRegistryBuilderImpl;
@ -127,9 +128,18 @@ public final class RegistryEntry<T> {
return this.apiRegistryBuilderImpl;
}
public RegistryEntry<T> apiRegistryBuilder(Class<?> builderClass, String builderImplClass) {
public @Nullable RegistryModificationApiSupport modificationApiSupport() {
return this.modificationApiSupport;
}
public RegistryEntry<T> writableApiRegistryBuilder(Class<?> builderClass, String builderImplClass) {
return this.apiRegistryBuilder(builderClass, builderImplClass, RegistryModificationApiSupport.WRITABLE);
}
public RegistryEntry<T> apiRegistryBuilder(Class<?> builderClass, String builderImplClass, RegistryModificationApiSupport modificationApiSupport) {
this.apiRegistryBuilder = builderClass;
this.apiRegistryBuilderImpl = builderImplClass;
this.modificationApiSupport = modificationApiSupport;
return this;
}
@ -151,7 +161,7 @@ public final class RegistryEntry<T> {
}
public boolean allowCustomKeys() {
return this.apiRegistryBuilder != null || RegistryEntries.DATA_DRIVEN.contains(this);
return (this.apiRegistryBuilder != null && this.modificationApiSupport.canAdd()) || RegistryEntries.DATA_DRIVEN.contains(this);
}
private <TO> Map<ResourceKey<T>, TO> getFields(Map<ResourceKey<T>, TO> map, Function<Field, @Nullable TO> transform) {
@ -211,4 +221,15 @@ public final class RegistryEntry<T> {
"implClass=" + this.implClass + ", " +
']';
}
public enum RegistryModificationApiSupport {
NONE,
ADDABLE,
MODIFIABLE,
WRITABLE;
public boolean canAdd() {
return this != MODIFIABLE && this != NONE;
}
}
}

View File

@ -12,12 +12,10 @@ import io.papermc.typewriter.replace.CompositeRewriter;
import io.papermc.typewriter.replace.ReplaceOptions;
import io.papermc.typewriter.replace.ReplaceOptionsLike;
import io.papermc.typewriter.replace.SearchReplaceRewriter;
import java.io.File;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;
import net.minecraft.SharedConstants;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.VisibleForTesting;
@ -48,7 +46,7 @@ public class PaperPatternSourceSetRewriter extends SourceSetRewriterImpl<Pattern
COMMENT_MARKER_FORMAT.formatted("Start", pattern),
COMMENT_MARKER_FORMAT.formatted("End", pattern)
)
.generatedComment(Annotations.annotationStyle(GeneratedFrom.class) + " " + SharedConstants.getCurrentVersion().getId())
.generatedComment(Annotations.annotationStyle(GeneratedFrom.class) + " " + SharedConstants.getCurrentVersion().id())
.targetClass(targetClass);
}

View File

@ -20,6 +20,8 @@ public final class Types {
public static final ClassNamed PAPER_REGISTRIES = ClassNamed.of("io.papermc.paper.registry", "PaperRegistries");
public static final ClassNamed REGISTRY_MODIFICATION_API_SUPPORT = ClassNamed.of("io.papermc.paper.registry.entry", "RegistryEntryMeta", "RegistryModificationApiSupport");
public static final ClassNamed PAPER_FEATURE_FLAG_PROVIDER_IMPL = ClassNamed.of("io.papermc.paper.world.flag", "PaperFeatureFlagProviderImpl");
public static final ClassNamed PAPER_SIMPLE_REGISTRY = ClassNamed.of("io.papermc.paper.registry", "PaperSimpleRegistry");

View File

@ -43,7 +43,7 @@ public class EnumRegistryRewriter<T> extends EnumRewriter<Holder.Reference<T>> {
@Override
protected Iterable<Holder.Reference<T>> getValues() {
return this.registry.get().listElements().sorted(Formatting.alphabeticKeyOrder(reference -> reference.key().location().getPath()))::iterator;
return this.registry.get().listElements().sorted(Formatting.HOLDER_ORDER)::iterator;
}
@Override

View File

@ -18,6 +18,7 @@ import org.jspecify.annotations.NullMarked;
@NullMarked
public class PaperRegistriesRewriter extends SearchReplaceRewriter {
private void appendEntry(String indent, StringBuilder builder, RegistryEntry<?> entry, boolean canBeDelayed, boolean apiOnly) {
builder.append(indent);
builder.append("start");
@ -52,9 +53,18 @@ public class PaperRegistriesRewriter extends SearchReplaceRewriter {
builder.append(".serializationUpdater(").append(Types.FIELD_RENAME.simpleName()).append('.').append(entry.fieldRename()).append(")");
}
if (entry.apiRegistryBuilderImpl() != null) {
builder.append(".writable(");
if (entry.apiRegistryBuilderImpl() != null && entry.modificationApiSupport() != null) {
switch (entry.modificationApiSupport()) {
case WRITABLE -> builder.append(".writable(");
case ADDABLE -> builder.append(".addable(");
case MODIFIABLE -> builder.append(".modifiable(");
case NONE -> builder.append(".create(");
}
builder.append(this.importCollector.getShortName(this.classNamedView.findFirst(entry.apiRegistryBuilderImpl()).resolve(this.classResolver))).append("::new");
if (entry.modificationApiSupport() == RegistryEntry.RegistryModificationApiSupport.NONE) {
builder.append(", ");
builder.append(Types.REGISTRY_MODIFICATION_API_SUPPORT.dottedNestedName()).append(".NONE");
}
builder.append(')');
} else {
builder.append(".build()");

View File

@ -1,6 +1,7 @@
package io.papermc.generator.rewriter.types.registry;
import io.papermc.generator.registry.RegistryEntries;
import io.papermc.generator.registry.RegistryEntry;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.event.RegistryEventProvider;
import io.papermc.typewriter.replace.SearchMetadata;
@ -17,7 +18,7 @@ public class RegistryEventsRewriter extends SearchReplaceRewriter {
@Override
public void insert(SearchMetadata metadata, StringBuilder builder) {
RegistryEntries.forEach(entry -> {
if (entry.apiRegistryBuilder() != null) {
if (entry.apiRegistryBuilder() != null && entry.modificationApiSupport() != RegistryEntry.RegistryModificationApiSupport.NONE) {
builder.append(metadata.indent());
builder.append("%s %s %s ".formatted(PUBLIC, STATIC, FINAL));
builder.append(RegistryEventProvider.class.getSimpleName());

View File

@ -71,7 +71,7 @@ public class RegistryFieldRewriter<T> extends SearchReplaceRewriter {
boolean isInterface = Objects.requireNonNull(this.fieldClass.knownClass()).isInterface();
Registry<T> registry = Main.REGISTRY_ACCESS.lookupOrThrow(this.registryKey);
this.experimentalKeys = Suppliers.memoize(() -> ExperimentalCollector.collectDataDrivenElementIds(registry));
Iterator<Holder.Reference<T>> referenceIterator = registry.listElements().filter(this::canPrintField).sorted(Formatting.alphabeticKeyOrder(reference -> reference.key().location().getPath())).iterator();
Iterator<Holder.Reference<T>> referenceIterator = registry.listElements().filter(this::canPrintField).sorted(Formatting.HOLDER_ORDER).iterator();
while (referenceIterator.hasNext()) {
Holder.Reference<T> reference = referenceIterator.next();

View File

@ -57,7 +57,7 @@ public class RegistryTagRewriter<T> extends SearchReplaceRewriter {
@Override
protected void insert(SearchMetadata metadata, StringBuilder builder) {
Registry<T> registry = Main.REGISTRY_ACCESS.lookupOrThrow(this.registryKey);
Iterator<? extends TagKey<T>> keyIterator = registry.listTagIds().sorted(Formatting.alphabeticKeyOrder(reference -> reference.location().getPath())).iterator();
Iterator<? extends TagKey<T>> keyIterator = registry.listTagIds().sorted(Formatting.TAG_ORDER).iterator();
while (keyIterator.hasNext()) {
TagKey<T> tagKey = keyIterator.next();

View File

@ -62,7 +62,7 @@ public class TagRewriter extends SearchReplaceRewriter {
builder.append('\n');
builder.append('\n');
Iterator<? extends TagKey<?>> keyIterator = registry.listTagIds().sorted(Formatting.alphabeticKeyOrder(tagKey -> tagKey.location().getPath())).iterator();
Iterator<? extends TagKey<?>> keyIterator = registry.listTagIds().sorted(Formatting.TAG_ORDER).iterator();
while (keyIterator.hasNext()) {
TagKey<?> tagKey = keyIterator.next();

View File

@ -44,6 +44,7 @@ public class EntityTypeRewriter extends EnumRegistryRewriter<EntityType<?>> {
.put("LeashKnot", "LeashHitch")
.put("LightningBolt", "LightningStrike")
.put("Tnt", "TNTPrimed")
.put("Minecart", "RideableMinecart")
.put("ChestMinecart", "StorageMinecart")
.put("CommandBlockMinecart", "CommandMinecart")
.put("TntMinecart", "ExplosiveMinecart")
@ -164,7 +165,7 @@ public class EntityTypeRewriter extends EnumRegistryRewriter<EntityType<?>> {
private String toBukkitClass(Holder.Reference<EntityType<?>> reference) {
Class<? extends Entity> internalClass = ENTITY_GENERIC_TYPES.get(reference.key());
if (Mob.class.isAssignableFrom(internalClass)) {
return this.importCollector.getShortName(MobGoalNames.bukkitMap.get((Class<? extends Mob>) internalClass));
return this.importCollector.getShortName(MobGoalNames.BUKKIT_BRIDGE.get((Class<? extends Mob>) internalClass));
}
String className = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, reference.key().location().getPath()); // use the key instead of the internal class name since name match a bit more

View File

@ -6,7 +6,6 @@ import io.papermc.generator.utils.Formatting;
import io.papermc.typewriter.preset.model.EnumValue;
import java.util.Optional;
import net.minecraft.core.Holder;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.item.Item;
@ -30,7 +29,7 @@ public class MaterialRewriter {
@Override
protected Iterable<Holder.Reference<Block>> getValues() {
return BuiltInRegistries.BLOCK.listElements().filter(reference -> !reference.value().equals(net.minecraft.world.level.block.Blocks.AIR))
.sorted(Formatting.alphabeticKeyOrder(reference -> reference.key().location().getPath()))::iterator;
.sorted(Formatting.HOLDER_ORDER)::iterator;
}
@Override
@ -86,7 +85,7 @@ public class MaterialRewriter {
@Override
protected Iterable<Holder.Reference<Item>> getValues() {
return BuiltInRegistries.ITEM.listElements().filter(reference -> BuiltInRegistries.BLOCK.getOptional(reference.key().location()).isEmpty() || reference.value().equals(net.minecraft.world.item.Items.AIR))
.sorted(Formatting.alphabeticKeyOrder(reference -> reference.key().location().getPath()))::iterator;
.sorted(Formatting.HOLDER_ORDER)::iterator;
}
@Override

View File

@ -131,7 +131,7 @@ public class StatisticRewriter {
@Override
protected Iterable<Holder.Reference<StatType<?>>> getValues() {
return BuiltInRegistries.STAT_TYPE.listElements().filter(reference -> reference.value() != Stats.CUSTOM)
.sorted(Formatting.alphabeticKeyOrder(reference -> reference.key().location().getPath()))::iterator;
.sorted(Formatting.HOLDER_ORDER)::iterator;
}
@Override
@ -157,7 +157,7 @@ public class StatisticRewriter {
@Override
protected Iterable<Holder.Reference<StatType<?>>> getValues() {
return BuiltInRegistries.STAT_TYPE.listElements().filter(reference -> reference.value() != Stats.CUSTOM)
.sorted(Formatting.alphabeticKeyOrder(reference -> reference.key().location().getPath()))::iterator;
.sorted(Formatting.HOLDER_ORDER)::iterator;
}
@Override

View File

@ -1,261 +0,0 @@
package io.papermc.generator.rewriter.types.simple.trial;
import com.google.gson.internal.Primitives;
import com.mojang.serialization.Codec;
import io.papermc.generator.registry.RegistryEntries;
import io.papermc.generator.rewriter.types.registry.RegistryFieldRewriter;
import io.papermc.generator.utils.ClassHelper;
import io.papermc.paper.datacomponent.item.BlockItemDataProperties;
import io.papermc.paper.datacomponent.item.ItemAdventurePredicate;
import io.papermc.paper.datacomponent.item.ItemArmorTrim;
import io.papermc.typewriter.ClassNamed;
import io.papermc.typewriter.parser.Lexer;
import io.papermc.typewriter.parser.sequence.SequenceTokens;
import io.papermc.typewriter.parser.sequence.TokenTaskBuilder;
import io.papermc.typewriter.parser.token.CharSequenceBlockToken;
import io.papermc.typewriter.parser.token.CharSequenceToken;
import io.papermc.typewriter.parser.token.TokenType;
import io.papermc.typewriter.replace.SearchMetadata;
import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import net.kyori.adventure.key.Key;
import net.minecraft.core.Holder;
import net.minecraft.core.component.DataComponentType;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.ExtraCodecs;
import net.minecraft.util.Unit;
import net.minecraft.world.item.AdventureModePredicate;
import net.minecraft.world.item.Instrument;
import net.minecraft.world.item.Rarity;
import net.minecraft.world.item.component.BlockItemStateProperties;
import net.minecraft.world.item.component.FireworkExplosion;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.equipment.trim.ArmorTrim;
import org.bukkit.FireworkEffect;
import org.bukkit.MusicInstrument;
import org.bukkit.inventory.ItemRarity;
import org.checkerframework.checker.index.qual.NonNegative;
import org.checkerframework.checker.index.qual.Positive;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.jspecify.annotations.Nullable;
import static io.papermc.generator.utils.Formatting.quoted;
public class DataComponentTypesRewriter extends RegistryFieldRewriter<DataComponentType<?>> {
public DataComponentTypesRewriter() {
super(Registries.DATA_COMPONENT_TYPE, null);
}
private static final Set<TokenType> FORMAT_TOKENS = EnumSet.of(
TokenType.COMMENT,
TokenType.SINGLE_COMMENT
);
private @MonotonicNonNull Map<String, CharSequenceBlockToken> javadocsPerConstant;
private Map<String, CharSequenceBlockToken> parseConstantJavadocs(String content) {
Map<String, CharSequenceBlockToken> map = new HashMap<>();
Lexer lex = new Lexer(content.toCharArray());
lex.checkMarkdownDocComments = !this.sourcesMetadata.canSkipMarkdownDocComments();
SequenceTokens.wrap(lex, FORMAT_TOKENS)
.group(action -> {
ProtoConstant constant = new ProtoConstant();
action
.map(TokenType.JAVADOC, token -> {
constant.javadocs(((CharSequenceBlockToken) token));
}, TokenTaskBuilder::asOptional)
.skip(TokenType.PUBLIC).skip(TokenType.STATIC).skip(TokenType.FINAL)
.skipQualifiedName(Predicate.isEqual(TokenType.JAVADOC))
.skipClosure(TokenType.LT, TokenType.GT, true, TokenTaskBuilder::asOptional) // skip generic
.map(TokenType.IDENTIFIER, token -> {
constant.name(((CharSequenceToken) token).value());
})
.skip(TokenType.IDENTIFIER)
.skipClosure(TokenType.LPAREN, TokenType.RPAREN, true)
.map(TokenType.SECO, $ -> {
if (constant.isComplete()) {
map.put(constant.name(), constant.javadocs());
}
});
}, TokenTaskBuilder::asRepeatable)
.executeOrThrow();
return map;
}
private static final Set<DataComponentType<?>> UNSUPPORTED_TYPES = Set.of(
DataComponents.CUSTOM_DATA,
DataComponents.CREATIVE_SLOT_LOCK,
DataComponents.DEBUG_STICK_STATE,
DataComponents.ENTITY_DATA,
DataComponents.BUCKET_ENTITY_DATA,
DataComponents.BLOCK_ENTITY_DATA,
DataComponents.BEES,
DataComponents.LOCK
);
private static final Map<ResourceKey<DataComponentType<?>>, Type> COMPONENT_GENERIC_TYPES = RegistryEntries.byRegistryKey(Registries.DATA_COMPONENT_TYPE).getFields(field -> {
if (field.getGenericType() instanceof ParameterizedType complexType && complexType.getActualTypeArguments().length == 1) {
return complexType.getActualTypeArguments()[0];
}
return null;
});
private static final Map<Class<?>, Class<?>> API_BRIDGE = Map.of(
Component.class, net.kyori.adventure.text.Component.class,
ResourceLocation.class, Key.class,
Instrument.class, MusicInstrument.class,
FireworkExplosion.class, FireworkEffect.class,
Rarity.class, ItemRarity.class,
ArmorTrim.class, ItemArmorTrim.class,
// renames
BlockItemStateProperties.class, BlockItemDataProperties.class,
AdventureModePredicate.class, ItemAdventurePredicate.class
);
@Deprecated
private static final Map<String, String> FIELD_RENAMES = Map.of(
"BLOCK_STATE", "BLOCK_DATA"
);
@Override
protected void insert(SearchMetadata metadata, StringBuilder builder) {
this.javadocsPerConstant = parseConstantJavadocs(metadata.replacedContent());
super.insert(metadata, builder);
}
@Override
protected boolean canPrintField(Holder.Reference<DataComponentType<?>> reference) {
return !UNSUPPORTED_TYPES.contains(reference.value());
}
@Override
protected void rewriteJavadocs(Holder.Reference<DataComponentType<?>> reference, String replacedContent, String indent, StringBuilder builder) {
String constantName = this.rewriteFieldName(reference);
if (this.javadocsPerConstant.containsKey(constantName)) {
CharSequenceBlockToken token = this.javadocsPerConstant.get(constantName);
builder.append(indent).append(replacedContent, token.pos(), token.endPos()).append('\n');
}
}
private boolean isValued;
private Class<?> handleParameterizedType(Type type) {
if (type instanceof ParameterizedType complexType) {
Type[] args = complexType.getActualTypeArguments();
if (args.length != 1) {
throw new UnsupportedOperationException("Unsupported type " + complexType);
}
Class<?> baseClass = ClassHelper.eraseType(complexType);
if (baseClass == Holder.class) {
return ClassHelper.eraseType(args[0]);
}
if (baseClass == ResourceKey.class) {
Class<?> componentClass = ClassHelper.eraseType(args[0]);
if (componentClass == Recipe.class) {
return ResourceLocation.class; // special case recipe registry is not really a thing
}
}
}
throw new UnsupportedOperationException("Unsupported type " + type);
}
@Override
protected String rewriteFieldType(Holder.Reference<DataComponentType<?>> reference) {
Type componentType = COMPONENT_GENERIC_TYPES.get(reference.key());
this.isValued = componentType != Unit.class;
if (this.isValued) {
Class<?> componentClass = null;
UnaryOperator<String> tryToWrap = UnaryOperator.identity();
if (!reference.value().isTransient()) {
final Class<? extends Annotation> annotation = getEquivalentAnnotation(reference.value().codecOrThrow());
if (annotation != null) {
tryToWrap = value -> "@%s %s".formatted(this.importCollector.getShortName(annotation), value);
}
}
if (componentType instanceof Class<?> clazz) {
componentClass = clazz;
} else if (componentType instanceof ParameterizedType complexType) {
Type[] args = complexType.getActualTypeArguments();
if (args.length != 1) {
throw new UnsupportedOperationException("Unsupported type " + componentType);
}
Class<?> baseClass = ClassHelper.eraseType(complexType);
if (baseClass == List.class) {
tryToWrap = value -> "%s<%s>".formatted(this.importCollector.getShortName(List.class), value);
componentClass = this.handleParameterizedType(args[0]);
} else {
componentClass = this.handleParameterizedType(complexType);
}
}
if (componentClass == null) {
throw new UnsupportedOperationException("Unsupported type " + componentType);
}
Class<?> apiComponentClass = null;
if (Primitives.isWrapperType(componentClass)) {
apiComponentClass = componentClass;
} else if (API_BRIDGE.containsKey(componentClass)) {
apiComponentClass = API_BRIDGE.get(componentClass);
}
final ClassNamed finalClass;
if (apiComponentClass == null) {
finalClass = this.classNamedView.tryFindFirst(io.papermc.typewriter.util.ClassHelper.retrieveFullNestedName(componentClass)).orElse(null);
} else {
finalClass = new ClassNamed(apiComponentClass);
}
return "%s.%s<%s>".formatted(
io.papermc.paper.datacomponent.DataComponentType.class.getSimpleName(),
io.papermc.paper.datacomponent.DataComponentType.Valued.class.getSimpleName(),
tryToWrap.apply(Optional.ofNullable(finalClass).map(this.importCollector::getShortName).orElse(componentClass.getSimpleName()))
);
} else {
return "%s.%s".formatted(
io.papermc.paper.datacomponent.DataComponentType.class.getSimpleName(),
io.papermc.paper.datacomponent.DataComponentType.NonValued.class.getSimpleName()
);
}
}
private @Nullable Class<? extends Annotation> getEquivalentAnnotation(Codec<?> codec) {
Class<? extends Annotation> annotation = null; // int range maybe?
if (codec == ExtraCodecs.POSITIVE_INT || codec == ExtraCodecs.POSITIVE_FLOAT) {
annotation = Positive.class;
} else if (codec == ExtraCodecs.NON_NEGATIVE_INT || codec == ExtraCodecs.NON_NEGATIVE_FLOAT) {
annotation = NonNegative.class;
}
return annotation;
}
@Override
protected String rewriteFieldName(Holder.Reference<DataComponentType<?>> reference) {
String keyedName = super.rewriteFieldName(reference);
return FIELD_RENAMES.getOrDefault(keyedName, keyedName);
}
@Override
protected String rewriteFieldValue(Holder.Reference<DataComponentType<?>> reference) {
return "%s(%s)".formatted(this.isValued ? "valued" : "unvalued", quoted(reference.key().location().getPath()));
}
}

View File

@ -0,0 +1,93 @@
package io.papermc.generator.rewriter.types.simple.trial;
import io.papermc.typewriter.parser.Lexer;
import io.papermc.typewriter.parser.sequence.SequenceTokens;
import io.papermc.typewriter.parser.sequence.TokenTaskBuilder;
import io.papermc.typewriter.parser.token.CharSequenceBlockToken;
import io.papermc.typewriter.parser.token.CharSequenceToken;
import io.papermc.typewriter.parser.token.TokenType;
import io.papermc.typewriter.preset.EnumCloneRewriter;
import io.papermc.typewriter.preset.model.EnumValue;
import io.papermc.typewriter.replace.SearchMetadata;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import net.minecraft.world.entity.Pose;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
public class PoseRewriter extends EnumCloneRewriter<Pose> {
public PoseRewriter() {
super(Pose.class);
}
private static final Set<TokenType> FORMAT_TOKENS = EnumSet.of(
TokenType.COMMENT,
TokenType.SINGLE_COMMENT
);
private static final Set<TokenType> END_VALUE_MARKERS = EnumSet.of(
TokenType.CO,
TokenType.SECO
);
private @MonotonicNonNull Map<String, CharSequenceBlockToken> javadocsPerConstant;
private Map<String, CharSequenceBlockToken> parseConstantJavadocs(String content) {
Map<String, CharSequenceBlockToken> map = new HashMap<>();
Lexer lex = new Lexer(content.toCharArray());
lex.checkMarkdownDocComments = !this.sourcesMetadata.canSkipMarkdownDocComments();
SequenceTokens.wrap(lex, FORMAT_TOKENS)
.group(action -> {
ProtoConstant constant = new ProtoConstant();
action
.map(TokenType.JAVADOC, token -> { // /** */
constant.javadocs(((CharSequenceBlockToken) token));
}, TokenTaskBuilder::asOptional)
.map(TokenType.IDENTIFIER, token -> { // <name>
constant.name(((CharSequenceToken) token).value());
})
.skipClosure(TokenType.LPAREN, TokenType.RPAREN, true, TokenTaskBuilder::asOptional) // (*)?
.skipClosure(TokenType.LSCOPE, TokenType.RSCOPE, true, TokenTaskBuilder::asOptional) // {*}?
.map(END_VALUE_MARKERS::contains, $ -> { // ;|,
// this part will fail for the last entry for enum without end (,;)
if (constant.isComplete()) {
map.put(constant.name(), constant.javadocs());
}
});
}, TokenTaskBuilder::asRepeatable)
.executeOrThrow();
return map;
}
private @MonotonicNonNull SearchMetadata metadata;
private static final Map<String, String> RENAMES = Map.of(
Pose.CROUCHING.name(), "SNEAKING"
);
@Override
protected void insert(SearchMetadata metadata, StringBuilder builder) {
this.javadocsPerConstant = parseConstantJavadocs(metadata.replacedContent());
this.metadata = metadata;
super.insert(metadata, builder);
}
@Override
protected EnumValue.Builder rewriteEnumValue(Pose item) {
return super.rewriteEnumValue(item).rename(name -> RENAMES.getOrDefault(name, name));
}
@Override
protected void appendEnumValue(Pose item, StringBuilder builder, String indent, boolean reachEnd) {
String constantName = RENAMES.getOrDefault(item.name(), item.name());
if (this.javadocsPerConstant.containsKey(constantName)) {
CharSequenceBlockToken token = this.javadocsPerConstant.get(constantName);
builder.append(indent).append(this.metadata.replacedContent(), token.pos(), token.endPos()).append('\n');
}
super.appendEnumValue(item, builder, indent, reachEnd);
}
}

View File

@ -12,7 +12,6 @@ import io.papermc.typewriter.parser.StringReader;
import io.papermc.typewriter.replace.CommentMarker;
import io.papermc.typewriter.replace.SearchReplaceRewriter;
import io.papermc.typewriter.replace.SearchReplaceRewriterBase;
import net.minecraft.SharedConstants;
import java.io.IOException;
import java.io.LineNumberReader;
import java.nio.charset.StandardCharsets;
@ -21,6 +20,7 @@ import java.nio.file.Path;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import net.minecraft.SharedConstants;
import static io.papermc.typewriter.replace.CommentMarker.EMPTY_MARKER;
@ -30,7 +30,7 @@ public class ScanOldGeneratedSourceCode {
static {
Main.bootStrap(false);
CURRENT_VERSION = SharedConstants.getCurrentVersion().getId();
CURRENT_VERSION = SharedConstants.getCurrentVersion().id();
}
public static void main(String[] args) throws IOException {

View File

@ -6,9 +6,11 @@ import io.papermc.generator.utils.Formatting;
import it.unimi.dsi.fastutil.Pair;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.properties.Property;
import org.jspecify.annotations.NullMarked;
@ -16,11 +18,11 @@ import org.jspecify.annotations.NullMarked;
@NullMarked
public abstract class DataPropertyWriterBase implements DataPropertyMaker {
protected final Collection<? extends Property<?>> properties;
protected final Stream<? extends Property<?>> properties;
protected final Class<? extends Block> blockClass;
protected DataPropertyWriterBase(Collection<? extends Property<?>> properties, Class<? extends Block> blockClass) {
this.properties = properties;
this.properties = properties.stream().sorted(Comparator.comparing(Property::getName));
this.blockClass = blockClass;
}
@ -31,12 +33,12 @@ public abstract class DataPropertyWriterBase implements DataPropertyMaker {
code.add("$T.of(\n", List.class);
}
code.indent();
Iterator<? extends Property<?>> it = this.properties.iterator();
while (it.hasNext()) {
Property<?> property = it.next();
Iterator<? extends Property<?>> properties = this.properties.iterator();
while (properties.hasNext()) {
Property<?> property = properties.next();
Pair<Class<?>, String> fieldName = PropertyWriter.referenceField(this.blockClass, property, fields);
code.add("$T.$L", fieldName.left(), fieldName.right());
if (it.hasNext()) {
if (properties.hasNext()) {
code.add(",");
}
code.add("\n");
@ -47,13 +49,13 @@ public abstract class DataPropertyWriterBase implements DataPropertyMaker {
protected void createSyntheticMap(CodeBlock.Builder code, Class<?> indexClass, Map<Property<?>, Field> fields) {
// assume indexClass is an enum with its values matching the property names
code.add("$T.of(\n", Map.class).indent();
Iterator<? extends Property<?>> it = this.properties.iterator();
while (it.hasNext()) {
Property<?> property = it.next();
Iterator<? extends Property<?>> properties = this.properties.iterator();
while (properties.hasNext()) {
Property<?> property = properties.next();
String name = Formatting.formatKeyAsField(property.getName());
Pair<Class<?>, String> fieldName = PropertyWriter.referenceField(this.blockClass, property, fields);
code.add("$T.$L, $T.$L", indexClass, name, fieldName.left(), fieldName.right());
if (it.hasNext()) {
if (properties.hasNext()) {
code.add(",");
}
code.add("\n");

View File

@ -5,201 +5,359 @@ import com.destroystokyo.paper.entity.ai.GoalKey;
import com.google.common.base.CaseFormat;
import io.papermc.generator.utils.Formatting;
import io.papermc.paper.entity.SchoolableFish;
import io.papermc.typewriter.util.ClassHelper;
import it.unimi.dsi.fastutil.ints.Int2BooleanFunction;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import net.minecraft.Util;
import net.minecraft.world.entity.ai.goal.Goal;
import net.minecraft.world.entity.monster.RangedAttackMob;
import org.apache.commons.lang3.math.NumberUtils;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.*;
import org.bukkit.entity.AbstractCow;
import org.bukkit.entity.AbstractHorse;
import org.bukkit.entity.AbstractSkeleton;
import org.bukkit.entity.AbstractVillager;
import org.bukkit.entity.Ageable;
import org.bukkit.entity.Allay;
import org.bukkit.entity.Ambient;
import org.bukkit.entity.Animals;
import org.bukkit.entity.Armadillo;
import org.bukkit.entity.Axolotl;
import org.bukkit.entity.Bat;
import org.bukkit.entity.Bee;
import org.bukkit.entity.Blaze;
import org.bukkit.entity.Bogged;
import org.bukkit.entity.Breeze;
import org.bukkit.entity.Cat;
import org.bukkit.entity.CaveSpider;
import org.bukkit.entity.ChestedHorse;
import org.bukkit.entity.Chicken;
import org.bukkit.entity.Cod;
import org.bukkit.entity.Cow;
import org.bukkit.entity.Creaking;
import org.bukkit.entity.Creature;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.Dolphin;
import org.bukkit.entity.Donkey;
import org.bukkit.entity.Drowned;
import org.bukkit.entity.ElderGuardian;
import org.bukkit.entity.EnderDragon;
import org.bukkit.entity.Enderman;
import org.bukkit.entity.Endermite;
import org.bukkit.entity.Evoker;
import org.bukkit.entity.Fish;
import org.bukkit.entity.Fox;
import org.bukkit.entity.Frog;
import org.bukkit.entity.Ghast;
import org.bukkit.entity.Giant;
import org.bukkit.entity.GlowSquid;
import org.bukkit.entity.Goat;
import org.bukkit.entity.Golem;
import org.bukkit.entity.Guardian;
import org.bukkit.entity.HappyGhast;
import org.bukkit.entity.Hoglin;
import org.bukkit.entity.Horse;
import org.bukkit.entity.Husk;
import org.bukkit.entity.Illager;
import org.bukkit.entity.Illusioner;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.Llama;
import org.bukkit.entity.MagmaCube;
import org.bukkit.entity.Mob;
import org.bukkit.entity.Monster;
import org.bukkit.entity.Mule;
import org.bukkit.entity.MushroomCow;
import org.bukkit.entity.Ocelot;
import org.bukkit.entity.Panda;
import org.bukkit.entity.Parrot;
import org.bukkit.entity.Phantom;
import org.bukkit.entity.Pig;
import org.bukkit.entity.PigZombie;
import org.bukkit.entity.Piglin;
import org.bukkit.entity.PiglinAbstract;
import org.bukkit.entity.PiglinBrute;
import org.bukkit.entity.Pillager;
import org.bukkit.entity.PolarBear;
import org.bukkit.entity.PufferFish;
import org.bukkit.entity.Rabbit;
import org.bukkit.entity.Raider;
import org.bukkit.entity.Ravager;
import org.bukkit.entity.Salmon;
import org.bukkit.entity.Sheep;
import org.bukkit.entity.Shulker;
import org.bukkit.entity.Silverfish;
import org.bukkit.entity.Skeleton;
import org.bukkit.entity.SkeletonHorse;
import org.bukkit.entity.Slime;
import org.bukkit.entity.Sniffer;
import org.bukkit.entity.Snowman;
import org.bukkit.entity.Spellcaster;
import org.bukkit.entity.Spider;
import org.bukkit.entity.Squid;
import org.bukkit.entity.Stray;
import org.bukkit.entity.Strider;
import org.bukkit.entity.Tadpole;
import org.bukkit.entity.Tameable;
import org.bukkit.entity.TraderLlama;
import org.bukkit.entity.TropicalFish;
import org.bukkit.entity.Turtle;
import org.bukkit.entity.Vex;
import org.bukkit.entity.Villager;
import org.bukkit.entity.Vindicator;
import org.bukkit.entity.WanderingTrader;
import org.bukkit.entity.Warden;
import org.bukkit.entity.WaterMob;
import org.bukkit.entity.Witch;
import org.bukkit.entity.Wither;
import org.bukkit.entity.WitherSkeleton;
import org.bukkit.entity.Wolf;
import org.bukkit.entity.Zoglin;
import org.bukkit.entity.Zombie;
import org.bukkit.entity.ZombieHorse;
import org.bukkit.entity.ZombieVillager;
import org.jspecify.annotations.NullMarked;
@NullMarked
public final class MobGoalNames { // todo sync with MobGoalHelper ideally this should not be duplicated
private static final Map<Class<? extends Goal>, Class<? extends Mob>> entityClassCache = new HashMap<>();
public static final Map<Class<? extends net.minecraft.world.entity.Mob>, Class<? extends Mob>> bukkitMap = new LinkedHashMap<>();
static {
private static final Map<Class<? extends Goal>, Class<? extends Mob>> GENERIC_TYPE_CACHE = new HashMap<>();
public static final Map<Class<? extends net.minecraft.world.entity.Mob>, Class<? extends Mob>> BUKKIT_BRIDGE = Util.make(new LinkedHashMap<>(), map -> {
//<editor-fold defaultstate="collapsed" desc="bukkitMap Entities">
bukkitMap.put(net.minecraft.world.entity.Mob.class, Mob.class);
bukkitMap.put(net.minecraft.world.entity.AgeableMob.class, Ageable.class);
bukkitMap.put(net.minecraft.world.entity.ambient.AmbientCreature.class, Ambient.class);
bukkitMap.put(net.minecraft.world.entity.animal.Animal.class, Animals.class);
bukkitMap.put(net.minecraft.world.entity.ambient.Bat.class, Bat.class);
bukkitMap.put(net.minecraft.world.entity.animal.Bee.class, Bee.class);
bukkitMap.put(net.minecraft.world.entity.monster.Blaze.class, Blaze.class);
bukkitMap.put(net.minecraft.world.entity.animal.Cat.class, Cat.class);
bukkitMap.put(net.minecraft.world.entity.monster.CaveSpider.class, CaveSpider.class);
bukkitMap.put(net.minecraft.world.entity.animal.Chicken.class, Chicken.class);
bukkitMap.put(net.minecraft.world.entity.animal.Cod.class, Cod.class);
bukkitMap.put(net.minecraft.world.entity.animal.Cow.class, Cow.class);
bukkitMap.put(net.minecraft.world.entity.PathfinderMob.class, Creature.class);
bukkitMap.put(net.minecraft.world.entity.monster.Creeper.class, Creeper.class);
bukkitMap.put(net.minecraft.world.entity.animal.Dolphin.class, Dolphin.class);
bukkitMap.put(net.minecraft.world.entity.monster.Drowned.class, Drowned.class);
bukkitMap.put(net.minecraft.world.entity.boss.enderdragon.EnderDragon.class, EnderDragon.class);
bukkitMap.put(net.minecraft.world.entity.monster.EnderMan.class, Enderman.class);
bukkitMap.put(net.minecraft.world.entity.monster.Endermite.class, Endermite.class);
bukkitMap.put(net.minecraft.world.entity.monster.Evoker.class, Evoker.class);
bukkitMap.put(net.minecraft.world.entity.animal.AbstractFish.class, Fish.class);
bukkitMap.put(net.minecraft.world.entity.animal.AbstractSchoolingFish.class, SchoolableFish.class);
bukkitMap.put(net.minecraft.world.entity.FlyingMob.class, Flying.class);
bukkitMap.put(net.minecraft.world.entity.animal.Fox.class, Fox.class);
bukkitMap.put(net.minecraft.world.entity.monster.Ghast.class, Ghast.class);
bukkitMap.put(net.minecraft.world.entity.monster.Giant.class, Giant.class);
bukkitMap.put(net.minecraft.world.entity.animal.AbstractGolem.class, Golem.class);
bukkitMap.put(net.minecraft.world.entity.monster.Guardian.class, Guardian.class);
bukkitMap.put(net.minecraft.world.entity.monster.ElderGuardian.class, ElderGuardian.class);
bukkitMap.put(net.minecraft.world.entity.animal.horse.Horse.class, Horse.class);
bukkitMap.put(net.minecraft.world.entity.animal.horse.AbstractHorse.class, AbstractHorse.class);
bukkitMap.put(net.minecraft.world.entity.animal.horse.AbstractChestedHorse.class, ChestedHorse.class);
bukkitMap.put(net.minecraft.world.entity.animal.horse.Donkey.class, Donkey.class);
bukkitMap.put(net.minecraft.world.entity.animal.horse.Mule.class, Mule.class);
bukkitMap.put(net.minecraft.world.entity.animal.horse.SkeletonHorse.class, SkeletonHorse.class);
bukkitMap.put(net.minecraft.world.entity.animal.horse.ZombieHorse.class, ZombieHorse.class);
bukkitMap.put(net.minecraft.world.entity.animal.camel.Camel.class, org.bukkit.entity.Camel.class);
bukkitMap.put(net.minecraft.world.entity.monster.AbstractIllager.class, Illager.class);
bukkitMap.put(net.minecraft.world.entity.monster.Illusioner.class, Illusioner.class);
bukkitMap.put(net.minecraft.world.entity.monster.SpellcasterIllager.class, Spellcaster.class);
bukkitMap.put(net.minecraft.world.entity.animal.IronGolem.class, IronGolem.class);
bukkitMap.put(net.minecraft.world.entity.animal.horse.Llama.class, Llama.class);
bukkitMap.put(net.minecraft.world.entity.animal.horse.TraderLlama.class, TraderLlama.class);
bukkitMap.put(net.minecraft.world.entity.monster.MagmaCube.class, MagmaCube.class);
bukkitMap.put(net.minecraft.world.entity.monster.Monster.class, Monster.class);
bukkitMap.put(net.minecraft.world.entity.monster.PatrollingMonster.class, Raider.class); // close enough
bukkitMap.put(net.minecraft.world.entity.animal.MushroomCow.class, MushroomCow.class);
bukkitMap.put(net.minecraft.world.entity.animal.Ocelot.class, Ocelot.class);
bukkitMap.put(net.minecraft.world.entity.animal.Panda.class, Panda.class);
bukkitMap.put(net.minecraft.world.entity.animal.Parrot.class, Parrot.class);
bukkitMap.put(net.minecraft.world.entity.animal.ShoulderRidingEntity.class, Parrot.class); // close enough
bukkitMap.put(net.minecraft.world.entity.monster.Phantom.class, Phantom.class);
bukkitMap.put(net.minecraft.world.entity.animal.Pig.class, Pig.class);
bukkitMap.put(net.minecraft.world.entity.monster.ZombifiedPiglin.class, PigZombie.class);
bukkitMap.put(net.minecraft.world.entity.monster.Pillager.class, Pillager.class);
bukkitMap.put(net.minecraft.world.entity.animal.PolarBear.class, PolarBear.class);
bukkitMap.put(net.minecraft.world.entity.animal.Pufferfish.class, PufferFish.class);
bukkitMap.put(net.minecraft.world.entity.animal.Rabbit.class, Rabbit.class);
bukkitMap.put(net.minecraft.world.entity.raid.Raider.class, Raider.class);
bukkitMap.put(net.minecraft.world.entity.monster.Ravager.class, Ravager.class);
bukkitMap.put(net.minecraft.world.entity.animal.Salmon.class, Salmon.class);
bukkitMap.put(net.minecraft.world.entity.animal.sheep.Sheep.class, Sheep.class);
bukkitMap.put(net.minecraft.world.entity.monster.Shulker.class, Shulker.class);
bukkitMap.put(net.minecraft.world.entity.monster.Silverfish.class, Silverfish.class);
bukkitMap.put(net.minecraft.world.entity.monster.Skeleton.class, Skeleton.class);
bukkitMap.put(net.minecraft.world.entity.monster.AbstractSkeleton.class, AbstractSkeleton.class);
bukkitMap.put(net.minecraft.world.entity.monster.Stray.class, Stray.class);
bukkitMap.put(net.minecraft.world.entity.monster.WitherSkeleton.class, WitherSkeleton.class);
bukkitMap.put(net.minecraft.world.entity.monster.Slime.class, Slime.class);
bukkitMap.put(net.minecraft.world.entity.animal.SnowGolem.class, Snowman.class);
bukkitMap.put(net.minecraft.world.entity.monster.Spider.class, Spider.class);
bukkitMap.put(net.minecraft.world.entity.animal.Squid.class, Squid.class);
bukkitMap.put(net.minecraft.world.entity.TamableAnimal.class, Tameable.class);
bukkitMap.put(net.minecraft.world.entity.animal.TropicalFish.class, TropicalFish.class);
bukkitMap.put(net.minecraft.world.entity.animal.Turtle.class, Turtle.class);
bukkitMap.put(net.minecraft.world.entity.monster.Vex.class, Vex.class);
bukkitMap.put(net.minecraft.world.entity.npc.Villager.class, Villager.class);
bukkitMap.put(net.minecraft.world.entity.npc.AbstractVillager.class, AbstractVillager.class);
bukkitMap.put(net.minecraft.world.entity.npc.WanderingTrader.class, WanderingTrader.class);
bukkitMap.put(net.minecraft.world.entity.monster.Vindicator.class, Vindicator.class);
bukkitMap.put(net.minecraft.world.entity.animal.WaterAnimal.class, WaterMob.class);
bukkitMap.put(net.minecraft.world.entity.monster.Witch.class, Witch.class);
bukkitMap.put(net.minecraft.world.entity.boss.wither.WitherBoss.class, Wither.class);
bukkitMap.put(net.minecraft.world.entity.animal.wolf.Wolf.class, Wolf.class);
bukkitMap.put(net.minecraft.world.entity.monster.Zombie.class, Zombie.class);
bukkitMap.put(net.minecraft.world.entity.monster.Husk.class, Husk.class);
bukkitMap.put(net.minecraft.world.entity.monster.ZombieVillager.class, ZombieVillager.class);
bukkitMap.put(net.minecraft.world.entity.monster.hoglin.Hoglin.class, Hoglin.class);
bukkitMap.put(net.minecraft.world.entity.monster.piglin.Piglin.class, Piglin.class);
bukkitMap.put(net.minecraft.world.entity.monster.piglin.AbstractPiglin.class, PiglinAbstract.class);
bukkitMap.put(net.minecraft.world.entity.monster.piglin.PiglinBrute.class, PiglinBrute.class);
bukkitMap.put(net.minecraft.world.entity.monster.Strider.class, Strider.class);
bukkitMap.put(net.minecraft.world.entity.monster.Zoglin.class, Zoglin.class);
bukkitMap.put(net.minecraft.world.entity.GlowSquid.class, GlowSquid.class);
bukkitMap.put(net.minecraft.world.entity.animal.axolotl.Axolotl.class, Axolotl.class);
bukkitMap.put(net.minecraft.world.entity.animal.goat.Goat.class, Goat.class);
bukkitMap.put(net.minecraft.world.entity.animal.frog.Frog.class, Frog.class);
bukkitMap.put(net.minecraft.world.entity.animal.frog.Tadpole.class, Tadpole.class);
bukkitMap.put(net.minecraft.world.entity.monster.warden.Warden.class, Warden.class);
bukkitMap.put(net.minecraft.world.entity.animal.allay.Allay.class, Allay.class);
bukkitMap.put(net.minecraft.world.entity.animal.sniffer.Sniffer.class, Sniffer.class);
bukkitMap.put(net.minecraft.world.entity.monster.breeze.Breeze.class, Breeze.class);
bukkitMap.put(net.minecraft.world.entity.animal.armadillo.Armadillo.class, Armadillo.class);
bukkitMap.put(net.minecraft.world.entity.monster.Bogged.class, Bogged.class);
bukkitMap.put(net.minecraft.world.entity.monster.creaking.Creaking.class, Creaking.class);
bukkitMap.put(net.minecraft.world.entity.animal.AgeableWaterCreature.class, Squid.class); // close enough
bukkitMap.put(net.minecraft.world.entity.animal.AbstractCow.class, AbstractCow.class);
map.put(net.minecraft.world.entity.Mob.class, Mob.class);
map.put(net.minecraft.world.entity.AgeableMob.class, Ageable.class);
map.put(net.minecraft.world.entity.ambient.AmbientCreature.class, Ambient.class);
map.put(net.minecraft.world.entity.animal.Animal.class, Animals.class);
map.put(net.minecraft.world.entity.ambient.Bat.class, Bat.class);
map.put(net.minecraft.world.entity.animal.Bee.class, Bee.class);
map.put(net.minecraft.world.entity.monster.Blaze.class, Blaze.class);
map.put(net.minecraft.world.entity.animal.Cat.class, Cat.class);
map.put(net.minecraft.world.entity.monster.CaveSpider.class, CaveSpider.class);
map.put(net.minecraft.world.entity.animal.Chicken.class, Chicken.class);
map.put(net.minecraft.world.entity.animal.Cod.class, Cod.class);
map.put(net.minecraft.world.entity.animal.Cow.class, Cow.class);
map.put(net.minecraft.world.entity.PathfinderMob.class, Creature.class);
map.put(net.minecraft.world.entity.monster.Creeper.class, Creeper.class);
map.put(net.minecraft.world.entity.animal.Dolphin.class, Dolphin.class);
map.put(net.minecraft.world.entity.monster.Drowned.class, Drowned.class);
map.put(net.minecraft.world.entity.boss.enderdragon.EnderDragon.class, EnderDragon.class);
map.put(net.minecraft.world.entity.monster.EnderMan.class, Enderman.class);
map.put(net.minecraft.world.entity.monster.Endermite.class, Endermite.class);
map.put(net.minecraft.world.entity.monster.Evoker.class, Evoker.class);
map.put(net.minecraft.world.entity.animal.AbstractFish.class, Fish.class);
map.put(net.minecraft.world.entity.animal.AbstractSchoolingFish.class, SchoolableFish.class);
map.put(net.minecraft.world.entity.animal.Fox.class, Fox.class);
map.put(net.minecraft.world.entity.monster.Ghast.class, Ghast.class);
map.put(net.minecraft.world.entity.monster.Giant.class, Giant.class);
map.put(net.minecraft.world.entity.animal.AbstractGolem.class, Golem.class);
map.put(net.minecraft.world.entity.monster.Guardian.class, Guardian.class);
map.put(net.minecraft.world.entity.monster.ElderGuardian.class, ElderGuardian.class);
map.put(net.minecraft.world.entity.animal.horse.Horse.class, Horse.class);
map.put(net.minecraft.world.entity.animal.horse.AbstractHorse.class, AbstractHorse.class);
map.put(net.minecraft.world.entity.animal.horse.AbstractChestedHorse.class, ChestedHorse.class);
map.put(net.minecraft.world.entity.animal.horse.Donkey.class, Donkey.class);
map.put(net.minecraft.world.entity.animal.horse.Mule.class, Mule.class);
map.put(net.minecraft.world.entity.animal.horse.SkeletonHorse.class, SkeletonHorse.class);
map.put(net.minecraft.world.entity.animal.horse.ZombieHorse.class, ZombieHorse.class);
map.put(net.minecraft.world.entity.animal.camel.Camel.class, org.bukkit.entity.Camel.class);
map.put(net.minecraft.world.entity.monster.AbstractIllager.class, Illager.class);
map.put(net.minecraft.world.entity.monster.Illusioner.class, Illusioner.class);
map.put(net.minecraft.world.entity.monster.SpellcasterIllager.class, Spellcaster.class);
map.put(net.minecraft.world.entity.animal.IronGolem.class, IronGolem.class);
map.put(net.minecraft.world.entity.animal.horse.Llama.class, Llama.class);
map.put(net.minecraft.world.entity.animal.horse.TraderLlama.class, TraderLlama.class);
map.put(net.minecraft.world.entity.monster.MagmaCube.class, MagmaCube.class);
map.put(net.minecraft.world.entity.monster.Monster.class, Monster.class);
map.put(net.minecraft.world.entity.monster.PatrollingMonster.class, Raider.class); // close enough
map.put(net.minecraft.world.entity.animal.MushroomCow.class, MushroomCow.class);
map.put(net.minecraft.world.entity.animal.Ocelot.class, Ocelot.class);
map.put(net.minecraft.world.entity.animal.Panda.class, Panda.class);
map.put(net.minecraft.world.entity.animal.Parrot.class, Parrot.class);
map.put(net.minecraft.world.entity.animal.ShoulderRidingEntity.class, Parrot.class); // close enough
map.put(net.minecraft.world.entity.monster.Phantom.class, Phantom.class);
map.put(net.minecraft.world.entity.animal.Pig.class, Pig.class);
map.put(net.minecraft.world.entity.monster.ZombifiedPiglin.class, PigZombie.class);
map.put(net.minecraft.world.entity.monster.Pillager.class, Pillager.class);
map.put(net.minecraft.world.entity.animal.PolarBear.class, PolarBear.class);
map.put(net.minecraft.world.entity.animal.Pufferfish.class, PufferFish.class);
map.put(net.minecraft.world.entity.animal.Rabbit.class, Rabbit.class);
map.put(net.minecraft.world.entity.raid.Raider.class, Raider.class);
map.put(net.minecraft.world.entity.monster.Ravager.class, Ravager.class);
map.put(net.minecraft.world.entity.animal.Salmon.class, Salmon.class);
map.put(net.minecraft.world.entity.animal.sheep.Sheep.class, Sheep.class);
map.put(net.minecraft.world.entity.monster.Shulker.class, Shulker.class);
map.put(net.minecraft.world.entity.monster.Silverfish.class, Silverfish.class);
map.put(net.minecraft.world.entity.monster.Skeleton.class, Skeleton.class);
map.put(net.minecraft.world.entity.monster.AbstractSkeleton.class, AbstractSkeleton.class);
map.put(net.minecraft.world.entity.monster.Stray.class, Stray.class);
map.put(net.minecraft.world.entity.monster.WitherSkeleton.class, WitherSkeleton.class);
map.put(net.minecraft.world.entity.monster.Slime.class, Slime.class);
map.put(net.minecraft.world.entity.animal.SnowGolem.class, Snowman.class);
map.put(net.minecraft.world.entity.monster.Spider.class, Spider.class);
map.put(net.minecraft.world.entity.animal.Squid.class, Squid.class);
map.put(net.minecraft.world.entity.TamableAnimal.class, Tameable.class);
map.put(net.minecraft.world.entity.animal.TropicalFish.class, TropicalFish.class);
map.put(net.minecraft.world.entity.animal.Turtle.class, Turtle.class);
map.put(net.minecraft.world.entity.monster.Vex.class, Vex.class);
map.put(net.minecraft.world.entity.npc.Villager.class, Villager.class);
map.put(net.minecraft.world.entity.npc.AbstractVillager.class, AbstractVillager.class);
map.put(net.minecraft.world.entity.npc.WanderingTrader.class, WanderingTrader.class);
map.put(net.minecraft.world.entity.monster.Vindicator.class, Vindicator.class);
map.put(net.minecraft.world.entity.animal.WaterAnimal.class, WaterMob.class);
map.put(net.minecraft.world.entity.monster.Witch.class, Witch.class);
map.put(net.minecraft.world.entity.boss.wither.WitherBoss.class, Wither.class);
map.put(net.minecraft.world.entity.animal.wolf.Wolf.class, Wolf.class);
map.put(net.minecraft.world.entity.monster.Zombie.class, Zombie.class);
map.put(net.minecraft.world.entity.monster.Husk.class, Husk.class);
map.put(net.minecraft.world.entity.monster.ZombieVillager.class, ZombieVillager.class);
map.put(net.minecraft.world.entity.monster.hoglin.Hoglin.class, Hoglin.class);
map.put(net.minecraft.world.entity.monster.piglin.Piglin.class, Piglin.class);
map.put(net.minecraft.world.entity.monster.piglin.AbstractPiglin.class, PiglinAbstract.class);
map.put(net.minecraft.world.entity.monster.piglin.PiglinBrute.class, PiglinBrute.class);
map.put(net.minecraft.world.entity.monster.Strider.class, Strider.class);
map.put(net.minecraft.world.entity.monster.Zoglin.class, Zoglin.class);
map.put(net.minecraft.world.entity.GlowSquid.class, GlowSquid.class);
map.put(net.minecraft.world.entity.animal.axolotl.Axolotl.class, Axolotl.class);
map.put(net.minecraft.world.entity.animal.goat.Goat.class, Goat.class);
map.put(net.minecraft.world.entity.animal.frog.Frog.class, Frog.class);
map.put(net.minecraft.world.entity.animal.frog.Tadpole.class, Tadpole.class);
map.put(net.minecraft.world.entity.monster.warden.Warden.class, Warden.class);
map.put(net.minecraft.world.entity.animal.allay.Allay.class, Allay.class);
map.put(net.minecraft.world.entity.animal.sniffer.Sniffer.class, Sniffer.class);
map.put(net.minecraft.world.entity.monster.breeze.Breeze.class, Breeze.class);
map.put(net.minecraft.world.entity.animal.armadillo.Armadillo.class, Armadillo.class);
map.put(net.minecraft.world.entity.monster.Bogged.class, Bogged.class);
map.put(net.minecraft.world.entity.monster.creaking.Creaking.class, Creaking.class);
map.put(net.minecraft.world.entity.animal.AgeableWaterCreature.class, Squid.class); // close enough
map.put(net.minecraft.world.entity.animal.AbstractCow.class, AbstractCow.class);
map.put(net.minecraft.world.entity.animal.HappyGhast.class, HappyGhast.class);
//</editor-fold>
}
});
private static final Map<String, String> deobfuscationMap = new HashMap<>();
// TODO these kinda should be checked on each release, in case nested classes changes
private static final Map<String, String> NESTED_CLASS_NAMES = Util.make(new HashMap<>(), map -> {
map.put("AbstractSkeleton$1", "AbstractSkeletonMelee");
static {
// TODO these kinda should be checked on each release, in case obfuscation changes
deobfuscationMap.put("abstract_skeleton_1", "abstract_skeleton_melee");
}
// remove duplicate
map.put("TraderLlama$TraderLlamaDefendWanderingTraderGoal", "TraderLlamaDefendWanderingTraderGoal");
map.put("AbstractIllager$RaiderOpenDoorGoal", "RaiderOpenDoorGoal");
private static String getPathName(String name) {
// weird enderman case
map.put("EnderMan.EndermanFreezeWhenLookedAt", "EndermanFreezeWhenLookedAt");
map.put("EnderMan.EndermanLeaveBlockGoal", "EndermanLeaveBlockGoal");
map.put("EnderMan.EndermanTakeBlockGoal", "EndermanTakeBlockGoal");
map.put("EnderMan.EndermanLookForPlayerGoal", "EndermanLookForPlayerGoal");
});
private static final Set<Class<? extends Mob>> NO_SPECIFIER = Set.of(
Mob.class,
Creature.class,
Animals.class,
RangedEntity.class,
Tameable.class,
Monster.class,
PufferFish.class // weird case
);
private static String getPathName(Class<? extends Mob> type, Class<?> holderClass, String name) {
String pathName = name.substring(name.lastIndexOf('.') + 1);
boolean needDeobfMap = false;
boolean needRename = false;
// inner classes
int firstInnerDelimiter = pathName.indexOf('$');
if (firstInnerDelimiter != -1) {
String innerClassName = pathName.substring(firstInnerDelimiter + 1);
for (String nestedClass : innerClassName.split("\\$")) {
if (NumberUtils.isDigits(nestedClass)) {
needDeobfMap = true;
String innerClassNames = pathName.substring(firstInnerDelimiter + 1);
for (String innerClassName : innerClassNames.split("\\$")) {
if (NumberUtils.isDigits(innerClassName)) {
needRename = true;
break;
}
}
if (!needDeobfMap) {
pathName = innerClassName;
if (!needRename && !NESTED_CLASS_NAMES.containsKey(pathName)) {
pathName = innerClassNames;
}
pathName = pathName.replace('$', '_');
// mapped, wooo!
}
if (!NESTED_CLASS_NAMES.containsKey(pathName)) {
if (needRename) {
throw new IllegalStateException("need to map " + name + " (" + pathName + ")");
}
String prefix = null;
if (!NO_SPECIFIER.contains(type)) {
prefix = type.getSimpleName();
} else if (!net.minecraft.world.entity.Mob.class.isAssignableFrom(holderClass)) {
prefix = holderClass.getSimpleName();
}
if (prefix != null && !pathName.startsWith(prefix)) {
pathName = prefix + pathName;
}
} else {
pathName = NESTED_CLASS_NAMES.get(pathName);
}
pathName = Formatting.stripWordOfCamelCaseName(pathName, "TargetGoal", true); // replace last? reverse search?
pathName = Formatting.stripWordOfCamelCaseName(pathName, "Goal", true);
pathName = Formatting.stripWordOfCamelCaseName(pathName, "Abstract", true);
pathName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, pathName);
if (needDeobfMap && !deobfuscationMap.containsKey(pathName)) {
System.err.println("need to map " + name + " (" + pathName + ")");
}
// did we rename this key?
return deobfuscationMap.getOrDefault(pathName, pathName);
return pathName;
}
public static <T extends Mob> GoalKey<T> getKey(Class<? extends Goal> goalClass) {
String name = getPathName(goalClass.getName());
return GoalKey.of(getEntity(goalClass), NamespacedKey.minecraft(name));
Class<T> type = getGenericType(goalClass);
Class<?> holderClass = ClassHelper.getTopLevelClass(goalClass);
String name = getPathName(type, holderClass, goalClass.getName());
return GoalKey.of(type, NamespacedKey.minecraft(name));
}
private static <T extends Mob> Class<T> getEntity(Class<? extends Goal> goalClass) {
private static final Int2BooleanFunction[] VISIBILITY_SEARCH_STEP = {
Modifier::isPublic,
Modifier::isProtected,
mod -> (mod & 0b111) == 0, // package-private
Modifier::isPrivate,
};
private static final Comparator<Constructor<?>> VISIBILITY_ORDER = Comparator.comparingInt(constructor -> {
int mod = constructor.getModifiers();
for (int i = 0; i < VISIBILITY_SEARCH_STEP.length; i++) {
Int2BooleanFunction visibility = VISIBILITY_SEARCH_STEP[i];
if (visibility.test(mod)) {
return i;
}
}
throw new UnsupportedOperationException("Unknown visibility: " + mod);
});
private static <T extends Mob> Class<T> getGenericType(Class<? extends Goal> goalClass) {
//noinspection unchecked
return (Class<T>) entityClassCache.computeIfAbsent(goalClass, key -> {
for (Constructor<?> ctor : key.getDeclaredConstructors()) {
for (Class<?> param : ctor.getParameterTypes()) {
if (net.minecraft.world.entity.Mob.class.isAssignableFrom(param)) {
return (Class<T>) GENERIC_TYPE_CACHE.computeIfAbsent(goalClass, key -> {
Constructor<?>[] constructors = key.getDeclaredConstructors();
Arrays.sort(constructors, VISIBILITY_ORDER);
for (Constructor<?> constructor : constructors) {
for (Class<?> paramType : constructor.getParameterTypes()) {
if (net.minecraft.world.entity.Mob.class.isAssignableFrom(paramType)) {
//noinspection unchecked
return toBukkitClass((Class<? extends net.minecraft.world.entity.Mob>) param);
} else if (RangedAttackMob.class.isAssignableFrom(param)) {
return toBukkitClass((Class<? extends net.minecraft.world.entity.Mob>) paramType);
} else if (RangedAttackMob.class.isAssignableFrom(paramType)) {
return RangedEntity.class;
}
}
}
throw new RuntimeException("Can't figure out applicable entity for mob goal " + goalClass); // maybe just return Mob?
throw new IllegalStateException("Can't figure out applicable entity for mob goal " + goalClass); // maybe just return Mob?
});
}
private static Class<? extends Mob> toBukkitClass(Class<? extends net.minecraft.world.entity.Mob> nmsClass) {
Class<? extends Mob> bukkitClass = bukkitMap.get(nmsClass);
private static Class<? extends Mob> toBukkitClass(Class<? extends net.minecraft.world.entity.Mob> internalClass) {
Class<? extends Mob> bukkitClass = BUKKIT_BRIDGE.get(internalClass);
if (bukkitClass == null) {
throw new RuntimeException("Can't figure out applicable bukkit entity for nms entity " + nmsClass); // maybe just return Mob?
throw new IllegalStateException("Can't figure out applicable bukkit entity for internal entity " + internalClass); // maybe just return Mob?
}
return bukkitClass;
}

View File

@ -84,7 +84,7 @@ public class GeneratedKeyType<T> extends SimpleGenerator {
MethodSpec.Builder createMethod = this.createMethod(typedKeyType);
boolean allExperimental = true;
for (Holder.Reference<T> reference : this.entry.registry().listElements().sorted(Formatting.alphabeticKeyOrder(reference -> reference.key().location().getPath())).toList()) {
for (Holder.Reference<T> reference : this.entry.registry().listElements().sorted(Formatting.HOLDER_ORDER).toList()) {
ResourceKey<T> key = reference.key();
String keyPath = key.location().getPath();
String fieldName = Formatting.formatKeyAsField(keyPath);

View File

@ -73,7 +73,7 @@ public class GeneratedTagKeyType extends SimpleGenerator {
MethodSpec.Builder createMethod = this.createMethod(tagKeyType);
AtomicBoolean allExperimental = new AtomicBoolean(true);
this.entry.registry().listTagIds().sorted(Formatting.alphabeticKeyOrder(tagKey -> tagKey.location().getPath())).forEach(tagKey -> {
this.entry.registry().listTagIds().sorted(Formatting.TAG_ORDER).forEach(tagKey -> {
String fieldName = Formatting.formatKeyAsField(tagKey.location().getPath());
FieldSpec.Builder fieldBuilder = FieldSpec.builder(tagKeyType, fieldName, PUBLIC, STATIC, FINAL)
.initializer("$N(key($S))", createMethod.build(), tagKey.location().getPath())

View File

@ -35,7 +35,7 @@ public final class Annotations {
public static final AnnotationSpec NULL_MARKED = AnnotationSpec.builder(NullMarked.class).build();
public static final AnnotationSpec OVERRIDE = AnnotationSpec.builder(Override.class).build();
public static final AnnotationSpec GENERATED_FROM = AnnotationSpec.builder(GeneratedFrom.class)
.addMember("value", "$S", SharedConstants.getCurrentVersion().getId())
.addMember("value", "$S", SharedConstants.getCurrentVersion().id())
.build();
public static final Iterable<AnnotationSpec> CLASS_HEADER = List.of(
suppressWarnings("unused", "SpellCheckingInspection"),

View File

@ -1,17 +1,19 @@
package io.papermc.generator.utils;
import java.util.Optional;
import org.apache.commons.lang3.math.NumberUtils;
import java.util.Comparator;
import java.util.Locale;
import java.util.OptionalInt;
import java.util.Optional;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.IntStream;
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.tags.TagKey;
import org.apache.commons.lang3.math.NumberUtils;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
@NullMarked
public final class Formatting {
@ -73,33 +75,36 @@ public final class Formatting {
return newName;
}
public static final Comparator<String> ALPHABETIC_KEY_ORDER = alphabeticKeyOrder(path -> path);
public static final Comparator<Holder.Reference<?>> HOLDER_ORDER = alphabeticKeyOrder(reference -> reference.key().location().getPath());
public static final Comparator<TagKey<?>> TAG_ORDER = alphabeticKeyOrder(tagKey -> tagKey.location().getPath());
public static <T> Comparator<T> alphabeticKeyOrder(Function<T, String> mapper) {
return (o1, o2) -> {
String path1 = mapper.apply(o1);
String path2 = mapper.apply(o2);
public static <T> Comparator<T> alphabeticKeyOrder(Function<T, String> pathConverter) {
return Comparator.comparing(pathConverter, (path1, path2) -> {
TrailingInt trailingInt1 = tryParseTrailingInt(path1);
TrailingInt trailingInt2 = tryParseTrailingInt(path2);
OptionalInt trailingInt1 = tryParseTrailingInt(path1);
OptionalInt trailingInt2 = tryParseTrailingInt(path2);
if (trailingInt1.isPresent() && trailingInt2.isPresent()) {
return Integer.compare(trailingInt1.getAsInt(), trailingInt2.getAsInt());
if (trailingInt1 != null && trailingInt2 != null &&
trailingInt1.prefix().equals(trailingInt2.prefix())) {
return Integer.compareUnsigned(trailingInt1.value(), trailingInt2.value());
}
return path1.compareTo(path2);
};
});
}
private static OptionalInt tryParseTrailingInt(String path) {
private static @Nullable TrailingInt tryParseTrailingInt(String path) {
int delimiterIndex = path.lastIndexOf('_');
if (delimiterIndex != -1) {
String score = path.substring(delimiterIndex + 1);
if (NumberUtils.isDigits(score)) {
return OptionalInt.of(Integer.parseInt(score));
String value = path.substring(delimiterIndex + 1);
if (NumberUtils.isDigits(value)) {
String prefix = path.substring(0, delimiterIndex);
return new TrailingInt(prefix, Integer.parseInt(value));
}
}
return OptionalInt.empty();
return null;
}
private record TrailingInt(String prefix, int value) {
}
private Formatting() {

View File

@ -1,6 +1,7 @@
package io.papermc.generator;
import io.papermc.generator.utils.BlockStateMapping;
import io.papermc.generator.utils.ClassHelper;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
@ -10,7 +11,6 @@ import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import io.papermc.generator.utils.ClassHelper;
import net.minecraft.SharedConstants;
import net.minecraft.server.Bootstrap;
import net.minecraft.world.level.block.ChiseledBookShelfBlock;

View File

@ -25,7 +25,7 @@ public class MobGoalConverterTest {
List<String> missingClasses = new ArrayList<>();
for (Class<Mob> nmsClass : classes) {
if (!MobGoalNames.bukkitMap.containsKey(nmsClass)) {
if (!MobGoalNames.BUKKIT_BRIDGE.containsKey(nmsClass)) {
missingClasses.add(nmsClass.getCanonicalName());
}
}