mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-29 15:49:00 +01:00
Expand out datapack API (#10828)
* Expand out datapack API * add getTitle * better enable check
This commit is contained in:
parent
8f59e0a8a4
commit
802cb228d7
2 changed files with 248 additions and 34 deletions
|
@ -3,6 +3,7 @@ From: Connor Linfoot <connorlinfoot@me.com>
|
|||
Date: Sun, 16 May 2021 15:07:34 +0100
|
||||
Subject: [PATCH] Add basic Datapack API
|
||||
|
||||
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/datapack/Datapack.java b/src/main/java/io/papermc/paper/datapack/Datapack.java
|
||||
new file mode 100644
|
||||
|
@ -12,35 +13,101 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.datapack;
|
||||
+
|
||||
+import java.util.Set;
|
||||
+import net.kyori.adventure.text.Component;
|
||||
+import org.bukkit.FeatureFlag;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.jetbrains.annotations.Contract;
|
||||
+import org.jetbrains.annotations.Unmodifiable;
|
||||
+
|
||||
+/**
|
||||
+ * This is a snapshot of a datapack on the server. It
|
||||
+ * won't be updated as datapacks are updated.
|
||||
+ */
|
||||
+public interface Datapack {
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the name/id of this datapack.
|
||||
+ *
|
||||
+ * @return the name of the pack
|
||||
+ */
|
||||
+ @NonNull
|
||||
+ String getName();
|
||||
+ @Contract(pure = true)
|
||||
+ @NonNull String getName();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the title component of this datapack.
|
||||
+ *
|
||||
+ * @return the title
|
||||
+ */
|
||||
+ @NonNull Component getTitle();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the description component of this datapack.
|
||||
+ *
|
||||
+ * @return the description
|
||||
+ */
|
||||
+ @NonNull Component getDescription();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets if this datapack is required to be enabled.
|
||||
+ *
|
||||
+ * @return true if the pack is required
|
||||
+ */
|
||||
+ boolean isRequired();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the compatibility status of this pack.
|
||||
+ *
|
||||
+ * @return the compatibility of the pack
|
||||
+ */
|
||||
+ @NonNull
|
||||
+ Compatibility getCompatibility();
|
||||
+ @NonNull Compatibility getCompatibility();
|
||||
+
|
||||
+ /**
|
||||
+ * @return whether or not the pack is currently enabled
|
||||
+ * Gets the set of required features for this datapack.
|
||||
+ *
|
||||
+ * @return the set of required features
|
||||
+ */
|
||||
+ @NonNull @Unmodifiable Set<FeatureFlag> getRequiredFeatures();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the enabled state of this pack.
|
||||
+ *
|
||||
+ * @return whether the pack is currently enabled
|
||||
+ */
|
||||
+ boolean isEnabled();
|
||||
+
|
||||
+ /**
|
||||
+ * Changes the enabled state of this pack. Will
|
||||
+ * cause a reload of resources ({@code /minecraft:reload}) if
|
||||
+ * any change happens.
|
||||
+ *
|
||||
+ * @param enabled true to enable, false to disable
|
||||
+ * @apiNote This method may be deprecated in the future as setters on a "snapshot" type are undesirable.
|
||||
+ */
|
||||
+ void setEnabled(boolean enabled);
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the source for this datapack.
|
||||
+ *
|
||||
+ * @return the pack source
|
||||
+ */
|
||||
+ @NonNull DatapackSource getSource();
|
||||
+
|
||||
+ /**
|
||||
+ * Computes the component vanilla Minecraft uses
|
||||
+ * to display this datapack. Includes the {@link #getSource()},
|
||||
+ * {@link #getDescription()}, {@link #getName()}, and the enabled state.
|
||||
+ *
|
||||
+ * @return a new component
|
||||
+ */
|
||||
+ @Contract(pure = true, value = "-> new")
|
||||
+ @NonNull Component computeDisplayName();
|
||||
+
|
||||
+ enum Compatibility {
|
||||
+ TOO_OLD,
|
||||
+ TOO_NEW,
|
||||
+ COMPATIBLE,
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/datapack/DatapackManager.java b/src/main/java/io/papermc/paper/datapack/DatapackManager.java
|
||||
new file mode 100644
|
||||
|
@ -53,21 +120,84 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+
|
||||
+import java.util.Collection;
|
||||
+import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
+import org.jetbrains.annotations.Unmodifiable;
|
||||
+
|
||||
+public interface DatapackManager {
|
||||
+
|
||||
+ /**
|
||||
+ * @return all the packs known to the server
|
||||
+ * Triggers a refresh of the available and selected datapacks. This
|
||||
+ * can find new datapacks, remove old ones, and update the metadata for
|
||||
+ * existing datapacks. Some of these changes will only take effect
|
||||
+ * after the next {@link org.bukkit.Server#reloadData()} or {@code /minecraft:reload}.
|
||||
+ */
|
||||
+ @NonNull
|
||||
+ Collection<Datapack> getPacks();
|
||||
+ void refreshPacks();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets a datapack by name. May require calling {@link #refreshPacks()} before
|
||||
+ * to get the latest pack information.
|
||||
+ *
|
||||
+ * @param name the name/id of the datapack
|
||||
+ * @return the datapack, or null if not found
|
||||
+ */
|
||||
+ @Nullable Datapack getPack(@NonNull String name);
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the available datapacks. May require calling {@link #refreshPacks()} before
|
||||
+ * to get the latest pack information.
|
||||
+ *
|
||||
+ * @return all the packs known to the server
|
||||
+ */
|
||||
+ @NonNull @Unmodifiable Collection<Datapack> getPacks();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the enabled datapacks. May require calling {@link #refreshPacks()} before
|
||||
+ * to get the latest pack information.
|
||||
+ *
|
||||
+ * @return all the packs which are currently enabled
|
||||
+ */
|
||||
+ @NonNull
|
||||
+ Collection<Datapack> getEnabledPacks();
|
||||
+ @NonNull @Unmodifiable Collection<Datapack> getEnabledPacks();
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/datapack/DatapackSource.java b/src/main/java/io/papermc/paper/datapack/DatapackSource.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/datapack/DatapackSource.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.datapack;
|
||||
+
|
||||
+/**
|
||||
+ * Source of a datapack.
|
||||
+ */
|
||||
+public sealed interface DatapackSource permits DatapackSourceImpl {
|
||||
+
|
||||
+ DatapackSource DEFAULT = create("default");
|
||||
+ DatapackSource BUILT_IN = create("built_in");
|
||||
+ DatapackSource FEATURE = create("feature");
|
||||
+ DatapackSource WORLD = create("world");
|
||||
+ DatapackSource SERVER = create("server");
|
||||
+
|
||||
+ private static DatapackSource create(final String name) {
|
||||
+ return new DatapackSourceImpl(name);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/datapack/DatapackSourceImpl.java b/src/main/java/io/papermc/paper/datapack/DatapackSourceImpl.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/datapack/DatapackSourceImpl.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.datapack;
|
||||
+
|
||||
+import org.jetbrains.annotations.ApiStatus;
|
||||
+
|
||||
+@ApiStatus.Internal
|
||||
+record DatapackSourceImpl(String name) implements DatapackSource {
|
||||
+
|
||||
+ @Override
|
||||
+ public String toString() {
|
||||
+ return this.name;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
|
|
|
@ -3,6 +3,7 @@ From: Connor Linfoot <connorlinfoot@me.com>
|
|||
Date: Sun, 16 May 2021 15:07:34 +0100
|
||||
Subject: [PATCH] Add basic Datapack API
|
||||
|
||||
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/datapack/PaperDatapack.java b/src/main/java/io/papermc/paper/datapack/PaperDatapack.java
|
||||
new file mode 100644
|
||||
|
@ -12,52 +13,105 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.datapack;
|
||||
+
|
||||
+import io.papermc.paper.adventure.PaperAdventure;
|
||||
+import io.papermc.paper.event.server.ServerResourcesReloadedEvent;
|
||||
+import io.papermc.paper.world.flag.PaperFeatureFlagProviderImpl;
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.List;
|
||||
+import java.util.Map;
|
||||
+import java.util.Set;
|
||||
+import java.util.concurrent.ConcurrentHashMap;
|
||||
+import net.kyori.adventure.text.Component;
|
||||
+import net.minecraft.server.MinecraftServer;
|
||||
+import net.minecraft.server.packs.repository.Pack;
|
||||
+import java.util.List;
|
||||
+import java.util.stream.Collectors;
|
||||
+import net.minecraft.server.packs.repository.PackSource;
|
||||
+import org.bukkit.FeatureFlag;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public class PaperDatapack implements Datapack {
|
||||
+ private final String name;
|
||||
+ private final Compatibility compatibility;
|
||||
+
|
||||
+ private static final Map<PackSource, DatapackSource> PACK_SOURCES = new ConcurrentHashMap<>();
|
||||
+ static {
|
||||
+ PACK_SOURCES.put(PackSource.DEFAULT, DatapackSource.DEFAULT);
|
||||
+ PACK_SOURCES.put(PackSource.BUILT_IN, DatapackSource.BUILT_IN);
|
||||
+ PACK_SOURCES.put(PackSource.FEATURE, DatapackSource.FEATURE);
|
||||
+ PACK_SOURCES.put(PackSource.WORLD, DatapackSource.WORLD);
|
||||
+ PACK_SOURCES.put(PackSource.SERVER, DatapackSource.SERVER);
|
||||
+ }
|
||||
+
|
||||
+ private final Pack pack;
|
||||
+ private final boolean enabled;
|
||||
+
|
||||
+ PaperDatapack(Pack loader, boolean enabled) {
|
||||
+ this.name = loader.getId();
|
||||
+ this.compatibility = Compatibility.valueOf(loader.getCompatibility().name());
|
||||
+ PaperDatapack(final Pack pack, final boolean enabled) {
|
||||
+ this.pack = pack;
|
||||
+ this.enabled = enabled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String getName() {
|
||||
+ return name;
|
||||
+ return this.pack.getId();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Component getTitle() {
|
||||
+ return PaperAdventure.asAdventure(this.pack.getTitle());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Component getDescription() {
|
||||
+ return PaperAdventure.asAdventure(this.pack.getDescription());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isRequired() {
|
||||
+ return this.pack.isRequired();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Compatibility getCompatibility() {
|
||||
+ return compatibility;
|
||||
+ return Datapack.Compatibility.valueOf(this.pack.getCompatibility().name());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Set<FeatureFlag> getRequiredFeatures() {
|
||||
+ return PaperFeatureFlagProviderImpl.fromNms(this.pack.getRequestedFeatures());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isEnabled() {
|
||||
+ return enabled;
|
||||
+ return this.enabled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setEnabled(boolean enabled) {
|
||||
+ if (enabled == this.enabled) {
|
||||
+ public void setEnabled(final boolean enabled) {
|
||||
+ final MinecraftServer server = MinecraftServer.getServer();
|
||||
+ final List<Pack> enabledPacks = new ArrayList<>(server.getPackRepository().getSelectedPacks());
|
||||
+ final @Nullable Pack packToChange = server.getPackRepository().getPack(this.getName());
|
||||
+ if (packToChange == null) {
|
||||
+ throw new IllegalStateException("Cannot toggle state of pack that doesn't exist: " + this.getName());
|
||||
+ }
|
||||
+ if (enabled == enabledPacks.contains(packToChange)) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ MinecraftServer server = MinecraftServer.getServer();
|
||||
+ List<String> enabledKeys = server.getPackRepository().getSelectedPacks().stream().map(Pack::getId).collect(Collectors.toList());
|
||||
+ if (enabled) {
|
||||
+ enabledKeys.add(this.name);
|
||||
+ packToChange.getDefaultPosition().insert(enabledPacks, packToChange, Pack::selectionConfig, false); // modeled off the default /datapack enable logic
|
||||
+ } else {
|
||||
+ enabledKeys.remove(this.name);
|
||||
+ enabledPacks.remove(packToChange);
|
||||
+ }
|
||||
+ server.reloadResources(enabledKeys, ServerResourcesReloadedEvent.Cause.PLUGIN);
|
||||
+ server.reloadResources(enabledPacks.stream().map(Pack::getId).toList(), ServerResourcesReloadedEvent.Cause.PLUGIN);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public DatapackSource getSource() {
|
||||
+ return PACK_SOURCES.computeIfAbsent(this.pack.location().source(), source -> new DatapackSourceImpl(source.toString()));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Component computeDisplayName() {
|
||||
+ return PaperAdventure.asAdventure(this.pack.getChatLink(this.enabled));
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/datapack/PaperDatapackManager.java b/src/main/java/io/papermc/paper/datapack/PaperDatapackManager.java
|
||||
|
@ -68,27 +122,57 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.datapack;
|
||||
+
|
||||
+import com.google.common.collect.Collections2;
|
||||
+import java.util.Collection;
|
||||
+import java.util.stream.Collectors;
|
||||
+import java.util.Collections;
|
||||
+import java.util.function.Predicate;
|
||||
+import net.minecraft.server.packs.repository.Pack;
|
||||
+import net.minecraft.server.packs.repository.PackRepository;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public class PaperDatapackManager implements DatapackManager {
|
||||
+
|
||||
+ private final PackRepository repository;
|
||||
+
|
||||
+ public PaperDatapackManager(PackRepository repository) {
|
||||
+ public PaperDatapackManager(final PackRepository repository) {
|
||||
+ this.repository = repository;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void refreshPacks() {
|
||||
+ this.repository.reload();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @Nullable Datapack getPack(final @NonNull String name) {
|
||||
+ final @Nullable Pack pack = this.repository.getPack(name);
|
||||
+ if (pack == null) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ return new PaperDatapack(pack, this.repository.getSelectedPacks().contains(pack));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Collection<Datapack> getPacks() {
|
||||
+ Collection<Pack> enabledPacks = repository.getSelectedPacks();
|
||||
+ return repository.getAvailablePacks().stream().map(loader -> new PaperDatapack(loader, enabledPacks.contains(loader))).collect(Collectors.toList());
|
||||
+ final Collection<Pack> enabledPacks = this.repository.getSelectedPacks();
|
||||
+ return this.transformPacks(this.repository.getAvailablePacks(), enabledPacks::contains);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Collection<Datapack> getEnabledPacks() {
|
||||
+ return repository.getSelectedPacks().stream().map(loader -> new PaperDatapack(loader, true)).collect(Collectors.toList());
|
||||
+ return this.transformPacks(this.repository.getSelectedPacks(), pack -> true);
|
||||
+ }
|
||||
+
|
||||
+ private Collection<Datapack> transformPacks(final Collection<Pack> packs, final Predicate<Pack> enabled) {
|
||||
+ return Collections.unmodifiableCollection(
|
||||
+ Collections2.transform(
|
||||
+ packs,
|
||||
+ pack -> new PaperDatapack(pack, enabled.test(pack))
|
||||
+ )
|
||||
+ );
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
|
|
Loading…
Reference in a new issue