mark experimental tags

This commit is contained in:
Lulu13022002 2024-01-26 22:01:44 +01:00
parent 0cad15bc3b
commit 72c2faa3ec
No known key found for this signature in database
GPG Key ID: 491C8F0B8ACDEB01
11 changed files with 142 additions and 67 deletions

View File

@ -1939,6 +1939,8 @@ public enum Sound implements Keyed, net.kyori.adventure.sound.Sound.Type {
ENTITY_GENERIC_SWIM("entity.generic.swim"),
@ApiStatus.Experimental
@MinecraftExperimental("update 1.21")
ENTITY_GENERIC_WIND_BURST("entity.generic.wind_burst"),
ENTITY_GHAST_AMBIENT("entity.ghast.ambient"),

View File

@ -3,6 +3,7 @@ package org.bukkit;
import io.papermc.paper.generated.GeneratedFrom;
import java.util.Set;
import org.bukkit.entity.EntityType;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
/**
@ -1995,6 +1996,8 @@ public interface Tag<T extends Keyed> extends Keyed {
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
@ApiStatus.Experimental
@MinecraftExperimental("update 1.21")
Tag<EntityType> ENTITY_TYPES_CAN_TURN_IN_BOATS = Bukkit.getTag(REGISTRY_ENTITY_TYPES, NamespacedKey.minecraft("can_turn_in_boats"), EntityType.class);
/**
@ -2002,6 +2005,8 @@ public interface Tag<T extends Keyed> extends Keyed {
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
@ApiStatus.Experimental
@MinecraftExperimental("update 1.21")
Tag<EntityType> ENTITY_TYPES_DEFLECTS_ARROWS = Bukkit.getTag(REGISTRY_ENTITY_TYPES, NamespacedKey.minecraft("deflects_arrows"), EntityType.class);
/**
@ -2009,6 +2014,8 @@ public interface Tag<T extends Keyed> extends Keyed {
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
@ApiStatus.Experimental
@MinecraftExperimental("update 1.21")
Tag<EntityType> ENTITY_TYPES_DEFLECTS_TRIDENTS = Bukkit.getTag(REGISTRY_ENTITY_TYPES, NamespacedKey.minecraft("deflects_tridents"), EntityType.class);
/**

View File

@ -1,46 +0,0 @@
package org.bukkit.entity;
import io.papermc.paper.generated.GeneratedFrom;
@SuppressWarnings({
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.20.4")
public enum Pose {
STANDING,
FALL_FLYING,
SLEEPING,
SWIMMING,
SPIN_ATTACK,
CROUCHING,
LONG_JUMPING,
DYING,
CROAKING,
USING_TONGUE,
SITTING,
ROARING,
SNIFFING,
EMERGING,
DIGGING,
SLIDING,
SHOOTING,
INHALING
}

View File

@ -3,7 +3,6 @@ package io.papermc.generator;
import io.papermc.generator.types.registry.AttributeGenerator;
import io.papermc.generator.types.registry.GeneratedKeyType;
import io.papermc.generator.types.SourceGenerator;
import io.papermc.generator.types.enumgen.EnumGenerator;
import io.papermc.generator.types.registry.BiomeGenerator;
import io.papermc.generator.types.registry.SoundGenerator;
import io.papermc.generator.types.goal.MobGoalGenerator;
@ -15,7 +14,6 @@ import io.papermc.paper.registry.RegistryKey;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.entity.Pose;
import org.bukkit.GameEvent;
import org.bukkit.block.Biome;
import org.bukkit.generator.structure.Structure;
@ -40,7 +38,6 @@ public interface Generators {
new StructureGenerator("Structure", "org.bukkit.generator.structure"),
new LegacyKeyedRegistryGenerator<>("TrimPattern", TrimPattern.class, "org.bukkit.inventory.meta.trim", Registries.TRIM_PATTERN, RegistryKey.TRIM_PATTERN),
new LegacyKeyedRegistryGenerator<>("TrimMaterial", TrimMaterial.class, "org.bukkit.inventory.meta.trim", Registries.TRIM_MATERIAL, RegistryKey.TRIM_MATERIAL),
new EnumGenerator<>(Pose.class, "org.bukkit.entity"),
new TagGenerator("Tag", "org.bukkit")
};

View File

@ -5,7 +5,8 @@ import com.mojang.logging.LogUtils;
import io.papermc.generator.types.SourceGenerator;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import io.papermc.generator.utils.TagCollector;
import io.papermc.generator.utils.TagResult;
import net.minecraft.SharedConstants;
import net.minecraft.commands.Commands;
import net.minecraft.core.LayeredRegistryAccess;
@ -28,6 +29,7 @@ public final class Main {
private static final Logger LOGGER = LogUtils.getLogger();
public static final RegistryAccess.Frozen REGISTRY_ACCESS;
public static final TagResult EXPERIMENTAL_TAGS;
static {
SharedConstants.tryDetectVersion();
@ -40,6 +42,7 @@ public final class Main {
REGISTRY_ACCESS = layers.compositeAccess().freeze();
final ReloadableServerResources datapack = ReloadableServerResources.loadResources(resourceManager, REGISTRY_ACCESS, FeatureFlags.REGISTRY.allFlags(), Commands.CommandSelection.DEDICATED, 0, MoreExecutors.directExecutor(), MoreExecutors.directExecutor()).join();
datapack.updateRegistryTags(REGISTRY_ACCESS);
EXPERIMENTAL_TAGS = TagCollector.grabExperimental(resourceManager);
}
private Main() {
@ -47,9 +50,9 @@ public final class Main {
public static void main(final String[] args) {
LOGGER.info("Running API generators...");
generate(Paths.get(args[0]), Generators.API);
generate(Path.of(args[0]), Generators.API);
// LOGGER.info("Running Server generators...");
// generate(Paths.get(args[1]), Generators.SERVER);
// generate(Path.of(args[1]), Generators.SERVER);
}
private static void generate(Path output, SourceGenerator[] generators) {

View File

@ -8,7 +8,8 @@ import io.papermc.generator.utils.Formatting;
import io.papermc.generator.utils.Javadocs;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import net.kyori.adventure.sound.Sound;
@ -35,7 +36,11 @@ public class SoundGenerator extends EnumRegistryGenerator<SoundEvent> {
return "entity";
}
return key.location().getPath();
}, value -> Suppliers.memoize(() -> Main.REGISTRY_ACCESS.registryOrThrow(value))));
}, key -> Suppliers.memoize(() -> Main.REGISTRY_ACCESS.registryOrThrow(key))));
private static final Set<String> EXPERIMENTAL_EXCEPTIONS = Set.of(
"entity.generic.wind_burst"
);
public SoundGenerator(final String className, final String pkg) {
super(className, pkg, Registries.SOUND_EVENT);
@ -55,21 +60,30 @@ public class SoundGenerator extends EnumRegistryGenerator<SoundEvent> {
}
String path = entry.getKey().location().getPath();
// the below way is not perfect, but it tries its best
if (EXPERIMENTAL_EXCEPTIONS.contains(path)) {
return Formatting.formatFeatureFlag(FeatureFlags.UPDATE_1_21);
}
String[] fragments = path.split("\\.");
if (fragments.length < 2) {
return null;
}
for (Map.Entry<String, Supplier<Registry<? extends FeatureElement>>> filteredRegistry : FILTERED_REGISTRIES.entrySet()) {
if (fragments[0].equals(filteredRegistry.getKey())) {
Registry<? extends FeatureElement> registry = filteredRegistry.getValue().get();
FeatureElement element = Objects.requireNonNull(registry.get(new ResourceLocation(ResourceLocation.DEFAULT_NAMESPACE, fragments[1])));
if (element instanceof BundleItem) {
return Formatting.formatFeatureFlag(FeatureFlags.BUNDLE); // special case since the item is not locked itself just in the creative menu
}
if (FeatureFlags.isExperimental(element.requiredFeatures())) {
return Formatting.formatFeatureFlagSet(element.requiredFeatures());
}
Supplier<Registry<? extends FeatureElement>> filteredRegistry = FILTERED_REGISTRIES.get(fragments[0]);
if (filteredRegistry == null) {
return null;
}
Registry<? extends FeatureElement> registry = filteredRegistry.get();
Optional<? extends FeatureElement> optionalElement = registry.getOptional(new ResourceLocation(ResourceLocation.DEFAULT_NAMESPACE, fragments[1]));
if (optionalElement.isPresent()) {
FeatureElement element = optionalElement.get();
if (element instanceof BundleItem) {
return Formatting.formatFeatureFlag(FeatureFlags.BUNDLE); // special case since the item is not locked itself just in the creative menu
}
if (FeatureFlags.isExperimental(element.requiredFeatures())) {
return Formatting.formatFeatureFlagSet(element.requiredFeatures());
}
}

View File

@ -16,6 +16,7 @@ import io.papermc.generator.utils.Annotations;
import io.papermc.generator.utils.Formatting;
import io.papermc.generator.utils.Javadocs;
import io.papermc.paper.tag.EntityTags;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
@ -37,6 +38,7 @@ import org.checkerframework.framework.qual.DefaultQualifier;
import static com.squareup.javapoet.TypeSpec.interfaceBuilder;
import static io.papermc.generator.utils.Annotations.NOT_NULL;
import static io.papermc.generator.utils.Annotations.experimentalAnnotations;
import static javax.lang.model.element.Modifier.ABSTRACT;
import static javax.lang.model.element.Modifier.FINAL;
import static javax.lang.model.element.Modifier.PUBLIC;
@ -121,6 +123,7 @@ public class TagGenerator extends SimpleGenerator {
typeBuilder.addField(registryFieldBuilder.build());
final String fieldPrefix = Formatting.formatTagFieldPrefix(tagRegistry.name(), registryKey);
final Collection<String> experimentalTags = Main.EXPERIMENTAL_TAGS.perRegistry().get(tagRegistry.registryKey());
for (final TagKey<?> tagKey : registry.getTagNames().sorted(Comparator.comparing(tagKey -> tagKey.location().getPath())).toList()) {
final String keyPath = tagKey.location().getPath();
@ -130,6 +133,9 @@ public class TagGenerator extends SimpleGenerator {
.addModifiers(PUBLIC, STATIC, FINAL)
.initializer("$T.getTag($L, $T.minecraft($S), $T.class)", Bukkit.class, registryFieldName, NamespacedKey.class, keyPath, tagRegistry.apiType())
.addJavadoc(Javadocs.getVersionDependentField("{@code $L}"), tagKey.location().toString());
if (experimentalTags.contains(keyPath)) {
fieldBuilder.addAnnotations(experimentalAnnotations(Formatting.formatFeatureFlagName(Main.EXPERIMENTAL_TAGS.perFeatureFlag().get(tagKey))));
}
typeBuilder.addField(fieldBuilder.build());
}

View File

@ -2,8 +2,6 @@ package io.papermc.generator.utils;
import java.util.Locale;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.kyori.adventure.key.Key;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.Registries;
@ -48,6 +46,10 @@ public final class Formatting {
public static String formatFeatureFlag(FeatureFlag featureFlag) {
Set<ResourceLocation> names = FeatureFlags.REGISTRY.toNames(FeatureFlagSet.of(featureFlag));
String name = names.iterator().next().getPath(); // eww
return formatFeatureFlagName(name);
}
public static String formatFeatureFlagName(String name) {
int updateIndex = name.indexOf("update_");
if (updateIndex == 0) {
return "update %s".formatted(name.substring(updateIndex + "update_".length()).replace('_', '.'));
@ -55,6 +57,15 @@ public final class Formatting {
return name.replace('_', ' ') + " feature";
}
public static String formatTagKey(String tagDir, String resourcePath) {
int tagsIndex = resourcePath.indexOf(tagDir);
int dotIndex = resourcePath.lastIndexOf('.');
if (tagsIndex == -1 || dotIndex == -1) {
return "none";
}
return resourcePath.substring(tagsIndex + tagDir.length() + 1, dotIndex); // tags/registry_key/[tagKey].json
}
private Formatting() {
}
}

View File

@ -4,7 +4,6 @@ import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;

View File

@ -0,0 +1,73 @@
package io.papermc.generator.utils;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import io.papermc.generator.Main;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.PackResources;
import net.minecraft.server.packs.PackType;
import net.minecraft.server.packs.resources.MultiPackResourceManager;
import net.minecraft.tags.TagKey;
import net.minecraft.tags.TagManager;
// collect all the tags by grabbing the json from the datapack
// another (probably) way is to hook into the data generator like the key generator
public final class TagCollector {
private static ResourceLocation minecraft(String path) {
return new ResourceLocation(ResourceLocation.DEFAULT_NAMESPACE, path);
}
public static TagResult grabExperimental(final MultiPackResourceManager resourceManager) {
Map<TagKey<?>, String> perFeatureFlag = new HashMap<>();
ImmutableMultimap.Builder<ResourceKey<? extends Registry<?>>, String> perRegistry = ImmutableMultimap.builder();
// first collect all vanilla tags
Multimap<ResourceKey<? extends Registry<?>>, String> vanillaTags = HashMultimap.create();
resourceManager.listPacks().filter(packResources -> packResources.packId().equals("vanilla")).forEach(pack -> {
collectFromPack(pack, vanillaTags::put);
});
// then distinct with other datapack tags to know for sure newly created tags and so experimental one
resourceManager.listPacks().forEach(pack -> {
String packId = pack.packId();
if (packId.equals("vanilla")) return;
collectFromPack(pack, (registryKey, path) -> {
if (vanillaTags.get(registryKey).contains(path)) {
return;
}
perFeatureFlag.put(TagKey.create((ResourceKey<? extends Registry<Object>>) registryKey, minecraft(path)), packId);
perRegistry.put(registryKey, path);
});
});
return new TagResult(perFeatureFlag, perRegistry.build());
}
private static void collectFromPack(PackResources pack, BiConsumer<ResourceKey<? extends Registry<?>>, String> output) {
Set<String> namespaces = pack.getNamespaces(PackType.SERVER_DATA);
for (String namespace : namespaces) {
Main.REGISTRY_ACCESS.registries().forEach(entry -> {
// this is probably expensive but can't find another way around and datapack loader has similar logic
// the issue is that registry key can have parent/key (and custom folder too) but tag key can also have parent/key so parsing become a mess
// without having at least one of the two values
String tagDir = TagManager.getTagDir(entry.key());
pack.listResources(PackType.SERVER_DATA, namespace, tagDir, (id, supplier) -> {
output.accept(entry.key(), Formatting.formatTagKey(tagDir, id.getPath()));
});
});
}
}
private TagCollector() {
}
}

View File

@ -0,0 +1,9 @@
package io.papermc.generator.utils;
import com.google.common.collect.Multimap;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey;
import net.minecraft.tags.TagKey;
import java.util.Map;
public record TagResult(Map<TagKey<?>, String> perFeatureFlag, Multimap<ResourceKey<? extends Registry<?>>, String> perRegistry) {}