mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-03 16:04:38 +01:00
8c5b837e05
Firstly, the old methods all routed to the CompletableFuture method. However, the CF method could not guarantee that if the caller was off-main that the future would be "completed" on-main. Since the callback methods used the CF one, this meant that the callback methods did not guarantee that the callbacks were to be called on the main thread. Now, all methods route to getChunkAtAsync(x, z, gen, urgent, cb) so that the methods with the callback are guaranteed to invoke the callback on the main thread. The CF behavior remains unchanged; it may still appear to complete on main if invoked off-main. Secondly, remove the scheduleOnMain invocation in the async chunk completion. This unnecessarily delays the callback by 1 tick. Thirdly, add getChunksAtAsync(minX, minZ, maxX, maxZ, ...) which will load chunks within an area. This method is provided as a helper as keeping all chunks loaded within an area can be complicated to implement for plugins (due to the lacking ticket API), and is already implemented internally anyways. Fourthly, remove the ticket addition that occured with getChunkAt and getChunkAtAsync. The ticket addition may delay the unloading of the chunk unnecessarily. It also fixes a very rare timing bug where the future/callback would be completed after the chunk unloads.
210 lines
7.9 KiB
Diff
210 lines
7.9 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
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
|
|
index 0000000000000000000000000000000000000000..8bd8263b51fb2bb364353565b1ba26b3b0d1d55e
|
|
--- /dev/null
|
|
+++ b/src/main/java/io/papermc/paper/datapack/PaperDatapack.java
|
|
@@ -0,0 +1,103 @@
|
|
+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 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 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(final Pack pack, final boolean enabled) {
|
|
+ this.pack = pack;
|
|
+ this.enabled = enabled;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public String getName() {
|
|
+ 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 Datapack.Compatibility.valueOf(this.pack.getCompatibility().name());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Set<FeatureFlag> getRequiredFeatures() {
|
|
+ return PaperFeatureFlagProviderImpl.fromNms(this.pack.getRequestedFeatures());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isEnabled() {
|
|
+ return this.enabled;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ 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;
|
|
+ }
|
|
+ if (enabled) {
|
|
+ packToChange.getDefaultPosition().insert(enabledPacks, packToChange, Pack::selectionConfig, false); // modeled off the default /datapack enable logic
|
|
+ } else {
|
|
+ enabledPacks.remove(packToChange);
|
|
+ }
|
|
+ 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
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..caa41c525d2b36b5a9f9942380f06c97d5781a93
|
|
--- /dev/null
|
|
+++ b/src/main/java/io/papermc/paper/datapack/PaperDatapackManager.java
|
|
@@ -0,0 +1,55 @@
|
|
+package io.papermc.paper.datapack;
|
|
+
|
|
+import com.google.common.collect.Collections2;
|
|
+import java.util.Collection;
|
|
+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(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() {
|
|
+ final Collection<Pack> enabledPacks = this.repository.getSelectedPacks();
|
|
+ return this.transformPacks(this.repository.getAvailablePacks(), enabledPacks::contains);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Collection<Datapack> getEnabledPacks() {
|
|
+ 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
|
|
index 3cfacacd1d8fd17ec4b54936afd8124823b1a00b..b4af066a21e4893b5ec146d109b5146b6996a0cf 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
@@ -308,6 +308,7 @@ public final class CraftServer implements Server {
|
|
private final List<CraftPlayer> playerView;
|
|
public int reloadCount;
|
|
public Set<String> activeCompatibilities = Collections.emptySet();
|
|
+ private final io.papermc.paper.datapack.PaperDatapackManager datapackManager; // Paper
|
|
public static Exception excessiveVelEx; // Paper - Velocity warnings
|
|
|
|
static {
|
|
@@ -392,6 +393,7 @@ public final class CraftServer implements Server {
|
|
if (this.configuration.getBoolean("settings.use-map-color-cache")) {
|
|
MapPalette.setMapColorCache(new CraftMapColorCache(this.logger));
|
|
}
|
|
+ datapackManager = new io.papermc.paper.datapack.PaperDatapackManager(console.getPackRepository()); // Paper
|
|
}
|
|
|
|
public boolean getCommandBlockOverride(String command) {
|
|
@@ -3036,5 +3038,11 @@ public final class CraftServer implements Server {
|
|
public com.destroystokyo.paper.entity.ai.MobGoals getMobGoals() {
|
|
return mobGoals;
|
|
}
|
|
+
|
|
+ @Override
|
|
+ public io.papermc.paper.datapack.PaperDatapackManager getDatapackManager() {
|
|
+ return datapackManager;
|
|
+ }
|
|
+
|
|
// Paper end
|
|
}
|