From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Fri, 26 May 2023 18:14:44 -0700 Subject: [PATCH] Code Generation Currently includes generated key holder classes for types used in the Registry Modification API diff --git a/build.gradle.kts b/build.gradle.kts index 768024b2b4584fd7dd86f068c0e79c89ffc5faa1..f11a22ab01e97e51619c96f2d8a78a99297efc59 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,7 @@ plugins { `java-library` `maven-publish` + idea // Paper } java { @@ -45,6 +46,22 @@ dependencies { testImplementation("org.ow2.asm:asm-tree:9.7") } +// Paper start +val generatedApiPath: java.nio.file.Path = rootProject.projectDir.toPath().resolve("paper-api-generator/generated") +idea { + module { + generatedSourceDirs.add(generatedApiPath.toFile()) + } +} +sourceSets { + main { + java { + srcDir(generatedApiPath) + } + } +} +// Paper end + configure { publications.create("maven") { from(components["java"]) @@ -121,3 +138,14 @@ tasks.check { dependsOn(scanJar) } // Paper end +// Paper start +val scanJarForOldGeneratedCode = tasks.register("scanJarForOldGeneratedCode", io.papermc.paperweight.tasks.ScanJarForOldGeneratedCode::class) { + mcVersion.set(providers.gradleProperty("mcVersion")) + annotation.set("Lio/papermc/paper/generated/GeneratedFrom;") + jarToScan.set(tasks.jar.flatMap { it.archiveFile }) + classpath.from(configurations.compileClasspath) +} +tasks.check { + dependsOn(scanJarForOldGeneratedCode) +} +// Paper end diff --git a/src/main/java/io/papermc/paper/generated/GeneratedFrom.java b/src/main/java/io/papermc/paper/generated/GeneratedFrom.java new file mode 100644 index 0000000000000000000000000000000000000000..2512dba27edfdccbc4430815b6cba048e3d93484 --- /dev/null +++ b/src/main/java/io/papermc/paper/generated/GeneratedFrom.java @@ -0,0 +1,21 @@ +package io.papermc.paper.generated; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.jetbrains.annotations.ApiStatus; + +/** + * Used to mark classes which are generated from + * a specific version of minecraft. + */ +@ApiStatus.Internal +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface GeneratedFrom { + + String value(); +} diff --git a/src/main/java/io/papermc/paper/registry/RegistryKey.java b/src/main/java/io/papermc/paper/registry/RegistryKey.java new file mode 100644 index 0000000000000000000000000000000000000000..7763ea28a00c25ffd8ba8941cff29bae5ae117a2 --- /dev/null +++ b/src/main/java/io/papermc/paper/registry/RegistryKey.java @@ -0,0 +1,149 @@ +package io.papermc.paper.registry; + +import net.kyori.adventure.key.Keyed; +import org.bukkit.Art; +import org.bukkit.Fluid; +import org.bukkit.GameEvent; +import org.bukkit.JukeboxSong; +import org.bukkit.MusicInstrument; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.attribute.Attribute; +import org.bukkit.block.Biome; +import org.bukkit.block.BlockType; +import org.bukkit.block.banner.PatternType; +import org.bukkit.damage.DamageType; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Cat; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Frog; +import org.bukkit.entity.Villager; +import org.bukkit.entity.Wolf; +import org.bukkit.entity.memory.MemoryKey; +import org.bukkit.generator.structure.Structure; +import org.bukkit.generator.structure.StructureType; +import org.bukkit.inventory.ItemType; +import org.bukkit.inventory.MenuType; +import org.bukkit.inventory.meta.trim.TrimMaterial; +import org.bukkit.inventory.meta.trim.TrimPattern; +import org.bukkit.map.MapCursor; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.potion.PotionType; +import org.jetbrains.annotations.ApiStatus; + +import static io.papermc.paper.registry.RegistryKeyImpl.create; + +/** + * Identifier for a specific registry. For use with + * {@link TypedKey} and the registry modification API. + *

+ * There are 2 types of registries, identified as "built-in" + * or "data-driven". The former are not changeable by datapacks (which + * doesn't necessarily mean they aren't changeable in the API) and + * are loaded first. "Data-driven" registries are all created by + * reading in data from the vanilla and other datapacks. + * + * @param the value type + */ +@SuppressWarnings("unused") +public sealed interface RegistryKey extends Keyed permits RegistryKeyImpl { + + /* ******************* * + * Built-in Registries * + * ******************* */ + /** + * Built-in registry for game events + * @see io.papermc.paper.registry.keys.GameEventKeys + */ + RegistryKey GAME_EVENT = create("game_event"); + /** + * Built-in registry for structure types. + * @see io.papermc.paper.registry.keys.StructureTypeKeys + */ + RegistryKey STRUCTURE_TYPE = create("worldgen/structure_type"); + /** + * Built-in registry for instruments. + * @see io.papermc.paper.registry.keys.InstrumentKeys + */ + RegistryKey INSTRUMENT = create("instrument"); + /** + * Built-in registry for potion effect types (mob effects). + * @see io.papermc.paper.registry.keys.MobEffectKeys + */ + RegistryKey MOB_EFFECT = create("mob_effect"); + /** + * @apiNote DO NOT USE + */ + @ApiStatus.Internal + RegistryKey BLOCK = create("block"); + /** + * @apiNote DO NOT USE + */ + @ApiStatus.Internal + RegistryKey ITEM = create("item"); + + + /* ********************** * + * Data-driven Registries * + * ********************** */ + /** + * Data-driven registry for biomes. + * @see io.papermc.paper.registry.keys.BiomeKeys + */ + RegistryKey BIOME = create("worldgen/biome"); + /** + * Data-driven registry for structures. + * @see io.papermc.paper.registry.keys.StructureKeys + */ + RegistryKey STRUCTURE = create("worldgen/structure"); + /** + * Data-driven registry for trim materials. + * @see io.papermc.paper.registry.keys.TrimMaterialKeys + */ + RegistryKey TRIM_MATERIAL = create("trim_material"); + /** + * Data-driven registry for trim patterns. + * @see io.papermc.paper.registry.keys.TrimPatternKeys + */ + RegistryKey TRIM_PATTERN = create("trim_pattern"); + /** + * Data-driven registry for damage types. + * @see io.papermc.paper.registry.keys.DamageTypeKeys + */ + RegistryKey DAMAGE_TYPE = create("damage_type"); + /** + * Data-driven registry for wolf variants. + * @see io.papermc.paper.registry.keys.WolfVariantKeys + */ + RegistryKey WOLF_VARIANT = create("wolf_variant"); + /** + * Data-driven registry for enchantments. + * @see io.papermc.paper.registry.keys.EnchantmentKeys + */ + RegistryKey ENCHANTMENT = create("enchantment"); + /** + * Data-driven registry for jukebox songs. + */ + @ApiStatus.Experimental + RegistryKey JUKEBOX_SONG = create("jukebox_song"); + + + /* ******************* * + * API-only Registries * + * ******************* */ + RegistryKey PAINTING_VARIANT = create("painting_variant"); + RegistryKey ATTRIBUTE = create("attribute"); + RegistryKey BANNER_PATTERN = create("banner_pattern"); + RegistryKey CAT_VARIANT = create("cat_variant"); + RegistryKey ENTITY_TYPE = create("entity_type"); + RegistryKey PARTICLE_TYPE = create("particle_type"); + RegistryKey POTION = create("potion"); + RegistryKey SOUND_EVENT = create("sound_event"); + RegistryKey VILLAGER_PROFESSION = create("villager_profession"); + RegistryKey VILLAGER_TYPE = create("villager_type"); + RegistryKey> MEMORY_MODULE_TYPE = create("memory_module_type"); + RegistryKey FLUID = create("fluid"); + RegistryKey FROG_VARIANT = create("frog_variant"); + RegistryKey MAP_DECORATION_TYPE = create("map_decoration_type"); + RegistryKey MENU = create("menu"); +} diff --git a/src/main/java/io/papermc/paper/registry/RegistryKeyImpl.java b/src/main/java/io/papermc/paper/registry/RegistryKeyImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..791813220b2504214b1adecc69093cd600fb0f8c --- /dev/null +++ b/src/main/java/io/papermc/paper/registry/RegistryKeyImpl.java @@ -0,0 +1,24 @@ +package io.papermc.paper.registry; + +import com.google.common.collect.Sets; +import java.util.Set; +import net.kyori.adventure.key.Key; +import org.intellij.lang.annotations.Subst; +import org.jetbrains.annotations.NotNull; + +record RegistryKeyImpl(@NotNull Key key) implements RegistryKey { + + static final Set> REGISTRY_KEYS = Sets.newIdentityHashSet(); + + static RegistryKey create(@Subst("some_key") final String key) { + final RegistryKey registryKey = createInternal(key); + REGISTRY_KEYS.add(registryKey); + return registryKey; + } + + // creates the key without adding to the internal set of keys + static RegistryKey createInternal(@Subst("some_key") final String key) { + return new RegistryKeyImpl<>(Key.key(Key.MINECRAFT_NAMESPACE, key)); + } + +} diff --git a/src/main/java/io/papermc/paper/registry/TypedKey.java b/src/main/java/io/papermc/paper/registry/TypedKey.java new file mode 100644 index 0000000000000000000000000000000000000000..6f5a062ba7ee7173468ecea3c1855a233bf3855e --- /dev/null +++ b/src/main/java/io/papermc/paper/registry/TypedKey.java @@ -0,0 +1,44 @@ +package io.papermc.paper.registry; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.key.Keyed; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +/** + * Represents a key for a value in a specific registry. + * + * @param the value type for the registry + */ +@ApiStatus.Experimental +public sealed interface TypedKey extends Keyed permits TypedKeyImpl { + + /** + * Gets the key for the value in the registry. + * + * @return the value's key + */ + @Override + @NotNull Key key(); + + /** + * Gets the registry key for the value this key + * represents. + * + * @return the registry key + */ + @NotNull RegistryKey registryKey(); + + /** + * Create a typed key from a key and a registry key. + * + * @param registryKey the registry this key is for + * @param key the key for the value in the registry + * @param value type + * @return a new key for the value key and registry key + */ + @ApiStatus.Experimental + static @NotNull TypedKey create(final @NotNull RegistryKey registryKey, final @NotNull Key key) { + return new TypedKeyImpl<>(key, registryKey); + } +} diff --git a/src/main/java/io/papermc/paper/registry/TypedKeyImpl.java b/src/main/java/io/papermc/paper/registry/TypedKeyImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..1a97b3359c4ece5c29131da7c3f208aaa8fab66e --- /dev/null +++ b/src/main/java/io/papermc/paper/registry/TypedKeyImpl.java @@ -0,0 +1,8 @@ +package io.papermc.paper.registry; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.key.Keyed; +import org.jetbrains.annotations.NotNull; + +record TypedKeyImpl(@NotNull Key key, @NotNull RegistryKey registryKey) implements TypedKey { +} diff --git a/src/main/java/org/bukkit/MinecraftExperimental.java b/src/main/java/org/bukkit/MinecraftExperimental.java index a86b87e4c3332202e40e484c3f9c6562b419c70f..305532968f9f7dd497c77259ed147ea2f081bc74 100644 --- a/src/main/java/org/bukkit/MinecraftExperimental.java +++ b/src/main/java/org/bukkit/MinecraftExperimental.java @@ -47,5 +47,6 @@ public @interface MinecraftExperimental { @ApiStatus.Internal public enum Requires { + BUNDLE, TRADE_REBALANCE // Paper } }