Updated Upstream (Paper & Pufferfish)

Upstream has released updates that appear to apply and compile correctly

Paper Changes:
PaperMC/Paper@2033dba Updated Upstream (CraftBukkit)
PaperMC/Paper@a3ad720 Remove ChatColor usages (#7543)
PaperMC/Paper@8fc0999 Fix some nullability things (#7275)
PaperMC/Paper@fd069dd Remove incorrect throws javadoc in Team (#7869)
PaperMC/Paper@bed5cb2 Limit resolved selectors when enabled
PaperMC/Paper@4d83ed0 [ci skip] Changing the order of the rebase with autosquash command in the contributing.md (#6974)
PaperMC/Paper@071a4a2 throw exception if worlds are created while being ticked (#7653)
PaperMC/Paper@5b6397a Make leave messages for kicks the same as for quitting (#7874)
PaperMC/Paper@5befb55 Updated Upstream (Bukkit/CraftBukkit) (#7875)
PaperMC/Paper@b3deb25 Move some methods to RegionAccessor (#7635)
PaperMC/Paper@d8ef841 [DataConverter] Fix generator options parsing
PaperMC/Paper@4b27254 Fix treasure maps discovered settings (#7627)
PaperMC/Paper@276d830 Fix campfire walker in V1920

Pufferfish Changes:
pufferfish-gg/Pufferfish@671d68b Add Entity TTLs
pufferfish-gg/Pufferfish@aaca13d Updated Upstream (Paper)
This commit is contained in:
Ben Kerllenevich
2022-06-07 13:08:57 -04:00
parent 46a92bd39a
commit dc4a29b567
39 changed files with 345 additions and 310 deletions

View File

@@ -77,10 +77,10 @@ index 0282e3b75470e1a68ea1fc228082483514ba432e..b04e9ab317fbce9c090b61076eb07c40
"Specification-Title" to "Bukkit",
"Specification-Version" to project.version,
diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java
index 5ba64e1083b7cb1eec64d1925095c6ca5865ff07..a5e4467382422df6cff2b9f61f44feabfe7084f3 100644
index f3bf9df8c0bd56cad461210ce8551ade3a220b6b..088585a1075cd8790e2599eb6a8372adcff050e3 100644
--- a/src/main/java/co/aikar/timings/TimingsExport.java
+++ b/src/main/java/co/aikar/timings/TimingsExport.java
@@ -238,7 +238,8 @@ public class TimingsExport extends Thread {
@@ -240,7 +240,8 @@ public class TimingsExport extends Thread {
parent.put("config", createObject(
pair("spigot", mapAsJSON(Bukkit.spigot().getSpigotConfig(), null)),
pair("bukkit", mapAsJSON(Bukkit.spigot().getBukkitConfig(), null)),
@@ -113,7 +113,7 @@ index 218f5bafeed8551b55b91c7fccaf6935c8b631ca..f2fe6ea3719ff8b2913b7a3a939d7a5b
metrics.addCustomChart(new Metrics.DrilldownPie("java_version", () -> {
Map<String, Map<String, Integer>> map = new HashMap<>();
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
index fafbebbb5e8c1a381b673f97f1fa210687b52823..560e83f1e70cc2712e9c08ffd5e2cab8a6de687b 100644
index 8379c6313f06ab3eeaf02bad41d8b835d50e093f..7a7d0566611aafafba30b7b25c2f1f3e78b054fa 100644
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
@@ -241,6 +241,15 @@ public class PaperConfig {
@@ -557,7 +557,7 @@ index 0000000000000000000000000000000000000000..a7f297ebb569f7c1f205e967ca485be7
+}
diff --git a/src/main/java/gg/pufferfish/pufferfish/PufferfishCommand.java b/src/main/java/gg/pufferfish/pufferfish/PufferfishCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..020368da69b9a492155f6de6297f74732f4ab6ea
index 0000000000000000000000000000000000000000..e164237e749bcc43466d4ed7aeada5ab9fddf8a6
--- /dev/null
+++ b/src/main/java/gg/pufferfish/pufferfish/PufferfishCommand.java
@@ -0,0 +1,68 @@
@@ -585,7 +585,7 @@ index 0000000000000000000000000000000000000000..020368da69b9a492155f6de6297f7473
+ this.usageMessage = "/pufferfish [reload | version]";
+ this.setPermission("bukkit.command.pufferfish");
+ }
+
+
+ public static void init() {
+ MinecraftServer.getServer().server.getCommandMap().register("pufferfish", "Pufferfish", new PufferfishCommand());
+ }
@@ -631,17 +631,20 @@ index 0000000000000000000000000000000000000000..020368da69b9a492155f6de6297f7473
+}
diff --git a/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java b/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..56a5a31b41d00ba73259a7eda5c57d08570d3e6e
index 0000000000000000000000000000000000000000..7572cbc662a5b824435d75e1b3b7ea0e58144c9c
--- /dev/null
+++ b/src/main/java/gg/pufferfish/pufferfish/PufferfishConfig.java
@@ -0,0 +1,293 @@
@@ -0,0 +1,313 @@
+package gg.pufferfish.pufferfish;
+
+import gg.pufferfish.pufferfish.simd.SIMDDetection;
+import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Locale;
+import java.util.Map;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.tags.TagKey;
+import org.apache.logging.log4j.Level;
+import org.bukkit.configuration.ConfigurationSection;
+import net.minecraft.core.Registry;
@@ -667,10 +670,10 @@ index 0000000000000000000000000000000000000000..56a5a31b41d00ba73259a7eda5c57d08
+import java.util.Collections;
+
+public class PufferfishConfig {
+
+
+ private static final YamlFile config = new YamlFile();
+ private static int updates = 0;
+
+
+ private static ConfigurationSection convertToBukkit(org.simpleyaml.configuration.ConfigurationSection section) {
+ ConfigurationSection newSection = new MemoryConfiguration();
+ for (String key : section.getKeys(false)) {
@@ -682,18 +685,18 @@ index 0000000000000000000000000000000000000000..56a5a31b41d00ba73259a7eda5c57d08
+ }
+ return newSection;
+ }
+
+
+ public static ConfigurationSection getConfigCopy() {
+ return convertToBukkit(config);
+ }
+
+
+ public static int getUpdates() {
+ return updates;
+ }
+
+
+ public static void load() throws IOException {
+ File configFile = new File("pufferfish.yml");
+
+
+ if (configFile.exists()) {
+ try {
+ config.load(configFile);
@@ -701,14 +704,14 @@ index 0000000000000000000000000000000000000000..56a5a31b41d00ba73259a7eda5c57d08
+ throw new IOException(e);
+ }
+ }
+
+
+ getString("info.version", "1.0");
+ setComment("info",
+ "Pufferfish Configuration",
+ "Check out Pufferfish Host for maximum performance server hosting: https://pufferfish.host",
+ "Join our Discord for support: https://discord.gg/reZw4vQV9H",
+ "Download new builds at https://ci.pufferfish.host/job/Pufferfish");
+
+
+ for (Method method : PufferfishConfig.class.getDeclaredMethods()) {
+ if (Modifier.isStatic(method.getModifiers()) && Modifier.isPrivate(method.getModifiers()) && method.getParameterCount() == 0 &&
+ method.getReturnType() == Void.TYPE && !method.getName().startsWith("lambda")) {
@@ -720,17 +723,17 @@ index 0000000000000000000000000000000000000000..56a5a31b41d00ba73259a7eda5c57d08
+ }
+ }
+ }
+
+
+ updates++;
+
+
+ config.save(configFile);
+
+
+ // Attempt to detect vectorization
+ try {
+ SIMDDetection.isEnabled = SIMDDetection.canEnable(PufferfishLogger.LOGGER);
+ SIMDDetection.versionLimited = SIMDDetection.getJavaVersion() != 17 && SIMDDetection.getJavaVersion() != 18;
+ } catch (NoClassDefFoundError | Exception ignored) {}
+
+
+ if (SIMDDetection.isEnabled) {
+ PufferfishLogger.LOGGER.info("SIMD operations detected as functional. Will replace some operations with faster versions.");
+ } else if (SIMDDetection.versionLimited) {
@@ -742,76 +745,76 @@ index 0000000000000000000000000000000000000000..56a5a31b41d00ba73259a7eda5c57d08
+ PufferfishLogger.LOGGER.warning("Debug: Java: " + System.getProperty("java.version") + ", test run: " + SIMDDetection.testRun);
+ }
+ }
+
+
+ private static void setComment(String key, String... comment) {
+ if (config.contains(key)) {
+ config.setComment(key, String.join("\n", comment), CommentType.BLOCK);
+ }
+ }
+
+
+ private static void ensureDefault(String key, Object defaultValue, String... comment) {
+ if (!config.contains(key)) {
+ config.set(key, defaultValue);
+ config.setComment(key, String.join("\n", comment), CommentType.BLOCK);
+ }
+ }
+
+
+ private static boolean getBoolean(String key, boolean defaultValue, String... comment) {
+ return getBoolean(key, null, defaultValue, comment);
+ }
+
+
+ private static boolean getBoolean(String key, @Nullable String oldKey, boolean defaultValue, String... comment) {
+ ensureDefault(key, defaultValue, comment);
+ return config.getBoolean(key, defaultValue);
+ }
+
+
+ private static int getInt(String key, int defaultValue, String... comment) {
+ return getInt(key, null, defaultValue, comment);
+ }
+
+
+ private static int getInt(String key, @Nullable String oldKey, int defaultValue, String... comment) {
+ ensureDefault(key, defaultValue, comment);
+ return config.getInt(key, defaultValue);
+ }
+
+
+ private static double getDouble(String key, double defaultValue, String... comment) {
+ return getDouble(key, null, defaultValue, comment);
+ }
+
+
+ private static double getDouble(String key, @Nullable String oldKey, double defaultValue, String... comment) {
+ ensureDefault(key, defaultValue, comment);
+ return config.getDouble(key, defaultValue);
+ }
+
+
+ private static String getString(String key, String defaultValue, String... comment) {
+ return getOldString(key, null, defaultValue, comment);
+ }
+
+
+ private static String getOldString(String key, @Nullable String oldKey, String defaultValue, String... comment) {
+ ensureDefault(key, defaultValue, comment);
+ return config.getString(key, defaultValue);
+ }
+
+
+ private static List<String> getStringList(String key, List<String> defaultValue, String... comment) {
+ return getStringList(key, null, defaultValue, comment);
+ }
+
+
+ private static List<String> getStringList(String key, @Nullable String oldKey, List<String> defaultValue, String... comment) {
+ ensureDefault(key, defaultValue, comment);
+ return config.getStringList(key);
+ }
+
+
+ public static String sentryDsn;
+ private static void sentry() {
+ String sentryEnvironment = System.getenv("SENTRY_DSN");
+ String sentryConfig = getString("sentry-dsn", "", "Sentry DSN for improved error logging, leave blank to disable", "Obtain from https://sentry.io/");
+
+
+ sentryDsn = sentryEnvironment == null ? sentryConfig : sentryEnvironment;
+ if (sentryDsn != null && !sentryDsn.isBlank()) {
+ gg.pufferfish.pufferfish.sentry.SentryManager.init();
+ }
+ }
+
+
+ public static boolean enableBooks;
+ private static void books() {
+ enableBooks = getBoolean("enable-books", true,
@@ -820,7 +823,7 @@ index 0000000000000000000000000000000000000000..56a5a31b41d00ba73259a7eda5c57d08
+ "disabling this option.",
+ "This can be overridden per-player with the permission pufferfish.usebooks");
+ }
+
+
+ public static boolean enableSuffocationOptimization;
+ private static void suffocationOptimization() {
+ enableSuffocationOptimization = getBoolean("enable-suffocation-optimization", true,
@@ -829,7 +832,7 @@ index 0000000000000000000000000000000000000000..56a5a31b41d00ba73259a7eda5c57d08
+ "be left enabled on most servers, but is provided as a",
+ "configuration option if the vanilla deviation is undesirable.");
+ }
+
+
+ public static boolean enableAsyncMobSpawning;
+ public static boolean asyncMobSpawningInitialized;
+ private static void asyncMobSpawning() {
@@ -839,14 +842,14 @@ index 0000000000000000000000000000000000000000..56a5a31b41d00ba73259a7eda5c57d08
+ "paper's per-player-mob-spawns setting set to true for this to work.",
+ "One quick note - this does not actually spawn mobs async (that would be very unsafe).",
+ "This just offloads some expensive calculations that are required for mob spawning.");
+
+
+ // This prevents us from changing the value during a reload.
+ if (!asyncMobSpawningInitialized) {
+ asyncMobSpawningInitialized = true;
+ enableAsyncMobSpawning = temp;
+ }
+ }
+
+
+ public static int maxProjectileLoadsPerTick;
+ public static int maxProjectileLoadsPerProjectile;
+ private static void projectileLoading() {
@@ -888,7 +891,24 @@ index 0000000000000000000000000000000000000000..56a5a31b41d00ba73259a7eda5c57d08
+
+ setComment("dab", "Optimizes entity brains when", "they're far away from the player");
+ }
+
+
+ public static Map<String, Integer> projectileTimeouts;
+ private static void projectileTimeouts() {
+ // Set some defaults
+ getInt("entity_timeouts.SNOWBALL", -1);
+ getInt("entity_timeouts.LLAMA_SPIT", -1);
+ setComment("entity_timeouts",
+ "These values define a entity's maximum lifespan. If an",
+ "entity is in this list and it has survived for longer than",
+ "that number of ticks, then it will be removed. Setting a value to",
+ "-1 disables this feature.");
+
+ for (EntityType<?> entityType : Registry.ENTITY_TYPE) {
+ String type = EntityType.getKey(entityType).getPath().toUpperCase(Locale.ROOT);
+ entityType.ttl = config.getInt("entity_timeouts." + type, -1);
+ }
+ }
+
+ public static boolean throttleInactiveGoalSelectorTick;
+ private static void inactiveGoalSelectorThrottle() {
+ getBoolean("inactive-goal-selector-throttle", "inactive-goal-selector-disable", true,
@@ -952,7 +972,7 @@ index 0000000000000000000000000000000000000000..53f2df00c6809618a9ee3d2ea72e85e8
+}
diff --git a/src/main/java/gg/pufferfish/pufferfish/PufferfishVersionFetcher.java b/src/main/java/gg/pufferfish/pufferfish/PufferfishVersionFetcher.java
new file mode 100644
index 0000000000000000000000000000000000000000..adafc4fd661cf080b004b86c3eaed231a0133101
index 0000000000000000000000000000000000000000..461022af9ad85fe00329678f0f61d684d291c628
--- /dev/null
+++ b/src/main/java/gg/pufferfish/pufferfish/PufferfishVersionFetcher.java
@@ -0,0 +1,136 @@
@@ -984,46 +1004,46 @@ index 0000000000000000000000000000000000000000..adafc4fd661cf080b004b86c3eaed231
+import org.jetbrains.annotations.Nullable;
+
+public class PufferfishVersionFetcher implements VersionFetcher {
+
+
+ private static final Logger LOGGER = Logger.getLogger("PufferfishVersionFetcher");
+ private static final HttpClient client = HttpClient.newHttpClient();
+
+
+ private static final URI JENKINS_URI = URI.create("https://ci.pufferfish.host/job/Pufferfish-1.18/lastSuccessfulBuild/buildNumber");
+ private static final String GITHUB_FORMAT = "https://api.github.com/repos/pufferfish-gg/Pufferfish/compare/ver/1.18...%s";
+
+
+ private static final HttpResponse.BodyHandler<JsonObject> JSON_OBJECT_BODY_HANDLER = responseInfo -> HttpResponse.BodySubscribers
+ .mapping(
+ HttpResponse.BodySubscribers.ofString(StandardCharsets.UTF_8),
+ string -> new Gson().fromJson(string, JsonObject.class)
+ );
+
+
+ @Override
+ public long getCacheTime() {
+ return TimeUnit.MINUTES.toMillis(30);
+ }
+
+
+ @Override
+ public @NotNull Component getVersionMessage(final @NotNull String serverVersion) {
+ final String[] parts = CraftServer.class.getPackage().getImplementationVersion().split("-");
+ @NotNull Component component;
+
+
+ if (parts.length != 3) {
+ component = text("Unknown server version.", RED);
+ } else {
+ final String versionString = parts[2];
+
+
+ try {
+ component = this.fetchJenkinsVersion(Integer.parseInt(versionString));
+ } catch (NumberFormatException e) {
+ component = this.fetchGithubVersion(versionString.substring(1, versionString.length() - 1));
+ }
+ }
+
+
+ final @Nullable Component history = this.getHistory();
+ return history != null ? Component
+ .join(JoinConfiguration.noSeparators(), component, Component.newline(), this.getHistory()) : component;
+ }
+
+
+ private @NotNull Component fetchJenkinsVersion(final int versionNumber) {
+ final HttpRequest request = HttpRequest.newBuilder(JENKINS_URI).build();
+ try {
@@ -1031,7 +1051,7 @@ index 0000000000000000000000000000000000000000..adafc4fd661cf080b004b86c3eaed231
+ if (response.statusCode() != 200) {
+ return text("Received invalid status code (" + response.statusCode() + ") from server.", RED);
+ }
+
+
+ int latestVersionNumber;
+ try {
+ latestVersionNumber = Integer.parseInt(response.body());
@@ -1039,7 +1059,7 @@ index 0000000000000000000000000000000000000000..adafc4fd661cf080b004b86c3eaed231
+ LOGGER.log(Level.WARNING, "Received invalid response from Jenkins \"" + response.body() + "\".");
+ return text("Received invalid response from server.", RED);
+ }
+
+
+ final int versionDiff = latestVersionNumber - versionNumber;
+ return this.getResponseMessage(versionDiff);
+ } catch (IOException | InterruptedException e) {
@@ -1047,7 +1067,7 @@ index 0000000000000000000000000000000000000000..adafc4fd661cf080b004b86c3eaed231
+ return text("Failed to retrieve version from server.", RED);
+ }
+ }
+
+
+ // Based off code contributed by Techcable <Techcable@outlook.com> in Paper/GH-65
+ private @NotNull Component fetchGithubVersion(final @NotNull String hash) {
+ final URI uri = URI.create(String.format(GITHUB_FORMAT, hash));
@@ -1057,17 +1077,17 @@ index 0000000000000000000000000000000000000000..adafc4fd661cf080b004b86c3eaed231
+ if (response.statusCode() != 200) {
+ return text("Received invalid status code (" + response.statusCode() + ") from server.", RED);
+ }
+
+
+ final JsonObject obj = response.body();
+ final int versionDiff = obj.get("behind_by").getAsInt();
+
+
+ return this.getResponseMessage(versionDiff);
+ } catch (IOException | InterruptedException e) {
+ LOGGER.log(Level.WARNING, "Failed to look up version from GitHub", e);
+ return text("Failed to retrieve version from server.", RED);
+ }
+ }
+
+
+ private @NotNull Component getResponseMessage(final int versionDiff) {
+ return switch (Math.max(-1, Math.min(1, versionDiff))) {
+ case -1 -> text("You are running an unsupported version of Pufferfish.", RED);
@@ -1077,18 +1097,18 @@ index 0000000000000000000000000000000000000000..adafc4fd661cf080b004b86c3eaed231
+ RED);
+ };
+ }
+
+
+ private @Nullable Component getHistory() {
+ final VersionHistoryManager.VersionData data = VersionHistoryManager.INSTANCE.getVersionData();
+ if (data == null) {
+ return null;
+ }
+
+
+ final String oldVersion = data.getOldVersion();
+ if (oldVersion == null) {
+ return null;
+ }
+
+
+ return Component.text("Previous version: " + oldVersion, NamedTextColor.GRAY, TextDecoration.ITALIC);
+ }
+}
@@ -1788,7 +1808,7 @@ index 0000000000000000000000000000000000000000..db15d3fbe2b65fc8035573f5fdbea382
+}
diff --git a/src/main/java/gg/pufferfish/pufferfish/sentry/PufferfishSentryAppender.java b/src/main/java/gg/pufferfish/pufferfish/sentry/PufferfishSentryAppender.java
new file mode 100644
index 0000000000000000000000000000000000000000..731ef11c7a025ae95ed8a757b530d834733d0621
index 0000000000000000000000000000000000000000..d04a8a4336566dbe6e1b9ec0d574cff43e003fa8
--- /dev/null
+++ b/src/main/java/gg/pufferfish/pufferfish/sentry/PufferfishSentryAppender.java
@@ -0,0 +1,135 @@
@@ -1812,14 +1832,14 @@ index 0000000000000000000000000000000000000000..731ef11c7a025ae95ed8a757b530d834
+import org.apache.logging.log4j.core.filter.AbstractFilter;
+
+public class PufferfishSentryAppender extends AbstractAppender {
+
+
+ private static final org.apache.logging.log4j.Logger logger = LogManager.getLogger(PufferfishSentryAppender.class);
+ private static final Gson GSON = new Gson();
+
+
+ public PufferfishSentryAppender() {
+ super("PufferfishSentryAdapter", new SentryFilter(), null);
+ }
+
+
+ @Override
+ public void append(LogEvent logEvent) {
+ if (logEvent.getThrown() != null && logEvent.getLevel().isMoreSpecificThan(Level.WARN)) {
@@ -1836,55 +1856,55 @@ index 0000000000000000000000000000000000000000..731ef11c7a025ae95ed8a757b530d834
+ }
+ }
+ }
+
+
+ private void logException(LogEvent e) {
+ SentryEvent event = new SentryEvent(e.getThrown());
+
+
+ Message sentryMessage = new Message();
+ sentryMessage.setMessage(e.getMessage().getFormattedMessage());
+
+
+ event.setThrowable(e.getThrown());
+ event.setLevel(getLevel(e.getLevel()));
+ event.setLogger(e.getLoggerName());
+ event.setTransaction(e.getLoggerName());
+ event.setExtra("thread_name", e.getThreadName());
+
+
+ boolean hasContext = e.getContextData() != null;
+
+
+ if (hasContext && e.getContextData().containsKey("pufferfishsentry_playerid")) {
+ User user = new User();
+ user.setId(e.getContextData().getValue("pufferfishsentry_playerid"));
+ user.setUsername(e.getContextData().getValue("pufferfishsentry_playername"));
+ event.setUser(user);
+ }
+
+
+ if (hasContext && e.getContextData().containsKey("pufferfishsentry_pluginname")) {
+ event.setExtra("plugin.name", e.getContextData().getValue("pufferfishsentry_pluginname"));
+ event.setExtra("plugin.version", e.getContextData().getValue("pufferfishsentry_pluginversion"));
+ event.setTransaction(e.getContextData().getValue("pufferfishsentry_pluginname"));
+ }
+
+
+ if (hasContext && e.getContextData().containsKey("pufferfishsentry_eventdata")) {
+ Map<String, String> eventFields = GSON.fromJson((String) e.getContextData().getValue("pufferfishsentry_eventdata"), new TypeToken<Map<String, String>>() {}.getType());
+ if (eventFields != null) {
+ event.setExtra("event", eventFields);
+ }
+ }
+
+
+ Sentry.captureEvent(event);
+ }
+
+
+ private void logBreadcrumb(LogEvent e) {
+ Breadcrumb breadcrumb = new Breadcrumb();
+
+
+ breadcrumb.setLevel(getLevel(e.getLevel()));
+ breadcrumb.setCategory(e.getLoggerName());
+ breadcrumb.setType(e.getLoggerName());
+ breadcrumb.setMessage(e.getMessage().getFormattedMessage());
+
+
+ Sentry.addBreadcrumb(breadcrumb);
+ }
+
+
+ private SentryLevel getLevel(Level level) {
+ switch (level.getStandardLevel()) {
+ case TRACE:
@@ -1901,35 +1921,35 @@ index 0000000000000000000000000000000000000000..731ef11c7a025ae95ed8a757b530d834
+ return SentryLevel.INFO;
+ }
+ }
+
+
+ private static class SentryFilter extends AbstractFilter {
+
+
+ @Override
+ public Result filter(Logger logger, org.apache.logging.log4j.Level level, Marker marker, String msg,
+ Object... params) {
+ return this.filter(logger.getName());
+ }
+
+
+ @Override
+ public Result filter(Logger logger, org.apache.logging.log4j.Level level, Marker marker, Object msg, Throwable t) {
+ return this.filter(logger.getName());
+ }
+
+
+ @Override
+ public Result filter(LogEvent event) {
+ return this.filter(event == null ? null : event.getLoggerName());
+ }
+
+
+ private Result filter(String loggerName) {
+ return loggerName != null && loggerName.startsWith("gg.castaway.pufferfish.sentry") ? Result.DENY
+ : Result.NEUTRAL;
+ }
+
+
+ }
+}
diff --git a/src/main/java/gg/pufferfish/pufferfish/sentry/SentryManager.java b/src/main/java/gg/pufferfish/pufferfish/sentry/SentryManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..1b29210ad0bbb4ada150f23357f0c80d331c996d
index 0000000000000000000000000000000000000000..b011abbeb80b42de6be3785e47c7ba3c0f6dc161
--- /dev/null
+++ b/src/main/java/gg/pufferfish/pufferfish/sentry/SentryManager.java
@@ -0,0 +1,40 @@
@@ -1941,27 +1961,27 @@ index 0000000000000000000000000000000000000000..1b29210ad0bbb4ada150f23357f0c80d
+import org.apache.logging.log4j.Logger;
+
+public class SentryManager {
+
+
+ private static final Logger logger = LogManager.getLogger(SentryManager.class);
+
+
+ private SentryManager() {
+
+
+ }
+
+
+ private static boolean initialized = false;
+
+
+ public static synchronized void init() {
+ if (initialized) {
+ return;
+ }
+ try {
+ initialized = true;
+
+
+ Sentry.init(options -> {
+ options.setDsn(PufferfishConfig.sentryDsn);
+ options.setMaxBreadcrumbs(100);
+ });
+
+
+ PufferfishSentryAppender appender = new PufferfishSentryAppender();
+ appender.start();
+ ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()).addAppender(appender);
@@ -1971,11 +1991,11 @@ index 0000000000000000000000000000000000000000..1b29210ad0bbb4ada150f23357f0c80d
+ initialized = false;
+ }
+ }
+
+
+}
diff --git a/src/main/java/gg/pufferfish/pufferfish/util/AsyncExecutor.java b/src/main/java/gg/pufferfish/pufferfish/util/AsyncExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..9d6dc2c80945bec9bea74714c657c7a2e0bdde9e
index 0000000000000000000000000000000000000000..0772fbc77a198b3571b4ed1e8cc85e90ccd6e38a
--- /dev/null
+++ b/src/main/java/gg/pufferfish/pufferfish/util/AsyncExecutor.java
@@ -0,0 +1,51 @@
@@ -1989,29 +2009,29 @@ index 0000000000000000000000000000000000000000..9d6dc2c80945bec9bea74714c657c7a2
+import java.util.logging.Level;
+
+public class AsyncExecutor implements Runnable {
+
+
+ private Queue<Runnable> jobs = Queues.newConcurrentLinkedQueue();
+ private final Thread thread;
+ private final BooleanSupplier shouldRun;
+ private volatile boolean killswitch = false;
+
+
+ public AsyncExecutor(String threadName, BooleanSupplier shouldRun) {
+ this.thread = new Thread(this, threadName);
+ this.shouldRun = shouldRun;
+ }
+
+
+ public void start() {
+ thread.start();
+ }
+
+
+ public void kill() {
+ killswitch = true;
+ }
+
+
+ public void submit(Runnable runnable) {
+ jobs.offer(runnable);
+ }
+
+
+ @Override
+ public void run() {
+ while (!killswitch) {
@@ -2028,11 +2048,11 @@ index 0000000000000000000000000000000000000000..9d6dc2c80945bec9bea74714c657c7a2
+ LockSupport.parkNanos("executing tasks", 1000L);
+ }
+ }
+
+
+}
diff --git a/src/main/java/gg/pufferfish/pufferfish/util/AsyncPlayerAreaMap.java b/src/main/java/gg/pufferfish/pufferfish/util/AsyncPlayerAreaMap.java
new file mode 100644
index 0000000000000000000000000000000000000000..fdcb62d12164024a5f354d60cc863821a18d1b2a
index 0000000000000000000000000000000000000000..a93ee99c2399def1e221260547a3e6bce2d621fa
--- /dev/null
+++ b/src/main/java/gg/pufferfish/pufferfish/util/AsyncPlayerAreaMap.java
@@ -0,0 +1,31 @@
@@ -2044,22 +2064,22 @@ index 0000000000000000000000000000000000000000..fdcb62d12164024a5f354d60cc863821
+import net.minecraft.server.level.ServerPlayer;
+
+public final class AsyncPlayerAreaMap extends PlayerAreaMap {
+
+
+ public AsyncPlayerAreaMap() {
+ super();
+ this.areaMap = new Long2ObjectOpenHashMapWrapper<>(new ConcurrentHashMap<>(1024, 0.7f));
+ }
+
+
+ public AsyncPlayerAreaMap(final PooledLinkedHashSets<ServerPlayer> pooledHashSets) {
+ super(pooledHashSets);
+ this.areaMap = new Long2ObjectOpenHashMapWrapper<>(new ConcurrentHashMap<>(1024, 0.7f));
+ }
+
+
+ public AsyncPlayerAreaMap(final PooledLinkedHashSets<ServerPlayer> pooledHashSets, final ChangeCallback<ServerPlayer> addCallback,
+ final ChangeCallback<ServerPlayer> removeCallback) {
+ this(pooledHashSets, addCallback, removeCallback, null);
+ }
+
+
+ public AsyncPlayerAreaMap(final PooledLinkedHashSets<ServerPlayer> pooledHashSets, final ChangeCallback<ServerPlayer> addCallback,
+ final ChangeCallback<ServerPlayer> removeCallback, final ChangeSourceCallback<ServerPlayer> changeSourceCallback) {
+ super(pooledHashSets, addCallback, removeCallback, changeSourceCallback);
@@ -2095,7 +2115,7 @@ index 0000000000000000000000000000000000000000..c1929840254a3e6d721816f4a20415be
+}
diff --git a/src/main/java/gg/pufferfish/pufferfish/util/Long2ObjectOpenHashMapWrapper.java b/src/main/java/gg/pufferfish/pufferfish/util/Long2ObjectOpenHashMapWrapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..facd55463d44cb7e3d2ca6892982f5497b8dded1
index 0000000000000000000000000000000000000000..42cdc43d6b739973a0944f502089757247ee6c61
--- /dev/null
+++ b/src/main/java/gg/pufferfish/pufferfish/util/Long2ObjectOpenHashMapWrapper.java
@@ -0,0 +1,40 @@
@@ -2106,34 +2126,34 @@ index 0000000000000000000000000000000000000000..facd55463d44cb7e3d2ca6892982f549
+import org.jetbrains.annotations.Nullable;
+
+public class Long2ObjectOpenHashMapWrapper<V> extends Long2ObjectOpenHashMap<V> {
+
+
+ private final Map<Long, V> backingMap;
+
+
+ public Long2ObjectOpenHashMapWrapper(Map<Long, V> map) {
+ backingMap = map;
+ }
+
+
+ @Override
+ public V put(Long key, V value) {
+ return backingMap.put(key, value);
+ }
+
+
+ @Override
+ public V get(Object key) {
+ return backingMap.get(key);
+ }
+
+
+ @Override
+ public V remove(Object key) {
+ return backingMap.remove(key);
+ }
+
+
+ @Nullable
+ @Override
+ public V putIfAbsent(Long key, V value) {
+ return backingMap.putIfAbsent(key, value);
+ }
+
+
+ @Override
+ public int size() {
+ return backingMap.size();
@@ -2153,19 +2173,19 @@ index 6aec679e75aa6655b47a552db011924ea3a6c922..e8e49e1bdf1ff4ea60a4feb6ec52d999
public static long getCoordinateKey(final ChunkPos pair) {
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index c8d56947305c981a3268ce4ae3e975db350ceff2..371b0f95b23d67c9913875a3dd7888e722551f18 100644
index da15a224b8b974e78b9d8d5f514229b3b2a5a63e..22ad31a4320906ee6b56180324a48258c6e461f2 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -308,6 +308,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public volatile Thread shutdownThread; // Paper
@@ -310,6 +310,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public volatile boolean abnormalExit = false; // Paper
+
+ public gg.pufferfish.pufferfish.util.AsyncExecutor mobSpawnExecutor = new gg.pufferfish.pufferfish.util.AsyncExecutor("MobSpawning", () -> true); // Pufferfish - optimize mob spawning
public boolean isIteratingOverLevels = false; // Paper
+ public gg.pufferfish.pufferfish.util.AsyncExecutor mobSpawnExecutor = new gg.pufferfish.pufferfish.util.AsyncExecutor("MobSpawning", () -> true); // Pufferfish - optimize mob spawning
+
public static <S extends MinecraftServer> S spin(Function<Thread, S> serverFactory) {
AtomicReference<S> atomicreference = new AtomicReference();
@@ -1693,7 +1695,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
Thread thread = new Thread(() -> {
@@ -1696,7 +1698,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@DontObfuscate
public String getServerModName() {
@@ -2174,7 +2194,7 @@ index c8d56947305c981a3268ce4ae3e975db350ceff2..371b0f95b23d67c9913875a3dd7888e7
}
public SystemReport fillSystemReport(SystemReport details) {
@@ -2252,6 +2254,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -2255,6 +2257,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
public ProfilerFiller getProfiler() {
@@ -2256,19 +2276,19 @@ index 6ce27675103d4b691216c6b701b6ceb821af528f..0ab662448c24ba1d3c697f8096f03c88
return this.scaledRange(i);
}
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index fb0757d4bb32123641535a88a22bc074b8d2623f..b42e32bd1a6a669f498b577ec04661c4ba651198 100644
index fb0757d4bb32123641535a88a22bc074b8d2623f..3241f4f73395e8e5c0d15d85b2b77711a5984677 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -74,6 +74,9 @@ public class ServerChunkCache extends ChunkSource {
final it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<LevelChunk> loadedChunkMap = new it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<>(8192, 0.5f);
@@ -75,6 +75,9 @@ public class ServerChunkCache extends ChunkSource {
private final LevelChunk[] lastLoadedChunks = new LevelChunk[4 * 4];
+
+ public boolean firstRunSpawnCounts = true; // Pufferfish
+ public final java.util.concurrent.atomic.AtomicBoolean _pufferfish_spawnCountsReady = new java.util.concurrent.atomic.AtomicBoolean(false); // Pufferfish - optimize countmobs
+
private static int getChunkCacheKey(int x, int z) {
return x & 3 | ((z & 3) << 2);
}
@@ -961,6 +964,7 @@ public class ServerChunkCache extends ChunkSource {
ProfilerFiller gameprofilerfiller = this.level.getProfiler();
@@ -2324,7 +2344,7 @@ index fb0757d4bb32123641535a88a22bc074b8d2623f..b42e32bd1a6a669f498b577ec04661c4
}
// Paper end - controlled flush for entity tracker packets
}
+
+
+ // Pufferfish start - optimize mob spawning
+ if (gg.pufferfish.pufferfish.PufferfishConfig.enableAsyncMobSpawning) {
+ for (ServerPlayer player : this.level.players) {
@@ -2429,7 +2449,7 @@ index 98209532ad3e692d7e459640123f78bbd9a65889..93c1f9e3e9d62cc993fedb93fe43cbee
this.getRandomBlockPosition(j, 0, k, 15, blockposition);
int normalY = chunk.getHeight(Heightmap.Types.MOTION_BLOCKING, blockposition.getX() & 15, blockposition.getZ() & 15) + 1;
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 901fa17d0f0a3f66923f68f13f183bc4c17f7748..676f2cd4b152984aa76903fcf4377c745775bfc8 100644
index 0b7923f67d27549f41c0d398d1b99737f0c8a746..f98c6804ef8ec33551857606800295712f2e9057 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -1117,6 +1117,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
@@ -2553,7 +2573,7 @@ index 7437f01ca8f416e2c9150250e324af4725a4efb6..7ac51dbfce18a2bc52faa7a915abeccc
int LARGE_MAX_STACK_SIZE = 64;
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index dfd1f37757af1bd808cc2e2d8bf97123adf638bb..971e743cc99400681439de89252a29ee9de46188 100644
index dfd1f37757af1bd808cc2e2d8bf97123adf638bb..b47165433d43592742e508f9b918ab36b42c6df6 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -230,7 +230,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -2573,7 +2593,7 @@ index dfd1f37757af1bd808cc2e2d8bf97123adf638bb..971e743cc99400681439de89252a29ee
+ public int activatedPriority = gg.pufferfish.pufferfish.PufferfishConfig.maximumActivationPrio; // golf score
+ public final BlockPos.MutableBlockPos cachedBlockPos = new BlockPos.MutableBlockPos(); // used where needed
+ // Pufferfish end
+
+
public float getBukkitYaw() {
return this.yRot;
}
@@ -2625,7 +2645,20 @@ index dfd1f37757af1bd808cc2e2d8bf97123adf638bb..971e743cc99400681439de89252a29ee
return chunkMap.playerEntityTrackerTrackMaps[type.ordinal()].getObjectsInRange(MCUtil.getCoordinateKey(this));
}
@@ -3887,16 +3914,18 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -724,6 +751,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
// CraftBukkit end
public void baseTick() {
+ // Pufferfish start - entity TTL
+ if (type != EntityType.PLAYER && type.ttl >= 0 && this.tickCount >= type.ttl) {
+ remove(RemovalReason.DISCARDED);
+ return;
+ }
+ // Pufferfish end - entity TTL
this.level.getProfiler().push("entityBaseTick");
if (firstTick && this instanceof net.minecraft.world.entity.NeutralMob neutralMob) neutralMob.tickInitialPersistentAnger(level); // Paper - Update last hurt when ticking
this.feetBlockState = null;
@@ -3887,16 +3920,18 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
}
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tag, double speed) {
@@ -2651,7 +2684,7 @@ index dfd1f37757af1bd808cc2e2d8bf97123adf638bb..971e743cc99400681439de89252a29ee
double d1 = 0.0D;
boolean flag = this.isPushedByFluid();
boolean flag1 = false;
@@ -3904,14 +3933,61 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -3904,14 +3939,61 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
int k1 = 0;
BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos();
@@ -2719,7 +2752,7 @@ index dfd1f37757af1bd808cc2e2d8bf97123adf638bb..971e743cc99400681439de89252a29ee
if (d2 >= axisalignedbb.minY) {
flag1 = true;
@@ -3933,9 +4009,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -3933,9 +4015,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
// CraftBukkit end
}
}
@@ -2733,19 +2766,20 @@ index dfd1f37757af1bd808cc2e2d8bf97123adf638bb..971e743cc99400681439de89252a29ee
if (vec3d.length() > 0.0D) {
if (k1 > 0) {
diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java
index 79abd84696ef099f6b12ddeaa6e398f18c53316a..29169f9819ebbe0b90d87ed1e5833a3a57e39f06 100644
index 79abd84696ef099f6b12ddeaa6e398f18c53316a..5ec5e8a30c75b36412bacb0b60b560dfab7eeb22 100644
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
@@ -296,6 +296,7 @@ public class EntityType<T extends Entity> implements EntityTypeTest<Entity, T> {
@@ -296,6 +296,8 @@ public class EntityType<T extends Entity> implements EntityTypeTest<Entity, T> {
return Registry.ENTITY_TYPE.getOptional(ResourceLocation.tryParse(id));
}
+ public boolean dabEnabled = false; // Pufferfish
+ public int ttl = -1; // Pufferfish
// Paper start - add id
public final String id;
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index bd5825c5b5c81e0694a3635b981588f0d2ba83cb..2fe2307a10cb2e4e2b055cbe615b3750bf8fd310 100644
index d6ef140bcc35b10f78f2ec2f10c8a153395fc9df..33fbb85228f1570e40f2a825489362626bea3912 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -141,7 +141,6 @@ import org.bukkit.event.entity.EntityTeleportEvent;
@@ -4123,7 +4157,7 @@ index b1992ed5136cc7dcf04219868b94b3c37ae36b4b..5b5339cba819368f4d6b7eaf404fa59b
@Nullable
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index ab843069ac0653d03cf3f925f49555016cad84fa..ce1ca033b351785fb67304b8933990d7f2f22d29 100644
index 8a248e34fce1e04de4460f98b7627df495c66af1..04a1c7b37e44de50a1a201df3d61255b3bcd9b3e 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -249,7 +249,7 @@ import javax.annotation.Nullable; // Paper