mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-13 02:11:05 +01:00
77a5779e24
Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 2ec53f49 PR-1050: Fix empty result check for Complex Recipes 10671012 PR-1044: Add CrafterCraftEvent 4d87ffe0 Use correct method in JavaDoc ae5e5817 SPIGOT-7850: Add API for Bogged shear state 46b6d445 SPIGOT-7837: Support data pack banner patterns d5d0cefc Fix JavaDoc error b3c2b83d PR-1036: Add API for InventoryView derivatives 1fe2c75a SPIGOT-7809: Add ShieldMeta CraftBukkit Changes: 8ee6fd1b8 SPIGOT-7857: Improve ItemMeta block data deserialization 8f26c30c6 SPIGOT-7857: Fix spurious internal NBT tag when deserializing BlockStateMeta 759061b93 SPIGOT-7855: Fire does not spread or burn blocks 00fc9fb64 SPIGOT-7853: AnvilInventory#getRepairCost() always returns 0 7501e2e04 PR-1450: Add CrafterCraftEvent 8c51673e7 SPIGOT-5731: PortalCreateEvent#getEntity returns null for nether portals ignited by flint and steel d53d0d0b1 PR-1456: Fix inverted logic in CraftCrafterView#setSlotDisabled 682a678c8 SPIGOT-7850: Add API for Bogged shear state fccf5243a SPIGOT-7837: Support data pack banner patterns 9c3bd4390 PR-1431: Add API for InventoryView derivatives 0cc6acbc4 SPIGOT-7849: Fix FoodComponent serialize with "using-converts-to" using null 2c5474952 Don't rely on tags for CraftItemMetas 20d107e46 SPIGOT-7846: Fix ItemMeta for hanging signs 76f59e315 Remove redundant clone in Dropper InventoryMoveItemEvent e61a53d25 SPIGOT-7817: Call InventoryMoveItemEvent for Crafters 894682e2d SPIGOT-7839: Remove redundant Java version checks 2c12b2187 SPIGOT-7809: Add ShieldMeta and fix setting shield base colours Spigot Changes: fb8fb722 Rebuild patches 34bd42b7 SPIGOT-7835: Fix issue with custom hopper settings
370 lines
19 KiB
Diff
370 lines
19 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Riley Park <rileysebastianpark@gmail.com>
|
|
Date: Tue, 16 Jul 2024 14:55:23 -0700
|
|
Subject: [PATCH] Bundle spark
|
|
|
|
|
|
diff --git a/build.gradle.kts b/build.gradle.kts
|
|
index 1a734293c9416f13324bb0edf8f950c9029f8bc4..421f6b3dc8890d63d2e7aa774d0bf8f7e15890ab 100644
|
|
--- a/build.gradle.kts
|
|
+++ b/build.gradle.kts
|
|
@@ -61,6 +61,10 @@ dependencies {
|
|
implementation("io.papermc:reflection-rewriter-runtime:$reflectionRewriterVersion")
|
|
implementation("io.papermc:reflection-rewriter-proxy-generator:$reflectionRewriterVersion")
|
|
// Paper end - Remap reflection
|
|
+ // Paper start - spark
|
|
+ implementation("me.lucko:spark-api:0.1-20240720.200737-2")
|
|
+ implementation("me.lucko:spark-paper:1.10.84-20240720.204128-1")
|
|
+ // Paper end - spark
|
|
}
|
|
|
|
paperweight {
|
|
diff --git a/src/main/java/io/papermc/paper/SparksFly.java b/src/main/java/io/papermc/paper/SparksFly.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..19ee43e1ca053574a0151b4c43b01972183657e6
|
|
--- /dev/null
|
|
+++ b/src/main/java/io/papermc/paper/SparksFly.java
|
|
@@ -0,0 +1,200 @@
|
|
+package io.papermc.paper;
|
|
+
|
|
+import io.papermc.paper.configuration.GlobalConfiguration;
|
|
+import io.papermc.paper.plugin.entrypoint.classloader.group.PaperPluginClassLoaderStorage;
|
|
+import io.papermc.paper.plugin.provider.classloader.ConfiguredPluginClassLoader;
|
|
+import io.papermc.paper.plugin.provider.classloader.PaperClassLoaderStorage;
|
|
+import io.papermc.paper.util.MCUtil;
|
|
+import java.util.List;
|
|
+import java.util.logging.Level;
|
|
+import java.util.logging.Logger;
|
|
+import me.lucko.spark.paper.api.Compatibility;
|
|
+import me.lucko.spark.paper.api.PaperClassLookup;
|
|
+import me.lucko.spark.paper.api.PaperScheduler;
|
|
+import me.lucko.spark.paper.api.PaperSparkModule;
|
|
+import net.kyori.adventure.text.Component;
|
|
+import net.kyori.adventure.text.format.TextColor;
|
|
+import net.minecraft.util.ExceptionCollector;
|
|
+import org.bukkit.Server;
|
|
+import org.bukkit.command.Command;
|
|
+import org.bukkit.command.CommandSender;
|
|
+import org.bukkit.craftbukkit.CraftServer;
|
|
+
|
|
+// It's like electricity.
|
|
+public final class SparksFly {
|
|
+ public static final String ID = "spark";
|
|
+ public static final String COMMAND_NAME = "spark";
|
|
+
|
|
+ private static final String PREFER_SPARK_PLUGIN_PROPERTY = "paper.preferSparkPlugin";
|
|
+
|
|
+ private static final int SPARK_YELLOW = 0xffc93a;
|
|
+
|
|
+ private final Logger logger;
|
|
+ private final PaperSparkModule spark;
|
|
+
|
|
+ private boolean enabled;
|
|
+ private boolean disabledInConfigurationWarningLogged;
|
|
+
|
|
+ public SparksFly(final Server server) {
|
|
+ this.logger = Logger.getLogger(ID);
|
|
+ this.logger.log(Level.INFO, "This server bundles the spark profiler. For more information please visit https://docs.papermc.io/paper/profiling");
|
|
+ this.spark = PaperSparkModule.create(Compatibility.VERSION_1_0, server, this.logger, new PaperScheduler() {
|
|
+ @Override
|
|
+ public void executeAsync(final Runnable runnable) {
|
|
+ MCUtil.scheduleAsyncTask(this.catching(runnable, "asynchronous"));
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void executeSync(final Runnable runnable) {
|
|
+ MCUtil.ensureMain(this.catching(runnable, "synchronous"));
|
|
+ }
|
|
+
|
|
+ private Runnable catching(final Runnable runnable, final String type) {
|
|
+ return () -> {
|
|
+ try {
|
|
+ runnable.run();
|
|
+ } catch (final Throwable t) {
|
|
+ SparksFly.this.logger.log(Level.SEVERE, "An exception was encountered while executing a " + type + " spark task", t);
|
|
+ }
|
|
+ };
|
|
+ }
|
|
+ }, new PaperClassLookup() {
|
|
+ @Override
|
|
+ public Class<?> lookup(final String className) throws Exception {
|
|
+ final ExceptionCollector<ClassNotFoundException> exceptions = new ExceptionCollector<>();
|
|
+ try {
|
|
+ return Class.forName(className);
|
|
+ } catch (final ClassNotFoundException e) {
|
|
+ exceptions.add(e);
|
|
+ for (final ConfiguredPluginClassLoader loader : ((PaperPluginClassLoaderStorage) PaperClassLoaderStorage.instance()).getGlobalGroup().getClassLoaders()) {
|
|
+ try {
|
|
+ final Class<?> loadedClass = loader.loadClass(className, true, false, true);
|
|
+ if (loadedClass != null) {
|
|
+ return loadedClass;
|
|
+ }
|
|
+ } catch (final ClassNotFoundException exception) {
|
|
+ exceptions.add(exception);
|
|
+ }
|
|
+ }
|
|
+ exceptions.throwIfPresent();
|
|
+ return null;
|
|
+ }
|
|
+ }
|
|
+ });
|
|
+ }
|
|
+
|
|
+ public void enableEarlyIfRequested() {
|
|
+ if (!isPluginPreferred() && shouldEnableImmediately()) {
|
|
+ this.enable();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void enableBeforePlugins() {
|
|
+ if (!isPluginPreferred()) {
|
|
+ this.enable();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void enableAfterPlugins(final Server server) {
|
|
+ final boolean isPluginPreferred = isPluginPreferred();
|
|
+ final boolean isPluginEnabled = isPluginEnabled(server);
|
|
+ if (!isPluginPreferred || !isPluginEnabled) {
|
|
+ if (isPluginPreferred && !this.enabled) {
|
|
+ this.logger.log(Level.INFO, "The spark plugin has been preferred but was not loaded. The bundled spark profiler will enabled instead.");
|
|
+ }
|
|
+ this.enable();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private void enable() {
|
|
+ if (!this.enabled) {
|
|
+ if (GlobalConfiguration.get().spark.enabled) {
|
|
+ this.enabled = true;
|
|
+ this.spark.enable();
|
|
+ } else {
|
|
+ if (!this.disabledInConfigurationWarningLogged) {
|
|
+ this.logger.log(Level.INFO, "The spark profiler will not be enabled because it is currently disabled in the configuration.");
|
|
+ this.disabledInConfigurationWarningLogged = true;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void disable() {
|
|
+ if (this.enabled) {
|
|
+ this.spark.disable();
|
|
+ this.enabled = false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void registerCommandBeforePlugins(final Server server) {
|
|
+ if (!isPluginPreferred()) {
|
|
+ this.registerCommand(server);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void registerCommandAfterPlugins(final Server server) {
|
|
+ if ((!isPluginPreferred() || !isPluginEnabled(server)) && server.getCommandMap().getCommand(COMMAND_NAME) == null) {
|
|
+ this.registerCommand(server);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private void registerCommand(final Server server) {
|
|
+ server.getCommandMap().register(COMMAND_NAME, "paper", new CommandImpl(COMMAND_NAME));
|
|
+ }
|
|
+
|
|
+ public void tickStart() {
|
|
+ this.spark.onServerTickStart();
|
|
+ }
|
|
+
|
|
+ public void tickEnd(final double duration) {
|
|
+ this.spark.onServerTickEnd(duration);
|
|
+ }
|
|
+
|
|
+ void executeCommand(final CommandSender sender, final String[] args) {
|
|
+ this.spark.executeCommand(sender, args);
|
|
+ }
|
|
+
|
|
+ List<String> tabComplete(final CommandSender sender, final String[] args) {
|
|
+ return this.spark.tabComplete(sender, args);
|
|
+ }
|
|
+
|
|
+ public static boolean isPluginPreferred() {
|
|
+ return Boolean.getBoolean(PREFER_SPARK_PLUGIN_PROPERTY);
|
|
+ }
|
|
+
|
|
+ private static boolean isPluginEnabled(final Server server) {
|
|
+ return server.getPluginManager().isPluginEnabled(ID);
|
|
+ }
|
|
+
|
|
+ private static boolean shouldEnableImmediately() {
|
|
+ return GlobalConfiguration.get().spark.enableImmediately;
|
|
+ }
|
|
+
|
|
+ public static final class CommandImpl extends Command {
|
|
+ CommandImpl(final String name) {
|
|
+ super(name);
|
|
+ this.setPermission("spark");
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean execute(final CommandSender sender, final String commandLabel, final String[] args) {
|
|
+ final SparksFly spark = ((CraftServer) sender.getServer()).spark;
|
|
+ if (spark.enabled) {
|
|
+ spark.executeCommand(sender, args);
|
|
+ } else {
|
|
+ sender.sendMessage(Component.text("The spark profiler is currently disabled.", TextColor.color(SPARK_YELLOW)));
|
|
+ }
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public List<String> tabComplete(final CommandSender sender, final String alias, final String[] args) throws IllegalArgumentException {
|
|
+ final SparksFly spark = ((CraftServer) sender.getServer()).spark;
|
|
+ if (spark.enabled) {
|
|
+ return spark.tabComplete(sender, args);
|
|
+ }
|
|
+ return List.of();
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/io/papermc/paper/plugin/provider/source/FileProviderSource.java b/src/main/java/io/papermc/paper/plugin/provider/source/FileProviderSource.java
|
|
index 6b8ed8a0baaf4a57d20e57cec3400af5561ddd79..48604e7f96adc9e226e034054c5e2bad0b024eb5 100644
|
|
--- a/src/main/java/io/papermc/paper/plugin/provider/source/FileProviderSource.java
|
|
+++ b/src/main/java/io/papermc/paper/plugin/provider/source/FileProviderSource.java
|
|
@@ -1,6 +1,9 @@
|
|
package io.papermc.paper.plugin.provider.source;
|
|
|
|
+import com.mojang.logging.LogUtils;
|
|
+import io.papermc.paper.SparksFly;
|
|
import io.papermc.paper.plugin.PluginInitializerManager;
|
|
+import io.papermc.paper.plugin.configuration.PluginMeta;
|
|
import io.papermc.paper.plugin.entrypoint.EntrypointHandler;
|
|
import io.papermc.paper.plugin.provider.type.PluginFileType;
|
|
import org.bukkit.plugin.InvalidPluginException;
|
|
@@ -17,12 +20,14 @@ import java.nio.file.attribute.BasicFileAttributes;
|
|
import java.util.Set;
|
|
import java.util.function.Function;
|
|
import java.util.jar.JarFile;
|
|
+import org.slf4j.Logger;
|
|
|
|
/**
|
|
* Loads a plugin provider at the given plugin jar file path.
|
|
*/
|
|
public class FileProviderSource implements ProviderSource<Path, Path> {
|
|
|
|
+ private static final Logger LOGGER = LogUtils.getClassLogger();
|
|
private final Function<Path, String> contextChecker;
|
|
private final boolean applyRemap;
|
|
|
|
@@ -82,6 +87,12 @@ public class FileProviderSource implements ProviderSource<Path, Path> {
|
|
);
|
|
}
|
|
|
|
+ final PluginMeta config = type.getConfig(file);
|
|
+ if ((config.getName().equals("spark") && config.getMainClass().equals("me.lucko.spark.bukkit.BukkitSparkPlugin")) && !SparksFly.isPluginPreferred()) {
|
|
+ LOGGER.info("The spark plugin will not be loaded as this server bundles the spark profiler.");
|
|
+ return;
|
|
+ }
|
|
+
|
|
type.register(entrypointHandler, file, context);
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
index 45695abbeb0a6d47b31b23ba6c464f17e99d7898..23ddd26af762c1cd7fb3920669abb96b3213ab37 100644
|
|
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
@@ -752,6 +752,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
|
// Paper end - Configurable player collision
|
|
|
|
this.server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.POSTWORLD);
|
|
+ this.server.spark.registerCommandBeforePlugins(this.server); // Paper - spark
|
|
+ this.server.spark.enableAfterPlugins(this.server); // Paper - spark
|
|
if (io.papermc.paper.plugin.PluginInitializerManager.instance().pluginRemapper != null) io.papermc.paper.plugin.PluginInitializerManager.instance().pluginRemapper.pluginsEnabled(); // Paper - Remap plugins
|
|
io.papermc.paper.command.brigadier.PaperCommands.INSTANCE.setValid(); // Paper - reset invalid state for event fire below
|
|
io.papermc.paper.plugin.lifecycle.event.LifecycleEventRunner.INSTANCE.callReloadableRegistrarEvent(io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents.COMMANDS, io.papermc.paper.command.brigadier.PaperCommands.INSTANCE, org.bukkit.plugin.Plugin.class, io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.INITIAL); // Paper - call commands event for regular plugins
|
|
@@ -1038,6 +1040,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
|
MinecraftServer.LOGGER.info("Stopping server");
|
|
Commands.COMMAND_SENDING_POOL.shutdownNow(); // Paper - Perf: Async command map building; Shutdown and don't bother finishing
|
|
MinecraftTimings.stopServer(); // Paper
|
|
+ this.server.spark.disable(); // Paper - spark
|
|
// CraftBukkit start
|
|
if (this.server != null) {
|
|
this.server.disablePlugins();
|
|
@@ -1227,6 +1230,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
|
// tasks are default scheduled at -1 + delay, and first tick will tick at 1
|
|
final long actualDoneTimeMs = System.currentTimeMillis() - org.bukkit.craftbukkit.Main.BOOT_TIME.toEpochMilli(); // Paper - Add total time
|
|
LOGGER.info("Done ({})! For help, type \"help\"", String.format(java.util.Locale.ROOT, "%.3fs", actualDoneTimeMs / 1000.00D)); // Paper - Add total time
|
|
+ this.server.spark.enableBeforePlugins(); // Paper - spark
|
|
org.spigotmc.WatchdogThread.tick();
|
|
// Paper end - Improved Watchdog Support
|
|
org.spigotmc.WatchdogThread.hasStarted = true; // Paper
|
|
@@ -1586,6 +1590,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
|
});
|
|
isOversleep = false;MinecraftTimings.serverOversleep.stopTiming();
|
|
// Paper end
|
|
+ this.server.spark.tickStart(); // Paper - spark
|
|
new com.destroystokyo.paper.event.server.ServerTickStartEvent(this.tickCount+1).callEvent(); // Paper - Server Tick Events
|
|
|
|
++this.tickCount;
|
|
@@ -1628,6 +1633,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
|
long endTime = System.nanoTime();
|
|
long remaining = (TICK_TIME - (endTime - lastTick)) - catchupTime;
|
|
new com.destroystokyo.paper.event.server.ServerTickEndEvent(this.tickCount, ((double)(endTime - lastTick) / 1000000D), remaining).callEvent();
|
|
+ this.server.spark.tickEnd(((double)(endTime - lastTick) / 1000000D)); // Paper - spark
|
|
// Paper end - Server Tick Events
|
|
this.profiler.push("tallying");
|
|
long j = Util.getNanos() - i;
|
|
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
|
index d43b98bdfcb00603737a309c0fb7793d42289b8c..dd56c8e041116ef3602a9f89c998c8208ab89b51 100644
|
|
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
|
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
|
@@ -226,6 +226,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
|
this.paperConfigurations.initializeGlobalConfiguration(this.registryAccess());
|
|
this.paperConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess());
|
|
// Paper end - initialize global and world-defaults configuration
|
|
+ this.server.spark.enableEarlyIfRequested(); // Paper - spark
|
|
// Paper start - fix converting txt to json file; convert old users earlier after PlayerList creation but before file load/save
|
|
if (this.convertOldUsers()) {
|
|
this.getProfileCache().save(false); // Paper
|
|
@@ -235,6 +236,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
|
org.spigotmc.WatchdogThread.doStart(org.spigotmc.SpigotConfig.timeoutTime, org.spigotmc.SpigotConfig.restartOnCrash); // Paper - start watchdog thread
|
|
thread.start(); // Paper - Enhance console tab completions for brigadier commands; start console thread after MinecraftServer.console & PaperConfig are initialized
|
|
io.papermc.paper.command.PaperCommands.registerCommands(this); // Paper - setup /paper command
|
|
+ this.server.spark.registerCommandBeforePlugins(this.server); // Paper - spark
|
|
com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Paper - start metrics
|
|
com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // Paper - load version history now
|
|
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
index 3a91faeb6957e4e783b1de3e1145e7d1d164a857..c8b82bc41f2042bb4b067f06265a3a22e51f7629 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
@@ -309,6 +309,7 @@ public final class CraftServer implements Server {
|
|
public static Exception excessiveVelEx; // Paper - Velocity warnings
|
|
private final io.papermc.paper.logging.SysoutCatcher sysoutCatcher = new io.papermc.paper.logging.SysoutCatcher(); // Paper
|
|
private final io.papermc.paper.potion.PaperPotionBrewer potionBrewer; // Paper - Custom Potion Mixes
|
|
+ public final io.papermc.paper.SparksFly spark; // Paper - spark
|
|
|
|
// Paper start - Folia region threading API
|
|
private final io.papermc.paper.threadedregions.scheduler.FallbackRegionScheduler regionizedScheduler = new io.papermc.paper.threadedregions.scheduler.FallbackRegionScheduler();
|
|
@@ -474,6 +475,7 @@ public final class CraftServer implements Server {
|
|
}
|
|
this.potionBrewer = new io.papermc.paper.potion.PaperPotionBrewer(console); // Paper - custom potion mixes
|
|
datapackManager = new io.papermc.paper.datapack.PaperDatapackManager(console.getPackRepository()); // Paper
|
|
+ this.spark = new io.papermc.paper.SparksFly(this); // Paper - spark
|
|
}
|
|
|
|
public boolean getCommandBlockOverride(String command) {
|
|
@@ -1099,6 +1101,7 @@ public final class CraftServer implements Server {
|
|
this.reloadData();
|
|
org.spigotmc.SpigotConfig.registerCommands(); // Spigot
|
|
io.papermc.paper.command.PaperCommands.registerCommands(this.console); // Paper
|
|
+ this.spark.registerCommandBeforePlugins(this); // Paper - spark
|
|
this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*");
|
|
this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions");
|
|
|
|
@@ -1127,6 +1130,7 @@ public final class CraftServer implements Server {
|
|
this.loadPlugins();
|
|
this.enablePlugins(PluginLoadOrder.STARTUP);
|
|
this.enablePlugins(PluginLoadOrder.POSTWORLD);
|
|
+ this.spark.registerCommandAfterPlugins(this); // Paper - spark
|
|
if (io.papermc.paper.plugin.PluginInitializerManager.instance().pluginRemapper != null) io.papermc.paper.plugin.PluginInitializerManager.instance().pluginRemapper.pluginsEnabled(); // Paper - Remap plugins
|
|
// Paper start - brigadier command API
|
|
io.papermc.paper.command.brigadier.PaperCommands.INSTANCE.setValid(); // to clear invalid state for event fire below
|