improve docs

This commit is contained in:
Jake Potrebic 2024-05-12 20:10:55 -07:00
parent 586c8013a4
commit b4589d8248
No known key found for this signature in database
GPG Key ID: ECE0B3C133C016C5
3 changed files with 143 additions and 27 deletions

View File

@ -4,12 +4,27 @@ Date: Sun, 12 May 2024 17:30:54 -0700
Subject: [PATCH] Add datapack registration lifecycle event
diff --git a/src/main/java/io/papermc/paper/datapack/Datapack.java b/src/main/java/io/papermc/paper/datapack/Datapack.java
index 7b2ab0be10a21e0496ad1d485ff8cb2c0b92a2cb..e6037cc5b79b5206e5da8d53c5009932e7c81c86 100644
--- a/src/main/java/io/papermc/paper/datapack/Datapack.java
+++ b/src/main/java/io/papermc/paper/datapack/Datapack.java
@@ -29,4 +29,10 @@ public interface Datapack {
COMPATIBLE,
}
+ /**
+ * Position of the pack in the load order.
+ */
+ enum Position {
+ TOP, BOTTOM
+ }
}
diff --git a/src/main/java/io/papermc/paper/datapack/DatapackRegistrar.java b/src/main/java/io/papermc/paper/datapack/DatapackRegistrar.java
new file mode 100644
index 0000000000000000000000000000000000000000..7eb14d45af846005719f000938cfe1502f995588
index 0000000000000000000000000000000000000000..257999ad95be6be5feb890cc064a3f6c00215bce
--- /dev/null
+++ b/src/main/java/io/papermc/paper/datapack/DatapackRegistrar.java
@@ -0,0 +1,45 @@
@@ -0,0 +1,122 @@
+package io.papermc.paper.datapack;
+
+import io.papermc.paper.plugin.lifecycle.event.registrar.Registrar;
@ -22,44 +37,126 @@ index 0000000000000000000000000000000000000000..7eb14d45af846005719f000938cfe150
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * The registrar for datapacks. The event for this registrar
+ * is called anytime the game tries to discover datapacks at any of the
+ * configured locations. This means that if a datapack should stay available to the server,
+ * it must always be discovered whenever this event fires.
+ * <p>An example of a plugin loading a datapack from within it's own jar is below</p>
+ * <pre>{@code
+ * class YourPluginBootstrap implements PluginBootstrap {
+ * @Override
+ * public void bootstrap(BoostrapContext context) {
+ * final LifecycleEventManager<BootstrapContext> manager = context.getLifecycleManager();
+ * manager.registerEventHandler(LifecycleEvents.DATAPACK_DISCOVERY, event -> {
+ * DatapackRegistrar registrar = event.registrar();
+ * try {
+ * final URI uri = Objects.requireNonNull(
+ * YourPluginBootstrap.class.getResource("/pack")
+ * ).toURI();
+ * registrar.discoverPack(uri, "packId");
+ * } catch (final URISyntaxException | IOException e) {
+ * throw new RuntimeException(e);
+ * }
+ * });
+ * }
+ * }
+ * }</pre>
+ * @see io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents#DATAPACK_DISCOVERY
+ */
+@ApiStatus.NonExtendable
+public interface DatapackRegistrar extends Registrar {
+
+ default void addDatapack(final @NotNull URI uri, final @NotNull String id) throws IOException {
+ this.addDatapack(uri, id, c -> {});
+ /**
+ * Discovers a datapack at the specified {@link URI} with the id.
+ *
+ * @param uri the location of the pack
+ * @param id a unique id
+ * @throws IOException if any IO error occurs
+ */
+ default void discoverPack(final @NotNull URI uri, final @NotNull String id) throws IOException {
+ this.discoverPack(uri, id, c -> {});
+ }
+
+ void addDatapack(@NotNull URI uri, @NotNull String id, Consumer<Configurer> configurer) throws IOException;
+ /**
+ * Discovers a datapack at the specified {@link URI} with the id.
+ *
+ * @param uri the location of the pack
+ * @param id a unique id
+ * @param configurer a configurer for extra options
+ * @throws IOException if any IO error occurs
+ */
+ void discoverPack(@NotNull URI uri, @NotNull String id, Consumer<Configurer> configurer) throws IOException;
+
+ default void addDatapack(final @NotNull Path path, final @NotNull String id) throws IOException {
+ this.addDatapack(path, id, c -> {});
+ /**
+ * Discovers a datapack at the specified {@link Path} with the id.
+ *
+ * @param path the location of the pack
+ * @param id a unique id
+ * @throws IOException if any IO error occurs
+ */
+ default void discoverPack(final @NotNull Path path, final @NotNull String id) throws IOException {
+ this.discoverPack(path, id, c -> {});
+ }
+
+ void addDatapack(@NotNull Path path, @NotNull String id, @NotNull Consumer<Configurer> configurer) throws IOException;
+
+ /**
+ * Discovers a datapack at the specified {@link Path} with the id.
+ *
+ * @param path the location of the pack
+ * @param id a unique id
+ * @param configurer a configurer for extra options
+ * @throws IOException if any IO error occurs
+ */
+ void discoverPack(@NotNull Path path, @NotNull String id, @NotNull Consumer<Configurer> configurer) throws IOException;
+
+ /**
+ * Configures additional, optional, details about a datapack.
+ */
+ @ApiStatus.NonExtendable
+ interface Configurer {
+
+ /**
+ * Changes the title of the datapack from the default which
+ * is just the "id" in the {@code registerPack} methods.
+ *
+ * @param title the new title
+ * @return the configurer for chaining
+ */
+ @Contract(value = "_ -> this", mutates = "this")
+ Configurer title(Component title);
+
+ /**
+ * Sets if this pack is required. Defaults to false.
+ * A required pack cannot be disabled.
+ *
+ * @param required true to require the pack
+ * @return the configurer for chaining
+ */
+ @Contract(value = "_ -> this", mutates = "this")
+ Configurer required(boolean required);
+
+ /**
+ * Configures the position in the
+ * load order of this datapack.
+ *
+ * @param fixed won't move around in the load order as packs are added/removed
+ * @param position try to insert at the top of the order or bottom
+ * @return the configurer for chaining
+ */
+ @Contract(value = "_, _ -> this", mutates = "this")
+ Configurer position(boolean fixed, Position position);
+
+ enum Position {
+ TOP, BOTTOM
+ }
+ Configurer position(boolean fixed, Datapack.Position position);
+ }
+}
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEvents.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEvents.java
index 1fab48593c567fe05b085ac6e12dc22556cf0b92..180b4545ad3693c86a612043c3cb0c4b76248630 100644
index 1fab48593c567fe05b085ac6e12dc22556cf0b92..dcff07f8fe1627662726611602bd0f8213e39133 100644
--- a/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEvents.java
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEvents.java
@@ -5,6 +5,7 @@ import io.papermc.paper.plugin.bootstrap.BootstrapContext;
@@ -1,10 +1,12 @@
package io.papermc.paper.plugin.lifecycle.event.types;
import io.papermc.paper.command.brigadier.Commands;
+import io.papermc.paper.datapack.DatapackRegistrar;
import io.papermc.paper.plugin.bootstrap.BootstrapContext;
import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent;
import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager;
import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner;
@ -67,11 +164,16 @@ index 1fab48593c567fe05b085ac6e12dc22556cf0b92..180b4545ad3693c86a612043c3cb0c4b
import io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.ApiStatus;
@@ -24,6 +25,8 @@ public final class LifecycleEvents {
@@ -24,6 +26,13 @@ public final class LifecycleEvents {
*/
public static final LifecycleEventType.Prioritizable<LifecycleEventOwner, ReloadableRegistrarEvent<Commands>> COMMANDS = prioritized("commands", LifecycleEventOwner.class);
+ public static final LifecycleEventType.Prioritizable<BootstrapContext, RegistrarEvent<io.papermc.paper.datapack.DatapackRegistrar>> DATAPACK_REGISTRATION = prioritized("datapack_registration", BootstrapContext.class);
+ /**
+ * This event is for informing the server about any available datapacks from other sources such as inside a plugin's jar. You
+ * can register a handler for this event only in {@link io.papermc.paper.plugin.bootstrap.PluginBootstrap#bootstrap(BootstrapContext)}.
+ * @see DatapackRegistrar an example of a datapack being discovered
+ */
+ public static final LifecycleEventType.Prioritizable<BootstrapContext, RegistrarEvent<DatapackRegistrar>> DATAPACK_DISCOVERY = prioritized("datapack_discovery", BootstrapContext.class);
+
//<editor-fold desc="helper methods" defaultstate="collapsed">
@ApiStatus.Internal

View File

@ -9,7 +9,7 @@ public net/minecraft/server/packs/repository/FolderRepositorySource$FolderPackDe
diff --git a/src/main/java/io/papermc/paper/datapack/PaperDatapackRegistrarImpl.java b/src/main/java/io/papermc/paper/datapack/PaperDatapackRegistrarImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..d9634a37a9fc5fe4fd1b69a19f013483a0f03828
index 0000000000000000000000000000000000000000..bad03ce8f6a399f9b9903acf41570e471cdc41dc
--- /dev/null
+++ b/src/main/java/io/papermc/paper/datapack/PaperDatapackRegistrarImpl.java
@@ -0,0 +1,120 @@
@ -64,12 +64,12 @@ index 0000000000000000000000000000000000000000..d9634a37a9fc5fe4fd1b69a19f013483
+ }
+
+ @Override
+ public void addDatapack(final URI uri, final String id, final Consumer<Configurer> configurer) throws IOException {
+ this.addDatapack(VanillaPackResourcesBuilder.safeGetPath(uri), id, configurer);
+ public void discoverPack(final URI uri, final String id, final Consumer<Configurer> configurer) throws IOException {
+ this.discoverPack(VanillaPackResourcesBuilder.safeGetPath(uri), id, configurer);
+ }
+
+ @Override
+ public void addDatapack(final Path path, final String id, final Consumer<Configurer> configurer) throws IOException {
+ public void discoverPack(final Path path, final String id, final Consumer<Configurer> configurer) throws IOException {
+ final List<ForbiddenSymlinkInfo> badLinks = new ArrayList<>();
+ final Pack.@Nullable ResourcesSupplier resourcesSupplier = this.detector.detectPackResources(path, badLinks);
+ if (!badLinks.isEmpty()) {
@ -123,7 +123,7 @@ index 0000000000000000000000000000000000000000..d9634a37a9fc5fe4fd1b69a19f013483
+ }
+
+ @Override
+ public Configurer position(final boolean fixed, final Position position) {
+ public Configurer position(final boolean fixed, final Datapack.Position position) {
+ this.fixedPosition = fixed;
+ this.position = switch (position) {
+ case TOP -> Pack.Position.TOP;
@ -135,7 +135,7 @@ index 0000000000000000000000000000000000000000..d9634a37a9fc5fe4fd1b69a19f013483
+}
diff --git a/src/main/java/io/papermc/paper/datapack/PluginDatapackRepositorySource.java b/src/main/java/io/papermc/paper/datapack/PluginDatapackRepositorySource.java
new file mode 100644
index 0000000000000000000000000000000000000000..e4363316480cb18bcb825f1d921daddcd32d7d88
index 0000000000000000000000000000000000000000..b1f0b20c4464de96c416c2d692b3e9e8976b9cfe
--- /dev/null
+++ b/src/main/java/io/papermc/paper/datapack/PluginDatapackRepositorySource.java
@@ -0,0 +1,29 @@
@ -162,7 +162,7 @@ index 0000000000000000000000000000000000000000..e4363316480cb18bcb825f1d921daddc
+
+ @Override
+ public void loadPacks(final Consumer<Pack> packAdder) {
+ LifecycleEventRunner.INSTANCE.callStaticRegistrarEvent(LifecycleEvents.DATAPACK_REGISTRATION,
+ LifecycleEventRunner.INSTANCE.callStaticRegistrarEvent(LifecycleEvents.DATAPACK_DISCOVERY,
+ new PaperDatapackRegistrarImpl(this.validator, packAdder),
+ BootstrapContext.class
+ );
@ -200,6 +200,20 @@ index 0000000000000000000000000000000000000000..dfea23ddde7b929f4d47c5de9539cf8b
+ return true;
+ }
+}
diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventRunner.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventRunner.java
index 6c072e44a8144de6658b4eb818c996f0eac5805b..346c9f8dbeda7c48e88b10964e04a89fa3628661 100644
--- a/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventRunner.java
+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventRunner.java
@@ -27,7 +27,8 @@ public class LifecycleEventRunner {
private static final Logger LOGGER = LogUtils.getClassLogger();
private static final Supplier<Set<LifecycleEventType<?, ?, ?>>> BLOCKS_RELOADING = Suppliers.memoize(() -> Set.of( // lazy due to cyclic initialization
- LifecycleEvents.COMMANDS
+ LifecycleEvents.COMMANDS,
+ LifecycleEvents.DATAPACK_DISCOVERY
));
public static final LifecycleEventRunner INSTANCE = new LifecycleEventRunner();
diff --git a/src/main/java/net/minecraft/server/packs/repository/ServerPacksSource.java b/src/main/java/net/minecraft/server/packs/repository/ServerPacksSource.java
index def8ed40ef732b512a07fe50449c77a860b97462..72c39887631916a7e448123fa793057779e75c53 100644
--- a/src/main/java/net/minecraft/server/packs/repository/ServerPacksSource.java

View File

@ -19,11 +19,11 @@ public class TestPluginBootstrap implements PluginBootstrap {
public void bootstrap(@NotNull BootstrapContext context) {
// io.papermc.testplugin.brigtests.Registration.registerViaBootstrap(context);
final LifecycleEventManager<BootstrapContext> manager = context.getLifecycleManager();
manager.registerEventHandler(LifecycleEvents.DATAPACK_REGISTRATION, event -> {
manager.registerEventHandler(LifecycleEvents.DATAPACK_DISCOVERY, event -> {
final DatapackRegistrar registrar = event.registrar();
try {
final URI uri = Objects.requireNonNull(TestPluginBootstrap.class.getResource("/pack")).toURI();
registrar.addDatapack(uri, "test", text("HEY THERE"));
registrar.discoverPack(uri, "test");
} catch (final URISyntaxException | IOException e) {
throw new RuntimeException(e);
}