PaperMC/patches/server/1046-Bundle-spark.patch

372 lines
19 KiB
Diff
Raw Normal View History

2024-07-20 18:35:39 +02:00
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
2024-10-26 17:49:28 +02:00
index 9966576652ed6007d2228237f292c1dc83ede485..9b3a6b336cb1344d4e74e0e4f7c50ffd1e1b8955 100644
2024-07-20 18:35:39 +02:00
--- a/build.gradle.kts
+++ b/build.gradle.kts
Updated Upstream (Bukkit/CraftBukkit) (#11501) 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: bb4e97c6 Add support for Java 23 bc6874dd Bump asm to 9.7.1 50e8a00b PR-1064: Add specific getTopInventory methods for InventoryView derivatives 758b0a0f SPIGOT-7911: Fix Location#isWorldLoaded() for re-loaded worlds 133a64a7 Improve Registry#getOrThrow messages be0f5957 PR-1058: Add tests for Minecraft registry <-> Bukkit fields d1b31df2 PR-1062: Clarify BeaconView documentation 3fab4384 PR-1060: Cache Material to BlockType and ItemType conversion 967a7301 SPIGOT-7906: Increase YAML nesting limit to 100 6ecf033d SPIGOT-7899: Smithing recipes don't require inputs CraftBukkit Changes: 0a7bd6c81 PR-1493: Improve reroute performance and add some tests 54941524c Add support for Java 23 f4d957fff SPIGOT-7915: Fix World#getKeepSpawnInMemory() using Spawn Radius rather than Spawn Chunk Radius ded183674 Fix HIDE_ENCHANTS flag in items without enchantments 308785a0a Bump asm to 9.7.1 and re-add ClassReader to ClassWriter 72ce823cd PR-1487: Add specific getTopInventory methods for InventoryView derivatives 11a5e840c SPIGOT-7907, PR-1484: Improve merchant recipe item matching behavior to more closely align with older versions 45b66f7e4 SPIGOT-7909: Always set HIDE_ENCHANTS flag to item if flag is set 963459791 Increase outdated build delay fc5b2d75f SPIGOT-7910: Fix launching breeze wind charge from API and improve dispenser launch API c7d6428f2 SPIGOT-7856, PR-1483: End platform not dropping items after replacing blocks 2a5572b52 SPIGOT-7780, PR-1482: Cannot edit chunks during unload event 527041ab5 SPIGOT-7902, PR-1477: Fix CraftMetaPotion#hasCustomEffects() does not check if customEffects (List) is empty 5529a1769 Implement base methods for tags 30fbdbaaf Improve Registry#getOrThrow messages 6b71a7322 PR-1475: Add tests for Minecraft registry <-> Bukkit fields 5f24c255c SPIGOT-7908: Mark junit-platform-suite-engine as test scope e4c92ef65 PR-1473: Change tests to use suites, to run tests in different environments and feature flags d25e1e722 PR-1481: Fix BeaconView#set[X]Effect(null) d69a05362 PR-1480: Fix PerMaterialTest#isEdible test running for legacy materials bb3284a89 PR-1479: Use custom #isBlock method in legacy init instead of the one in Material, since it relies on legacy being init 98c57cbbe SPIGOT-7904: Fix NPE for PlayerItemBreakEvent f35bae9ec Fix missing hasJukeboxPlayable 8a6f8b6d8 SPIGOT-7881: CTRL+Pick Block saves position data into item 7913b3be7 SPIGOT-7899: Smithing recipes don't require inputs
2024-10-21 00:06:54 +02:00
@@ -62,6 +62,10 @@ dependencies {
2024-07-20 18:35:39 +02:00
implementation("io.papermc:reflection-rewriter-runtime:$reflectionRewriterVersion")
implementation("io.papermc:reflection-rewriter-proxy-generator:$reflectionRewriterVersion")
// Paper end - Remap reflection
+ // Paper start - spark
2024-07-20 22:56:37 +02:00
+ implementation("me.lucko:spark-api:0.1-20240720.200737-2")
2024-09-12 19:54:34 +02:00
+ implementation("me.lucko:spark-paper:1.10.105-SNAPSHOT")
2024-07-20 18:35:39 +02:00
+ // 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..2955b7ec9832a5752ea4aff9fc9d34ae2f9ee83e
2024-07-20 18:35:39 +02:00
--- /dev/null
+++ b/src/main/java/io/papermc/paper/SparksFly.java
@@ -0,0 +1,201 @@
2024-07-20 18:35:39 +02:00
+package io.papermc.paper;
+
+import io.papermc.paper.configuration.GlobalConfiguration;
2024-07-20 22:56:37 +02:00
+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;
2024-07-20 18:35:39 +02:00
+import io.papermc.paper.util.MCUtil;
+import java.util.Collection;
2024-07-20 18:35:39 +02:00
+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;
2024-07-20 22:56:37 +02:00
+import net.minecraft.util.ExceptionCollector;
2024-07-20 18:35:39 +02:00
+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";
+
2024-07-20 18:35:39 +02:00
+ 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 {
2024-07-20 22:56:37 +02:00
+ final ExceptionCollector<ClassNotFoundException> exceptions = new ExceptionCollector<>();
+ try {
+ return Class.forName(className);
2024-07-20 22:56:37 +02:00
+ } 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);
+ }
+ }
2024-07-20 22:56:37 +02:00
+ exceptions.throwIfPresent();
+ return null;
+ }
2024-07-20 18:35:39 +02:00
+ }
+ });
+ }
+
+ 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, this.spark.getPermissions()));
2024-07-20 18:35:39 +02:00
+ }
+
+ 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);
2024-07-20 18:35:39 +02:00
+ }
+
+ 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, final Collection<String> permissions) {
2024-07-20 18:35:39 +02:00
+ super(name);
+ this.setPermission(String.join(";", permissions));
2024-07-20 18:35:39 +02:00
+ }
+
+ @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
2024-10-26 17:49:28 +02:00
index 79f3dc4f53dce892c4756b0850352e0ca2eb95a6..de80ac827c8ac3630d68b73cb425d4b56f7d2cd7 100644
2024-07-20 18:35:39 +02:00
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
2024-10-26 17:49:28 +02:00
@@ -766,6 +766,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2024-07-20 18:35:39 +02:00
// 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
2024-10-26 17:49:28 +02:00
@@ -1052,6 +1054,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2024-07-20 18:35:39 +02:00
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();
2024-10-26 17:49:28 +02:00
@@ -1247,6 +1250,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2024-07-20 18:35:39 +02:00
// 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
2024-10-26 17:49:28 +02:00
@@ -1660,6 +1664,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2024-07-20 18:35:39 +02:00
});
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;
2024-10-26 17:49:28 +02:00
@@ -1687,6 +1692,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2024-07-20 18:35:39 +02:00
long remaining = (TICK_TIME - (endTime - lastTick)) - catchupTime;
new com.destroystokyo.paper.event.server.ServerTickEndEvent(this.tickCount, ((double)(endTime - lastTick) / 1000000D), remaining).callEvent();
// Paper end - Server Tick Events
2024-10-26 17:49:28 +02:00
+ this.server.spark.tickEnd(((double)(endTime - lastTick) / 1000000D)); // Paper - spark
gameprofilerfiller.push("tallying");
long k = Util.getNanos() - i;
int l = this.tickCount % 100;
2024-07-20 18:35:39 +02:00
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
2024-10-26 17:49:28 +02:00
index 7a79541db29cc47c844d617fc8a4360f61c73372..f8ee4b6c481d3fe15f48bf4a93696dd23e4f01a4 100644
2024-07-20 18:35:39 +02:00
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
2024-10-26 17:49:28 +02:00
@@ -225,6 +225,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
2024-07-20 18:35:39 +02:00
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
2024-10-26 17:49:28 +02:00
@@ -234,6 +235,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
2024-07-20 18:35:39 +02:00
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
2024-10-26 17:49:28 +02:00
index a34e40e273a79a234c3d79b6ad360ce3a4d35ba3..742d4cd3b42c1f4807c8ecb27ffa6df905d7f0ac 100644
2024-07-20 18:35:39 +02:00
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
2024-10-26 17:49:28 +02:00
@@ -312,6 +312,7 @@ public final class CraftServer implements Server {
2024-07-20 18:35:39 +02:00
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();
2024-10-26 17:49:28 +02:00
@@ -478,6 +479,7 @@ public final class CraftServer implements Server {
2024-07-20 18:35:39 +02:00
}
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) {
2024-10-26 17:49:28 +02:00
@@ -1104,6 +1106,7 @@ public final class CraftServer implements Server {
2024-07-20 18:35:39 +02:00
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");
2024-10-26 17:49:28 +02:00
@@ -1132,6 +1135,7 @@ public final class CraftServer implements Server {
2024-07-20 18:35:39 +02:00
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