diff --git a/patches/api/0001-Pufferfish-Sentry.patch b/patches/api/0001-Pufferfish-Sentry.patch new file mode 100644 index 00000000..80a2b36d --- /dev/null +++ b/patches/api/0001-Pufferfish-Sentry.patch @@ -0,0 +1,245 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Kevin Raneri +Date: Tue, 9 Nov 2021 14:01:56 -0500 +Subject: [PATCH] Pufferfish: Sentry + +Original license: GPL v3 +Original project: https://github.com/pufferfish-gg/Pufferfish + +diff --git a/build.gradle.kts b/build.gradle.kts +index 0719e49dde343c80d18daf82d7fed926150d7d6d..e23ed86c4288ecdfef37bf5b2cd132f348bf852a 100644 +--- a/build.gradle.kts ++++ b/build.gradle.kts +@@ -42,6 +42,7 @@ dependencies { + apiAndDocs("net.kyori:adventure-text-logger-slf4j") + api("org.apache.logging.log4j:log4j-api:2.17.1") + api("org.slf4j:slf4j-api:1.8.0-beta4") ++ api("io.sentry:sentry:6.19.1") // Pufferfish + + implementation("org.ow2.asm:asm:9.4") + implementation("org.ow2.asm:asm-commons:9.4") +diff --git a/src/main/java/gg/pufferfish/pufferfish/sentry/SentryContext.java b/src/main/java/gg/pufferfish/pufferfish/sentry/SentryContext.java +new file mode 100644 +index 0000000000000000000000000000000000000000..364e20dfb1a141e86ae64663cc5f31ac6be3306f +--- /dev/null ++++ b/src/main/java/gg/pufferfish/pufferfish/sentry/SentryContext.java +@@ -0,0 +1,165 @@ ++package gg.pufferfish.pufferfish.sentry; ++ ++import com.google.gson.Gson; ++ ++import java.lang.reflect.Field; ++import java.lang.reflect.Modifier; ++import java.util.Map; ++import java.util.TreeMap; ++ ++import org.apache.logging.log4j.ThreadContext; ++import org.bukkit.command.Command; ++import org.bukkit.command.CommandSender; ++import org.bukkit.entity.Player; ++import org.bukkit.event.Event; ++import org.bukkit.event.player.PlayerEvent; ++import org.bukkit.plugin.Plugin; ++import org.bukkit.plugin.RegisteredListener; ++import org.jetbrains.annotations.Nullable; ++ ++public class SentryContext { ++ ++ private static final Gson GSON = new Gson(); ++ ++ public static void setPluginContext(@Nullable Plugin plugin) { ++ if (plugin != null) { ++ ThreadContext.put("pufferfishsentry_pluginname", plugin.getName()); ++ ThreadContext.put("pufferfishsentry_pluginversion", plugin.getDescription().getVersion()); ++ } ++ } ++ ++ public static void removePluginContext() { ++ ThreadContext.remove("pufferfishsentry_pluginname"); ++ ThreadContext.remove("pufferfishsentry_pluginversion"); ++ } ++ ++ public static void setSenderContext(@Nullable CommandSender sender) { ++ if (sender != null) { ++ ThreadContext.put("pufferfishsentry_playername", sender.getName()); ++ if (sender instanceof Player player) { ++ ThreadContext.put("pufferfishsentry_playerid", player.getUniqueId().toString()); ++ } ++ } ++ } ++ ++ public static void removeSenderContext() { ++ ThreadContext.remove("pufferfishsentry_playername"); ++ ThreadContext.remove("pufferfishsentry_playerid"); ++ } ++ ++ public static void setEventContext(Event event, RegisteredListener registration) { ++ setPluginContext(registration.getPlugin()); ++ ++ try { ++ // Find the player that was involved with this event ++ Player player = null; ++ if (event instanceof PlayerEvent) { ++ player = ((PlayerEvent) event).getPlayer(); ++ } else { ++ Class eventClass = event.getClass(); ++ ++ Field playerField = null; ++ ++ for (Field field : eventClass.getDeclaredFields()) { ++ if (field.getType().equals(Player.class)) { ++ playerField = field; ++ break; ++ } ++ } ++ ++ if (playerField != null) { ++ playerField.setAccessible(true); ++ player = (Player) playerField.get(event); ++ } ++ } ++ ++ if (player != null) { ++ setSenderContext(player); ++ } ++ } catch (Exception e) { ++ } // We can't really safely log exceptions. ++ ++ ThreadContext.put("pufferfishsentry_eventdata", GSON.toJson(serializeFields(event))); ++ } ++ ++ public static void removeEventContext() { ++ removePluginContext(); ++ removeSenderContext(); ++ ThreadContext.remove("pufferfishsentry_eventdata"); ++ } ++ ++ private static Map serializeFields(Object object) { ++ Map fields = new TreeMap<>(); ++ fields.put("_class", object.getClass().getName()); ++ for (Field declaredField : object.getClass().getDeclaredFields()) { ++ try { ++ if (Modifier.isStatic(declaredField.getModifiers())) { ++ continue; ++ } ++ ++ String fieldName = declaredField.getName(); ++ if (fieldName.equals("handlers")) { ++ continue; ++ } ++ declaredField.setAccessible(true); ++ Object value = declaredField.get(object); ++ if (value != null) { ++ fields.put(fieldName, value.toString()); ++ } else { ++ fields.put(fieldName, ""); ++ } ++ } catch (Exception e) { ++ } // We can't really safely log exceptions. ++ } ++ return fields; ++ } ++ ++ public static class State { ++ ++ private Plugin plugin; ++ private Command command; ++ private String commandLine; ++ private Event event; ++ private RegisteredListener registeredListener; ++ ++ public Plugin getPlugin() { ++ return plugin; ++ } ++ ++ public void setPlugin(Plugin plugin) { ++ this.plugin = plugin; ++ } ++ ++ public Command getCommand() { ++ return command; ++ } ++ ++ public void setCommand(Command command) { ++ this.command = command; ++ } ++ ++ public String getCommandLine() { ++ return commandLine; ++ } ++ ++ public void setCommandLine(String commandLine) { ++ this.commandLine = commandLine; ++ } ++ ++ public Event getEvent() { ++ return event; ++ } ++ ++ public void setEvent(Event event) { ++ this.event = event; ++ } ++ ++ public RegisteredListener getRegisteredListener() { ++ return registeredListener; ++ } ++ ++ public void setRegisteredListener(RegisteredListener registeredListener) { ++ this.registeredListener = registeredListener; ++ } ++ } ++} +diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java +index 31324086e30d137c6ca53116b4b17c31c60ab3f7..09e69f98ea13c1fcb57cdc39e6640fe914fb9d3e 100644 +--- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java ++++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java +@@ -584,7 +584,9 @@ public final class SimplePluginManager implements PluginManager { + + // Paper start + private void handlePluginException(String msg, Throwable ex, Plugin plugin) { ++ gg.pufferfish.pufferfish.sentry.SentryContext.setPluginContext(plugin); // Pufferfish + server.getLogger().log(Level.SEVERE, msg, ex); ++ gg.pufferfish.pufferfish.sentry.SentryContext.removePluginContext(); // Pufferfish + callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerPluginEnableDisableException(msg, ex, plugin))); + } + // Paper end +@@ -667,9 +669,11 @@ public final class SimplePluginManager implements PluginManager { + )); + } + } catch (Throwable ex) { ++ gg.pufferfish.pufferfish.sentry.SentryContext.setEventContext(event, registration); // Pufferfish + // Paper start - error reporting + String msg = "Could not pass event " + event.getEventName() + " to " + registration.getPlugin().getDescription().getFullName(); + server.getLogger().log(Level.SEVERE, msg, ex); ++ gg.pufferfish.pufferfish.sentry.SentryContext.removeEventContext(); // Pufferfish + if (!(event instanceof com.destroystokyo.paper.event.server.ServerExceptionEvent)) { // We don't want to cause an endless event loop + callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerEventException(msg, ex, registration.getPlugin(), registration.getListener(), event))); + } +diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java +index eaefbb00e9993d54906cc8cf35cf753c0d6c7707..301e82369603f3dd6e6c1bd380da4bacacd7ef6c 100644 +--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java ++++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java +@@ -336,7 +336,13 @@ public final class JavaPluginLoader implements PluginLoader { + try { + jPlugin.setEnabled(true); + } catch (Throwable ex) { ++ gg.pufferfish.pufferfish.sentry.SentryContext.setPluginContext(plugin); // Pufferfish + server.getLogger().log(Level.SEVERE, "Error occurred while enabling " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex); ++ gg.pufferfish.pufferfish.sentry.SentryContext.removePluginContext(); // Pufferfish ++ // Paper start - Disable plugins that fail to load ++ this.server.getPluginManager().disablePlugin(jPlugin); ++ return; ++ // Paper end + } + + // Perhaps abort here, rather than continue going, but as it stands, +@@ -361,7 +367,9 @@ public final class JavaPluginLoader implements PluginLoader { + try { + jPlugin.setEnabled(false); + } catch (Throwable ex) { ++ gg.pufferfish.pufferfish.sentry.SentryContext.setPluginContext(plugin); // Pufferfish + server.getLogger().log(Level.SEVERE, "Error occurred while disabling " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex); ++ gg.pufferfish.pufferfish.sentry.SentryContext.removePluginContext(); // Pufferfish + } + + if (cloader instanceof PluginClassLoader) { diff --git a/patches/api/0001-Leaf-config-files.patch b/patches/api/0002-Leaf-config-files.patch similarity index 100% rename from patches/api/0001-Leaf-config-files.patch rename to patches/api/0002-Leaf-config-files.patch diff --git a/patches/api/0002-Bump-Dependencies.patch b/patches/api/0003-Bump-Dependencies.patch similarity index 93% rename from patches/api/0002-Bump-Dependencies.patch rename to patches/api/0003-Bump-Dependencies.patch index 36547d8e..ad955625 100644 --- a/patches/api/0002-Bump-Dependencies.patch +++ b/patches/api/0003-Bump-Dependencies.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Bump Dependencies diff --git a/build.gradle.kts b/build.gradle.kts -index 0719e49dde343c80d18daf82d7fed926150d7d6d..f8610e8337a2d2800ccce4c5462e7e997a22f32c 100644 +index e23ed86c4288ecdfef37bf5b2cd132f348bf852a..733236d0cde112d99b017f67f44d982396ffa352 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -24,15 +24,17 @@ configurations.api { @@ -29,7 +29,7 @@ index 0719e49dde343c80d18daf82d7fed926150d7d6d..f8610e8337a2d2800ccce4c5462e7e99 apiAndDocs(platform("net.kyori:adventure-bom:$adventureVersion")) apiAndDocs("net.kyori:adventure-api") apiAndDocs("net.kyori:adventure-text-minimessage") -@@ -40,33 +42,35 @@ dependencies { +@@ -40,34 +42,36 @@ dependencies { apiAndDocs("net.kyori:adventure-text-serializer-legacy") apiAndDocs("net.kyori:adventure-text-serializer-plain") apiAndDocs("net.kyori:adventure-text-logger-slf4j") @@ -38,6 +38,7 @@ index 0719e49dde343c80d18daf82d7fed926150d7d6d..f8610e8337a2d2800ccce4c5462e7e99 + // Leaf start - Bump Dependencies + api("org.apache.logging.log4j:log4j-api:2.20.0") + api("org.slf4j:slf4j-api:2.0.7") + api("io.sentry:sentry:6.19.1") // Pufferfish - implementation("org.ow2.asm:asm:9.4") - implementation("org.ow2.asm:asm-commons:9.4") @@ -78,7 +79,7 @@ index 0719e49dde343c80d18daf82d7fed926150d7d6d..f8610e8337a2d2800ccce4c5462e7e99 } configure { -@@ -112,9 +116,11 @@ tasks.withType { +@@ -113,9 +117,11 @@ tasks.withType { options.use() options.isDocFilesSubDirs = true options.links( @@ -91,7 +92,7 @@ index 0719e49dde343c80d18daf82d7fed926150d7d6d..f8610e8337a2d2800ccce4c5462e7e99 // Paper start //"https://javadoc.io/doc/net.md-5/bungeecord-chat/1.16-R0.4/", // don't link to bungee chat "https://jd.advntr.dev/api/$adventureVersion/", -@@ -155,6 +161,9 @@ val scanJar = tasks.register("scanJarForBadCalls", io.papermc.paperweight.tasks. +@@ -156,6 +162,9 @@ val scanJar = tasks.register("scanJarForBadCalls", io.papermc.paperweight.tasks. jarToScan.set(tasks.jar.flatMap { it.archiveFile }) classpath.from(configurations.compileClasspath) } diff --git a/patches/api/0003-KTP-Optimize-Spigot-event-bus.patch b/patches/api/0004-KTP-Optimize-Spigot-event-bus.patch similarity index 100% rename from patches/api/0003-KTP-Optimize-Spigot-event-bus.patch rename to patches/api/0004-KTP-Optimize-Spigot-event-bus.patch diff --git a/patches/api/0004-KeYi-Player-Skull-API.patch b/patches/api/0005-KeYi-Player-Skull-API.patch similarity index 100% rename from patches/api/0004-KeYi-Player-Skull-API.patch rename to patches/api/0005-KeYi-Player-Skull-API.patch diff --git a/patches/api/0006-Pufferfish-Sentry.patch b/patches/api/0006-Pufferfish-Sentry.patch deleted file mode 100644 index 1b959c0f..00000000 --- a/patches/api/0006-Pufferfish-Sentry.patch +++ /dev/null @@ -1,241 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Kevin Raneri -Date: Tue, 9 Nov 2021 14:01:56 -0500 -Subject: [PATCH] Pufferfish: Sentry - -Original license: GPL v3 -Original project: https://github.com/pufferfish-gg/Pufferfish - -diff --git a/build.gradle.kts b/build.gradle.kts -index f8610e8337a2d2800ccce4c5462e7e997a22f32c..19e8d4affebf995cb98271eb316d473d48eda702 100644 ---- a/build.gradle.kts -+++ b/build.gradle.kts -@@ -45,6 +45,7 @@ dependencies { - // Leaf start - Bump Dependencies - api("org.apache.logging.log4j:log4j-api:2.20.0") - api("org.slf4j:slf4j-api:2.0.7") -+ api("io.sentry:sentry:6.17.0") // Pufferfish - - implementation("org.ow2.asm:asm:9.5") - implementation("org.ow2.asm:asm-commons:9.5") -diff --git a/src/main/java/gg/pufferfish/pufferfish/sentry/SentryContext.java b/src/main/java/gg/pufferfish/pufferfish/sentry/SentryContext.java -new file mode 100644 -index 0000000000000000000000000000000000000000..10310fdd53de28efb8a8250f6d3b0c8eb08fb68a ---- /dev/null -+++ b/src/main/java/gg/pufferfish/pufferfish/sentry/SentryContext.java -@@ -0,0 +1,161 @@ -+package gg.pufferfish.pufferfish.sentry; -+ -+import com.google.gson.Gson; -+import java.lang.reflect.Field; -+import java.lang.reflect.Modifier; -+import java.util.Map; -+import java.util.TreeMap; -+import org.apache.logging.log4j.ThreadContext; -+import org.bukkit.command.Command; -+import org.bukkit.command.CommandSender; -+import org.bukkit.entity.Player; -+import org.bukkit.event.Event; -+import org.bukkit.event.player.PlayerEvent; -+import org.bukkit.plugin.Plugin; -+import org.bukkit.plugin.RegisteredListener; -+import org.jetbrains.annotations.Nullable; -+ -+public class SentryContext { -+ -+ private static final Gson GSON = new Gson(); -+ -+ public static void setPluginContext(@Nullable Plugin plugin) { -+ if (plugin != null) { -+ ThreadContext.put("pufferfishsentry_pluginname", plugin.getName()); -+ ThreadContext.put("pufferfishsentry_pluginversion", plugin.getDescription().getVersion()); -+ } -+ } -+ -+ public static void removePluginContext() { -+ ThreadContext.remove("pufferfishsentry_pluginname"); -+ ThreadContext.remove("pufferfishsentry_pluginversion"); -+ } -+ -+ public static void setSenderContext(@Nullable CommandSender sender) { -+ if (sender != null) { -+ ThreadContext.put("pufferfishsentry_playername", sender.getName()); -+ if (sender instanceof Player player) { -+ ThreadContext.put("pufferfishsentry_playerid", player.getUniqueId().toString()); -+ } -+ } -+ } -+ -+ public static void removeSenderContext() { -+ ThreadContext.remove("pufferfishsentry_playername"); -+ ThreadContext.remove("pufferfishsentry_playerid"); -+ } -+ -+ public static void setEventContext(Event event, RegisteredListener registration) { -+ setPluginContext(registration.getPlugin()); -+ -+ try { -+ // Find the player that was involved with this event -+ Player player = null; -+ if (event instanceof PlayerEvent) { -+ player = ((PlayerEvent) event).getPlayer(); -+ } else { -+ Class eventClass = event.getClass(); -+ -+ Field playerField = null; -+ -+ for (Field field : eventClass.getDeclaredFields()) { -+ if (field.getType().equals(Player.class)) { -+ playerField = field; -+ break; -+ } -+ } -+ -+ if (playerField != null) { -+ playerField.setAccessible(true); -+ player = (Player) playerField.get(event); -+ } -+ } -+ -+ if (player != null) { -+ setSenderContext(player); -+ } -+ } catch (Exception e) {} // We can't really safely log exceptions. -+ -+ ThreadContext.put("pufferfishsentry_eventdata", GSON.toJson(serializeFields(event))); -+ } -+ -+ public static void removeEventContext() { -+ removePluginContext(); -+ removeSenderContext(); -+ ThreadContext.remove("pufferfishsentry_eventdata"); -+ } -+ -+ private static Map serializeFields(Object object) { -+ Map fields = new TreeMap<>(); -+ fields.put("_class", object.getClass().getName()); -+ for (Field declaredField : object.getClass().getDeclaredFields()) { -+ try { -+ if (Modifier.isStatic(declaredField.getModifiers())) { -+ continue; -+ } -+ -+ String fieldName = declaredField.getName(); -+ if (fieldName.equals("handlers")) { -+ continue; -+ } -+ declaredField.setAccessible(true); -+ Object value = declaredField.get(object); -+ if (value != null) { -+ fields.put(fieldName, value.toString()); -+ } else { -+ fields.put(fieldName, ""); -+ } -+ } catch (Exception e) {} // We can't really safely log exceptions. -+ } -+ return fields; -+ } -+ -+ public static class State { -+ -+ private Plugin plugin; -+ private Command command; -+ private String commandLine; -+ private Event event; -+ private RegisteredListener registeredListener; -+ -+ public Plugin getPlugin() { -+ return plugin; -+ } -+ -+ public void setPlugin(Plugin plugin) { -+ this.plugin = plugin; -+ } -+ -+ public Command getCommand() { -+ return command; -+ } -+ -+ public void setCommand(Command command) { -+ this.command = command; -+ } -+ -+ public String getCommandLine() { -+ return commandLine; -+ } -+ -+ public void setCommandLine(String commandLine) { -+ this.commandLine = commandLine; -+ } -+ -+ public Event getEvent() { -+ return event; -+ } -+ -+ public void setEvent(Event event) { -+ this.event = event; -+ } -+ -+ public RegisteredListener getRegisteredListener() { -+ return registeredListener; -+ } -+ -+ public void setRegisteredListener(RegisteredListener registeredListener) { -+ this.registeredListener = registeredListener; -+ } -+ } -+} -diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java -index 31324086e30d137c6ca53116b4b17c31c60ab3f7..09e69f98ea13c1fcb57cdc39e6640fe914fb9d3e 100644 ---- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java -+++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java -@@ -584,7 +584,9 @@ public final class SimplePluginManager implements PluginManager { - - // Paper start - private void handlePluginException(String msg, Throwable ex, Plugin plugin) { -+ gg.pufferfish.pufferfish.sentry.SentryContext.setPluginContext(plugin); // Pufferfish - server.getLogger().log(Level.SEVERE, msg, ex); -+ gg.pufferfish.pufferfish.sentry.SentryContext.removePluginContext(); // Pufferfish - callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerPluginEnableDisableException(msg, ex, plugin))); - } - // Paper end -@@ -667,9 +669,11 @@ public final class SimplePluginManager implements PluginManager { - )); - } - } catch (Throwable ex) { -+ gg.pufferfish.pufferfish.sentry.SentryContext.setEventContext(event, registration); // Pufferfish - // Paper start - error reporting - String msg = "Could not pass event " + event.getEventName() + " to " + registration.getPlugin().getDescription().getFullName(); - server.getLogger().log(Level.SEVERE, msg, ex); -+ gg.pufferfish.pufferfish.sentry.SentryContext.removeEventContext(); // Pufferfish - if (!(event instanceof com.destroystokyo.paper.event.server.ServerExceptionEvent)) { // We don't want to cause an endless event loop - callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerEventException(msg, ex, registration.getPlugin(), registration.getListener(), event))); - } -diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java -index eaefbb00e9993d54906cc8cf35cf753c0d6c7707..301e82369603f3dd6e6c1bd380da4bacacd7ef6c 100644 ---- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java -+++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java -@@ -336,7 +336,13 @@ public final class JavaPluginLoader implements PluginLoader { - try { - jPlugin.setEnabled(true); - } catch (Throwable ex) { -+ gg.pufferfish.pufferfish.sentry.SentryContext.setPluginContext(plugin); // Pufferfish - server.getLogger().log(Level.SEVERE, "Error occurred while enabling " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex); -+ gg.pufferfish.pufferfish.sentry.SentryContext.removePluginContext(); // Pufferfish -+ // Paper start - Disable plugins that fail to load -+ this.server.getPluginManager().disablePlugin(jPlugin); -+ return; -+ // Paper end - } - - // Perhaps abort here, rather than continue going, but as it stands, -@@ -361,7 +367,9 @@ public final class JavaPluginLoader implements PluginLoader { - try { - jPlugin.setEnabled(false); - } catch (Throwable ex) { -+ gg.pufferfish.pufferfish.sentry.SentryContext.setPluginContext(plugin); // Pufferfish - server.getLogger().log(Level.SEVERE, "Error occurred while disabling " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex); -+ gg.pufferfish.pufferfish.sentry.SentryContext.removePluginContext(); // Pufferfish - } - - if (cloader instanceof PluginClassLoader) { diff --git a/patches/api/0005-Slice-Smooth-Teleports.patch b/patches/api/0006-Slice-Smooth-Teleports.patch similarity index 100% rename from patches/api/0005-Slice-Smooth-Teleports.patch rename to patches/api/0006-Slice-Smooth-Teleports.patch