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


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..6426f646afdd2a75df89d522068a36cf170d697d
--- /dev/null
+++ b/src/main/java/io/papermc/paper/datapack/PaperDatapack.java
@@ -0,0 +1,51 @@
+package io.papermc.paper.datapack;
+
+import io.papermc.paper.event.server.ServerResourcesReloadedEvent;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.packs.repository.ResourcePackLoader;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class PaperDatapack implements Datapack {
+    private final String name;
+    private final Compatibility compatibility;
+    private final boolean enabled;
+
+    PaperDatapack(ResourcePackLoader loader, boolean enabled) {
+        this.name = loader.getName();
+        this.compatibility = Compatibility.valueOf(loader.getVersion().name());
+        this.enabled = enabled;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public Compatibility getCompatibility() {
+        return compatibility;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        if (enabled == this.enabled) {
+            return;
+        }
+
+        MinecraftServer server = MinecraftServer.getServer();
+        List<String> enabledKeys = server.getResourcePackRepository().getEnabledPacks().stream().map(ResourcePackLoader::getName).collect(Collectors.toList());
+        if (enabled) {
+            enabledKeys.add(this.name);
+        } else {
+            enabledKeys.remove(this.name);
+        }
+        server.reloadServerResources(enabledKeys, ServerResourcesReloadedEvent.Cause.PLUGIN);
+    }
+}
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..378aaeebd7e011565fdc505da68c5b5285339add
--- /dev/null
+++ b/src/main/java/io/papermc/paper/datapack/PaperDatapackManager.java
@@ -0,0 +1,26 @@
+package io.papermc.paper.datapack;
+
+import net.minecraft.server.packs.repository.ResourcePackLoader;
+import net.minecraft.server.packs.repository.ResourcePackRepository;
+
+import java.util.Collection;
+import java.util.stream.Collectors;
+
+public class PaperDatapackManager implements DatapackManager {
+    private final ResourcePackRepository repository;
+
+    public PaperDatapackManager(ResourcePackRepository repository) {
+        this.repository = repository;
+    }
+
+    @Override
+    public Collection<Datapack> getPacks() {
+        Collection<ResourcePackLoader> enabledPacks = repository.getEnabledPacks();
+        return repository.getPacks().stream().map(loader -> new PaperDatapack(loader, enabledPacks.contains(loader))).collect(Collectors.toList());
+    }
+
+    @Override
+    public Collection<Datapack> getEnabledPacks() {
+        return repository.getEnabledPacks().stream().map(loader -> new PaperDatapack(loader, true)).collect(Collectors.toList());
+    }
+}
diff --git a/src/main/java/net/minecraft/server/packs/repository/ResourcePackLoader.java b/src/main/java/net/minecraft/server/packs/repository/ResourcePackLoader.java
index 5c038c02955d8517db0686f3b73c8573d3770466..01c4fda33a138b2d1f6b7c1335378445423a66a9 100644
--- a/src/main/java/net/minecraft/server/packs/repository/ResourcePackLoader.java
+++ b/src/main/java/net/minecraft/server/packs/repository/ResourcePackLoader.java
@@ -102,6 +102,7 @@ public class ResourcePackLoader implements AutoCloseable {
         });
     }
 
+    public final EnumResourcePackVersion getVersion() { return this.c(); } // Paper - OBFHELPER
     public EnumResourcePackVersion c() {
         return this.g;
     }
@@ -110,6 +111,7 @@ public class ResourcePackLoader implements AutoCloseable {
         return (IResourcePack) this.d.get();
     }
 
+    public final String getName() { return this.e(); } // Paper - OBFHELPER
     public String e() {
         return this.c;
     }
diff --git a/src/main/java/net/minecraft/server/packs/repository/ResourcePackRepository.java b/src/main/java/net/minecraft/server/packs/repository/ResourcePackRepository.java
index e87523612d0423d71eab7b9af851c1c268cdf84f..568da9686c41a41e43ede3fe15e0ca53c9688f8b 100644
--- a/src/main/java/net/minecraft/server/packs/repository/ResourcePackRepository.java
+++ b/src/main/java/net/minecraft/server/packs/repository/ResourcePackRepository.java
@@ -88,6 +88,7 @@ public class ResourcePackRepository implements AutoCloseable {
         return this.b.keySet();
     }
 
+    public final Collection<ResourcePackLoader> getPacks() { return this.c(); } // Paper - OBFHELPER
     public Collection<ResourcePackLoader> c() {
         return this.b.values();
     }
@@ -96,6 +97,7 @@ public class ResourcePackRepository implements AutoCloseable {
         return (Collection) this.c.stream().map(ResourcePackLoader::e).collect(ImmutableSet.toImmutableSet());
     }
 
+    public final Collection<ResourcePackLoader> getEnabledPacks() { return this.e(); } // Paper - OBFHELPER
     public Collection<ResourcePackLoader> e() {
         return this.c;
     }
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 706dad235de3b7ffe014f564e1c68f18e1edeefc..89244c152665c97cb539bea07fedd1774ed626f1 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -18,6 +18,7 @@ import com.mojang.serialization.Lifecycle;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.ByteBufOutputStream;
 import io.netty.buffer.Unpooled;
+import io.papermc.paper.datapack.PaperDatapackManager; // Paper
 import io.papermc.paper.util.TraceUtil;
 import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
 import java.awt.image.BufferedImage;
@@ -265,6 +266,7 @@ public final class CraftServer implements Server {
     public boolean ignoreVanillaPermissions = false;
     private final List<CraftPlayer> playerView;
     public int reloadCount;
+    private final PaperDatapackManager datapackManager; // Paper
     public static Exception excessiveVelEx; // Paper - Velocity warnings
 
     static {
@@ -347,6 +349,7 @@ public final class CraftServer implements Server {
         TicketType.PLUGIN.loadPeriod = Math.min(20, configuration.getInt("chunk-gc.period-in-ticks")); // Paper - cap plugin loads to 1 second
         minimumAPI = configuration.getString("settings.minimum-api");
         loadIcon();
+        datapackManager = new PaperDatapackManager(console.getResourcePackRepository()); // Paper
     }
 
     public boolean getCommandBlockOverride(String command) {
@@ -2497,5 +2500,11 @@ public final class CraftServer implements Server {
     public com.destroystokyo.paper.entity.ai.MobGoals getMobGoals() {
         return mobGoals;
     }
+
+    @Override
+    public PaperDatapackManager getDatapackManager() {
+        return datapackManager;
+    }
+
     // Paper end
 }