From 63cde5caa5d68834ae80a4ec37289452b1404bbf Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Sat, 29 Jun 2019 16:36:58 +1000
Subject: [PATCH] SPIGOT-5106: Config option to prevent plugins with
 incompatible API's from loading

---
 .../org/bukkit/craftbukkit/CraftServer.java   |  3 +++
 .../craftbukkit/util/CraftMagicNumbers.java   | 21 +++++++++++++++++--
 src/main/resources/configurations/bukkit.yml  |  1 +
 3 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index a6a6fba26a..faeb4bc468 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -220,6 +220,7 @@ public final class CraftServer implements Server {
     private int ambientSpawn = -1;
     private File container;
     private WarningState warningState = WarningState.DEFAULT;
+    public String minimumAPI;
     public CraftScoreboardManager scoreboardManager;
     public boolean playerCommandState;
     private boolean printSaveWarning;
@@ -305,6 +306,7 @@ public final class CraftServer implements Server {
         ambientSpawn = configuration.getInt("spawn-limits.ambient");
         console.autosavePeriod = configuration.getInt("ticks-per.autosave");
         warningState = WarningState.value(configuration.getString("settings.deprecated-verbose"));
+        minimumAPI = configuration.getString("settings.minimum-api");
         loadIcon();
     }
 
@@ -714,6 +716,7 @@ public final class CraftServer implements Server {
         waterAnimalSpawn = configuration.getInt("spawn-limits.water-animals");
         ambientSpawn = configuration.getInt("spawn-limits.ambient");
         warningState = WarningState.value(configuration.getString("settings.deprecated-verbose"));
+        minimumAPI = configuration.getString("settings.minimum-api");
         printSaveWarning = false;
         console.autosavePeriod = configuration.getInt("ticks-per.autosave");
         loadIcon();
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
index 7ae4e7288b..8b6ec888e8 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
@@ -8,8 +8,10 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
 import com.mojang.datafixers.Dynamic;
 import java.io.File;
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.logging.Level;
@@ -245,14 +247,29 @@ public final class CraftMagicNumbers implements UnsafeValues {
         return file.delete();
     }
 
+    private static final List<String> SUPPORTED_API = Arrays.asList("1.13", "1.14");
+
     @Override
     public void checkSupported(PluginDescriptionFile pdf) throws InvalidPluginException {
+        String minimumVersion = MinecraftServer.getServer().server.minimumAPI;
+        int minimumIndex = SUPPORTED_API.indexOf(minimumVersion);
+
         if (pdf.getAPIVersion() != null) {
-            if (!pdf.getAPIVersion().equals("1.13") && !pdf.getAPIVersion().equals("1.14")) {
+            int pluginIndex = SUPPORTED_API.indexOf(pdf.getAPIVersion());
+
+            if (pluginIndex == -1) {
                 throw new InvalidPluginException("Unsupported API version " + pdf.getAPIVersion());
             }
+
+            if (pluginIndex < minimumIndex) {
+                throw new InvalidPluginException("Plugin API version " + pdf.getAPIVersion() + " is lower than the minimum allowed version. Please update or replace it.");
+            }
         } else {
-            Bukkit.getLogger().log(Level.WARNING, "Plugin " + pdf.getFullName() + " does not specify an api-version.");
+            if (minimumIndex == -1) {
+                Bukkit.getLogger().log(Level.WARNING, "Plugin " + pdf.getFullName() + " does not specify an api-version.");
+            } else {
+                throw new InvalidPluginException("Plugin API version " + pdf.getAPIVersion() + " is lower than the minimum allowed version. Please update or replace it.");
+            }
         }
     }
 
diff --git a/src/main/resources/configurations/bukkit.yml b/src/main/resources/configurations/bukkit.yml
index e75ad475b7..43502ae9a3 100644
--- a/src/main/resources/configurations/bukkit.yml
+++ b/src/main/resources/configurations/bukkit.yml
@@ -22,6 +22,7 @@ settings:
     query-plugins: true
     deprecated-verbose: default
     shutdown-message: Server closed
+    minimum-api: none
 spawn-limits:
     monsters: 70
     animals: 10