diff --git a/README.md b/README.md
index 1527a78..244d63c 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
✨ SparklyPaper ✨
- 
+ 
SparklyPower's Paper fork, making large servers snappier with high-performance optimizations and improvements! Focused on performance improvements for Survival servers with high player counts.
diff --git a/build.gradle.kts b/build.gradle.kts
index 3b8d523..d923c62 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -16,7 +16,7 @@ repositories {
}
dependencies {
- remapper("net.fabricmc:tiny-remapper:0.10.2:fat") // Must be kept in sync with upstream
+ remapper("net.fabricmc:tiny-remapper:0.10.3:fat") // Must be kept in sync with upstream
decompiler("org.vineflower:vineflower:1.10.1") // Must be kept in sync with upstream
paperclip("io.papermc:paperclip:3.0.3") // You probably want this to be kept in sync with upstream
}
diff --git a/gradle.properties b/gradle.properties
index b41e7b3..2d0f69e 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,8 +1,8 @@
group=net.sparklypower.sparklypaper
-version=1.20.6-R0.1-SNAPSHOT
+version=1.21.1-R0.1-SNAPSHOT
-mcVersion=1.20.6
-paperRef=20f51650a9648c78e608d4d80f0e89dba24ac799
+mcVersion=1.21.1
+paperRef=e4b38b4f8c2d6647a36865b64f63df771b5e4041
org.gradle.caching=true
org.gradle.parallel=true
diff --git a/patches/api/0004-Parallel-world-ticking.patch b/patches/api/0004-Parallel-world-ticking.patch
index 4b9e8f5..54a49b4 100644
--- a/patches/api/0004-Parallel-world-ticking.patch
+++ b/patches/api/0004-Parallel-world-ticking.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Parallel world ticking
diff --git a/src/main/java/co/aikar/timings/Timings.java b/src/main/java/co/aikar/timings/Timings.java
-index 9812d668ad945aba486fbf6d5bf83c4292cb5d03..c82b9188c79a0671ca9d09d7cd31e63d5a378e9b 100644
+index e81d0bc309de877ed2b5da6122f55c162e9b5f10..718cbe97a2bc0e415ffaaf0aaa174ac1fbe71b4f 100644
--- a/src/main/java/co/aikar/timings/Timings.java
+++ b/src/main/java/co/aikar/timings/Timings.java
@@ -55,6 +55,7 @@ public final class Timings {
@@ -29,7 +29,7 @@ index 9812d668ad945aba486fbf6d5bf83c4292cb5d03..c82b9188c79a0671ca9d09d7cd31e63d
timingsEnabled = enabled;
warnAboutDeprecationOnEnable();
reset();
-@@ -180,6 +187,34 @@ public final class Timings {
+@@ -174,6 +181,34 @@ public final class Timings {
.build();
}
diff --git a/patches/api/0005-SPARKLYPOWER-Add-custom-blocks.patch b/patches/api/0005-SPARKLYPOWER-Add-custom-blocks.patch
index 4c08de0..ef4ff00 100644
--- a/patches/api/0005-SPARKLYPOWER-Add-custom-blocks.patch
+++ b/patches/api/0005-SPARKLYPOWER-Add-custom-blocks.patch
@@ -33,10 +33,10 @@ index be212b4fbeabab32a4dab6ae554768c368efaa88..fc885e551b1e8393569ec1391ee3decd
/**
diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java
-index 762216a117145676d3df2b74036799b024461fb7..5e7b8972f4a2bb21458049a552ebbfae2697f82b 100644
+index 54704da43cf9c429f3914f0580246dde99aa93c0..04ba1fa0eea60a8f01c89942cc8f3f8250192a72 100644
--- a/src/main/java/org/bukkit/Material.java
+++ b/src/main/java/org/bukkit/Material.java
-@@ -3818,6 +3818,22 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla
+@@ -3676,6 +3676,22 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla
BIG_DRIPLEAF_STEM(13167, Dripleaf.class),
POTTED_AZALEA_BUSH(20430),
POTTED_FLOWERING_AZALEA_BUSH(10609),
diff --git a/patches/server/0003-Optimize-entity-coordinate-key.patch b/patches/removed/server/0003-Optimize-entity-coordinate-key.patch
similarity index 100%
rename from patches/server/0003-Optimize-entity-coordinate-key.patch
rename to patches/removed/server/0003-Optimize-entity-coordinate-key.patch
diff --git a/patches/server/0001-new-fork-who-dis-Rebrand-to-SparklyPaper-and-Build-C.patch b/patches/server/0001-new-fork-who-dis-Rebrand-to-SparklyPaper-and-Build-C.patch
index 74db2a2..73792d4 100644
--- a/patches/server/0001-new-fork-who-dis-Rebrand-to-SparklyPaper-and-Build-C.patch
+++ b/patches/server/0001-new-fork-who-dis-Rebrand-to-SparklyPaper-and-Build-C.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] new fork who dis - Rebrand to SparklyPaper and Build Changes
diff --git a/build.gradle.kts b/build.gradle.kts
-index 4998aff0b7cb084dcda15c6a18bbe45e99b6000a..b2003e125fb923f531bf3777ebe39be0889601e4 100644
+index 421f6b3dc8890d63d2e7aa774d0bf8f7e15890ab..6c6d3af271c6b60304d6961fc22c7a84e0a8d342 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -3,6 +3,8 @@ import java.time.Instant
@@ -31,7 +31,7 @@ index 4998aff0b7cb084dcda15c6a18bbe45e99b6000a..b2003e125fb923f531bf3777ebe39be0
// Paper start
implementation("org.jline:jline-terminal-jansi:3.21.0")
implementation("net.minecrell:terminalconsoleappender:1.3.0")
-@@ -75,7 +82,12 @@ tasks.jar {
+@@ -79,7 +86,12 @@ tasks.jar {
val mcVersion = rootProject.providers.gradleProperty("mcVersion").get()
val build = System.getenv("BUILD_NUMBER") ?: null
val gitHash = git("rev-parse", "--short=7", "HEAD").getText().trim()
@@ -45,7 +45,7 @@ index 4998aff0b7cb084dcda15c6a18bbe45e99b6000a..b2003e125fb923f531bf3777ebe39be0
val date = git("show", "-s", "--format=%ci", gitHash).getText().trim() // Paper
val gitBranch = git("rev-parse", "--abbrev-ref", "HEAD").getText().trim() // Paper
attributes(
-@@ -86,8 +98,8 @@ tasks.jar {
+@@ -90,8 +102,8 @@ tasks.jar {
"Specification-Title" to "Paper",
"Specification-Version" to project.version,
"Specification-Vendor" to "Paper Team",
@@ -70,10 +70,10 @@ index 774556a62eb240da42e84db4502e2ed43495be17..9bc7b99b5b39a8ffe4118b8d86f5b806
if (stream != null) {
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
-index 6db566e3111ec08a99aa429624979cb83a85e272..ac350a7108a54c64cf162a683f979a04712ce4c6 100644
+index f7a4fee9bb25ff256dc2e5ea26bfbceca6a49167..e7321e56c6ba3c601641c6466857331e9fe5f4bb 100644
--- a/src/main/java/org/spigotmc/WatchdogThread.java
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
-@@ -155,14 +155,14 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
+@@ -155,14 +155,14 @@ public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThre
if (isLongTimeout) {
// Paper end
log.log( Level.SEVERE, "------------------------------" );
@@ -91,12 +91,12 @@ index 6db566e3111ec08a99aa429624979cb83a85e272..ac350a7108a54c64cf162a683f979a04
//
if ( net.minecraft.world.level.Level.lastPhysicsProblem != null )
{
-@@ -189,7 +189,7 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
+@@ -189,7 +189,7 @@ public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThre
}
// Paper end - Different message for short timeout
log.log( Level.SEVERE, "------------------------------" );
- log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper
+ log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to SparklyPaper!):" ); // SparklyPaper - branding changes // Paper
- io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.dumpAllChunkLoadInfo(isLongTimeout); // Paper - rewrite chunk system
+ ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler.dumpAllChunkLoadInfo(MinecraftServer.getServer(), isLongTimeout); // Paper - rewrite chunk system
this.dumpTickingInfo(); // Paper - log detailed tick information
WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log );
diff --git a/patches/server/0002-SparklyPaper-config-files.patch b/patches/server/0002-SparklyPaper-config-files.patch
index 3952c4e..08cebee 100644
--- a/patches/server/0002-SparklyPaper-config-files.patch
+++ b/patches/server/0002-SparklyPaper-config-files.patch
@@ -5,12 +5,12 @@ Subject: [PATCH] SparklyPaper config files
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
-index ad967cc2283f902c76e48a59d59cf0dbdacbb5e3..1fd163c4a4fdcbdb2626f15a4549c41c5e69e061 100644
+index dd56c8e041116ef3602a9f89c998c8208ab89b51..b7c39d2e93abbc5f988271d738490de68ce50b3b 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
-@@ -232,6 +232,15 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
- thread.start(); // Paper - Enhance console tab completions for brigadier commands; start console thread after MinecraftServer.console & PaperConfig are initialized
+@@ -238,6 +238,15 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
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
+ // SparklyPaper start
+ try {
@@ -25,10 +25,10 @@ index ad967cc2283f902c76e48a59d59cf0dbdacbb5e3..1fd163c4a4fdcbdb2626f15a4549c41c
this.setPvpAllowed(dedicatedserverproperties.pvp);
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
-index 14281a4e72f49dc4eb2ca3da8479c1f81a3a175d..5ff499481583d4cb68297b8600d5ea210eceece9 100644
+index e2a0487089eb5a7bdc1433e4c75f69d8e9f9d5f9..e086114c3d4b1d8ed46eec98e4b66cfc21451139 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
-@@ -171,6 +171,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+@@ -173,6 +173,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
// Paper end - add paper world config
public final com.destroystokyo.paper.antixray.ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray
@@ -36,8 +36,8 @@ index 14281a4e72f49dc4eb2ca3da8479c1f81a3a175d..5ff499481583d4cb68297b8600d5ea21
public final co.aikar.timings.WorldTimingsHandler timings; // Paper
public static BlockPos lastPhysicsProblem; // Spigot
private org.spigotmc.TickLimiter entityLimiter;
-@@ -208,6 +209,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
- protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator, java.util.concurrent.Executor executor) { // Paper - create paper world config; Async-Anti-Xray: Pass executor
+@@ -687,6 +688,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
+ protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator, java.util.concurrent.Executor executor) { // Paper - create paper world config & Anti-Xray
this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot
this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config
+ this.sparklyPaperConfig = net.sparklypower.sparklypaper.configs.SparklyPaperConfigUtils.INSTANCE.getWorldSettings(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // SparklyPaper
@@ -116,7 +116,7 @@ index 0000000000000000000000000000000000000000..bc0ec96f91f7c9ab9f9a865a50f69707
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 5db08432b6afd3639688830e717f40ceaf599248..06cda121c38a4d90e9f324db7482c92796209477 100644
+index 1b36e94617d4e777c419660936460d5cf8a4b3e8..cfd75fdc75866a70008837b4b0e2e6a3bad3da16 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -111,6 +111,7 @@ import net.minecraft.world.level.storage.PlayerDataStorage;
@@ -127,7 +127,7 @@ index 5db08432b6afd3639688830e717f40ceaf599248..06cda121c38a4d90e9f324db7482c927
import org.bukkit.BanList;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
-@@ -1056,6 +1057,7 @@ public final class CraftServer implements Server {
+@@ -1070,6 +1071,7 @@ public final class CraftServer implements Server {
org.spigotmc.SpigotConfig.init((File) this.console.options.valueOf("spigot-settings")); // Spigot
this.console.paperConfigurations.reloadConfigs(this.console);
@@ -135,7 +135,7 @@ index 5db08432b6afd3639688830e717f40ceaf599248..06cda121c38a4d90e9f324db7482c927
for (ServerLevel world : this.console.getAllLevels()) {
// world.serverLevelData.setDifficulty(config.difficulty); // Paper - per level difficulty
world.setSpawnSettings(world.serverLevelData.getDifficulty() != Difficulty.PEACEFUL && config.spawnMonsters, config.spawnAnimals); // Paper - per level difficulty (from MinecraftServer#setDifficulty(ServerLevel, Difficulty, boolean))
-@@ -1071,6 +1073,7 @@ public final class CraftServer implements Server {
+@@ -1085,6 +1087,7 @@ public final class CraftServer implements Server {
}
}
world.spigotConfig.init(); // Spigot
@@ -143,16 +143,16 @@ index 5db08432b6afd3639688830e717f40ceaf599248..06cda121c38a4d90e9f324db7482c927
}
Plugin[] pluginClone = pluginManager.getPlugins().clone(); // Paper
-@@ -1087,6 +1090,7 @@ public final class CraftServer implements Server {
- this.reloadData();
+@@ -1102,6 +1105,7 @@ public final class CraftServer implements Server {
org.spigotmc.SpigotConfig.registerCommands(); // Spigot
io.papermc.paper.command.PaperCommands.registerCommands(this.console); // Paper
+ this.spark.registerCommandBeforePlugins(this); // Paper - spark
+ net.sparklypower.sparklypaper.SparklyPaperCommands.INSTANCE.registerCommands(this.console); // SparklyPaper
this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*");
this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions");
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
-index b86ba59158964f73abd6622341a9acb98a33fa44..8ef6c2d1f69864eae5c36f3abd87cc179eb14992 100644
+index c1e88c31910e96ef07cece05046c0b55e708b52d..913249209d9c22ad4d111b49d1d1eeeab163b13a 100644
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
@@ -176,6 +176,14 @@ public class Main {
diff --git a/patches/server/0004-Rewrite-framed-map-tracker-ticking.patch b/patches/server/0003-Rewrite-framed-map-tracker-ticking.patch
similarity index 93%
rename from patches/server/0004-Rewrite-framed-map-tracker-ticking.patch
rename to patches/server/0003-Rewrite-framed-map-tracker-ticking.patch
index 8afd12e..7ec7496 100644
--- a/patches/server/0004-Rewrite-framed-map-tracker-ticking.patch
+++ b/patches/server/0003-Rewrite-framed-map-tracker-ticking.patch
@@ -11,10 +11,10 @@ now is just updating dirty map/decoration data.
When no bukkit renderers are added to the map, we also re-use the same packet for all players who are tracking it which avoids a lot of work.
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
-index a2279262c93408c11f5d2290b48fd794975e8cfe..7392a058bab0eca23cb82392d5b5cc50e8601499 100644
+index 8ea2f24695f5dad55e21f238b69442513e7a90c6..e8781c8857d4b8b241515c811a4686feda437abb 100644
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
-@@ -120,27 +120,40 @@ public class ServerEntity {
+@@ -124,27 +124,40 @@ public class ServerEntity {
Entity entity = this.entity;
@@ -60,7 +60,7 @@ index a2279262c93408c11f5d2290b48fd794975e8cfe..7392a058bab0eca23cb82392d5b5cc50
}
}
-@@ -382,6 +395,19 @@ public class ServerEntity {
+@@ -383,6 +396,19 @@ public class ServerEntity {
}
}
@@ -79,12 +79,12 @@ index a2279262c93408c11f5d2290b48fd794975e8cfe..7392a058bab0eca23cb82392d5b5cc50
+ // Paper end
}
- private void sendDirtyEntityData() {
+ public Vec3 getPositionBase() {
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java
-index da0d1c9a1c4ae081bff9ca4230c9a1503885c354..c6f6e3588f7cb966af6d67dcec765b041869baae 100644
+index 5b7245cd99593ee90e17c97e0104f3aba9ae05ea..03432d084f8ed0cb7716d612b35f740943dcc4c0 100644
--- a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java
+++ b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java
-@@ -461,6 +461,16 @@ public class ItemFrame extends HangingEntity {
+@@ -419,6 +419,16 @@ public class ItemFrame extends HangingEntity {
}
this.setItem(ItemStack.fromBukkitCopy(event.getItemStack()));
// Paper end - Add PlayerItemFrameChangeEvent
@@ -102,10 +102,10 @@ index da0d1c9a1c4ae081bff9ca4230c9a1503885c354..c6f6e3588f7cb966af6d67dcec765b04
itemstack.consume(1, player);
}
diff --git a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
-index cf8ae635fce7ea66d4e1ab1dc05575f035fa95ef..6e3eb9a28b6c190acfe37a03efce573da2da2749 100644
+index 17f33c83c6033564d6bf4fbd388b0b847c68adb3..6bcb565cd60b60be9255ef537591ee821caab7b5 100644
--- a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
+++ b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
-@@ -79,6 +79,16 @@ public class MapItemSavedData extends SavedData {
+@@ -80,6 +80,16 @@ public class MapItemSavedData extends SavedData {
private final Map frameMarkers = Maps.newHashMap();
private int trackedDecorationCount;
private org.bukkit.craftbukkit.map.RenderData vanillaRender = new org.bukkit.craftbukkit.map.RenderData(); // Paper
@@ -122,7 +122,7 @@ index cf8ae635fce7ea66d4e1ab1dc05575f035fa95ef..6e3eb9a28b6c190acfe37a03efce573d
// CraftBukkit start
public final CraftMapView mapView;
-@@ -351,6 +361,7 @@ public class MapItemSavedData extends SavedData {
+@@ -352,6 +362,7 @@ public class MapItemSavedData extends SavedData {
}
this.setDecorationsDirty();
@@ -130,7 +130,7 @@ index cf8ae635fce7ea66d4e1ab1dc05575f035fa95ef..6e3eb9a28b6c190acfe37a03efce573d
}
public static void addTargetDecoration(ItemStack stack, BlockPos pos, String id, Holder decorationType) {
-@@ -432,6 +443,7 @@ public class MapItemSavedData extends SavedData {
+@@ -433,6 +444,7 @@ public class MapItemSavedData extends SavedData {
}
this.setDecorationsDirty();
@@ -138,7 +138,7 @@ index cf8ae635fce7ea66d4e1ab1dc05575f035fa95ef..6e3eb9a28b6c190acfe37a03efce573d
}
}
-@@ -445,6 +457,20 @@ public class MapItemSavedData extends SavedData {
+@@ -446,6 +458,20 @@ public class MapItemSavedData extends SavedData {
public void setColorsDirty(int x, int z) {
this.setDirty();
@@ -159,16 +159,16 @@ index cf8ae635fce7ea66d4e1ab1dc05575f035fa95ef..6e3eb9a28b6c190acfe37a03efce573d
Iterator iterator = this.carriedBy.iterator();
while (iterator.hasNext()) {
-@@ -527,6 +553,7 @@ public class MapItemSavedData extends SavedData {
+@@ -528,6 +554,7 @@ public class MapItemSavedData extends SavedData {
public void removedFromFrame(BlockPos pos, int id) {
- this.removeDecoration("frame-" + id);
+ this.removeDecoration(MapItemSavedData.getFrameKey(id));
this.frameMarkers.remove(MapFrame.frameId(pos));
+ this.dirtyFrameDecorations = true; // Paper
}
public boolean updateColor(int x, int z, byte color) {
-@@ -584,6 +611,93 @@ public class MapItemSavedData extends SavedData {
- return this.trackedDecorationCount >= decorationCount;
+@@ -589,6 +616,93 @@ public class MapItemSavedData extends SavedData {
+ return "frame-" + id;
}
+ // Paper start
diff --git a/patches/server/0005-Skip-distanceToSqr-call-in-ServerEntity-sendChanges-.patch b/patches/server/0004-Skip-distanceToSqr-call-in-ServerEntity-sendChanges-.patch
similarity index 68%
rename from patches/server/0005-Skip-distanceToSqr-call-in-ServerEntity-sendChanges-.patch
rename to patches/server/0004-Skip-distanceToSqr-call-in-ServerEntity-sendChanges-.patch
index d248d89..9ea8558 100644
--- a/patches/server/0005-Skip-distanceToSqr-call-in-ServerEntity-sendChanges-.patch
+++ b/patches/server/0004-Skip-distanceToSqr-call-in-ServerEntity-sendChanges-.patch
@@ -9,19 +9,20 @@ The "distanceToSqr" call is a bit expensive, so avoiding it is pretty nice, arou
We could also check if the x,y,z coordinates are equal, but for now, let's just keep the identity check, which also helps us since Minecraft's code does reuse the original delta movement Vec3 object
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
-index 7392a058bab0eca23cb82392d5b5cc50e8601499..072aa9f0cd26602c0251819fd02711078382f9da 100644
+index e8781c8857d4b8b241515c811a4686feda437abb..aafa06b3730fa3826941cbec7177b58fbd672040 100644
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
-@@ -228,12 +228,14 @@ public class ServerEntity {
+@@ -229,6 +229,7 @@ public class ServerEntity {
if ((this.trackDelta || this.entity.hasImpulse || this.entity instanceof LivingEntity && ((LivingEntity) this.entity).isFallFlying()) && this.tickCount > 0) {
Vec3 vec3d1 = this.entity.getDeltaMovement();
-+ if (vec3d1 != this.ap) { // SparklyPaper start - skip distanceToSqr call in ServerEntity#sendChanges if the delta movement hasn't changed
- double d0 = vec3d1.distanceToSqr(this.ap);
++ if (vec3d1 != this.lastSentMovement) { // SparklyPaper start - skip distanceToSqr call in ServerEntity#sendChanges if the delta movement hasn't changed
+ double d0 = vec3d1.distanceToSqr(this.lastSentMovement);
if (d0 > 1.0E-7D || d0 > 0.0D && vec3d1.lengthSqr() == 0.0D) {
- this.ap = vec3d1;
- this.broadcast.accept(new ClientboundSetEntityMotionPacket(this.entity.getId(), this.ap));
+@@ -243,6 +244,7 @@ public class ServerEntity {
+ this.broadcast.accept(new ClientboundSetEntityMotionPacket(this.entity.getId(), this.lastSentMovement));
+ }
}
+ } // SparklyPaper end
}
diff --git a/patches/server/0006-Skip-MapItem-update-if-the-map-does-not-have-the-Cra.patch b/patches/server/0005-Skip-MapItem-update-if-the-map-does-not-have-the-Cra.patch
similarity index 100%
rename from patches/server/0006-Skip-MapItem-update-if-the-map-does-not-have-the-Cra.patch
rename to patches/server/0005-Skip-MapItem-update-if-the-map-does-not-have-the-Cra.patch
diff --git a/patches/server/0007-Fix-concurrency-issues-when-using-imageToBytes-in-mu.patch b/patches/server/0006-Fix-concurrency-issues-when-using-imageToBytes-in-mu.patch
similarity index 100%
rename from patches/server/0007-Fix-concurrency-issues-when-using-imageToBytes-in-mu.patch
rename to patches/server/0006-Fix-concurrency-issues-when-using-imageToBytes-in-mu.patch
diff --git a/patches/server/0008-Skip-dirty-stats-copy-when-requesting-player-stats.patch b/patches/server/0007-Skip-dirty-stats-copy-when-requesting-player-stats.patch
similarity index 95%
rename from patches/server/0008-Skip-dirty-stats-copy-when-requesting-player-stats.patch
rename to patches/server/0007-Skip-dirty-stats-copy-when-requesting-player-stats.patch
index 2a42196..2a89ece 100644
--- a/patches/server/0008-Skip-dirty-stats-copy-when-requesting-player-stats.patch
+++ b/patches/server/0007-Skip-dirty-stats-copy-when-requesting-player-stats.patch
@@ -6,7 +6,7 @@ Subject: [PATCH] Skip dirty stats copy when requesting player stats
There's literally only one getDirty call. Because the map was only retrieved once, we don't actually need to create a copy of the map just to iterate it, we can just access it directly and clear it manually after use.
diff --git a/src/main/java/net/minecraft/stats/ServerStatsCounter.java b/src/main/java/net/minecraft/stats/ServerStatsCounter.java
-index f890738d3bb9fb5e70a9d323c6cec97f9948f9cf..8685cb5bbfa26b0d77c6fdde8cf2dc8bebc06585 100644
+index fb7342f7a5008a283c3400c6313c637de8210dfa..1f9b3cacb276c144ecbef104e5d598b78dc0c025 100644
--- a/src/main/java/net/minecraft/stats/ServerStatsCounter.java
+++ b/src/main/java/net/minecraft/stats/ServerStatsCounter.java
@@ -90,12 +90,16 @@ public class ServerStatsCounter extends StatsCounter {
diff --git a/patches/server/0009-Skip-EntityScheduler-s-executeTick-checks-if-there-i.patch b/patches/server/0008-Skip-EntityScheduler-s-executeTick-checks-if-there-i.patch
similarity index 90%
rename from patches/server/0009-Skip-EntityScheduler-s-executeTick-checks-if-there-i.patch
rename to patches/server/0008-Skip-EntityScheduler-s-executeTick-checks-if-there-i.patch
index bea7c09..70ee23d 100644
--- a/patches/server/0009-Skip-EntityScheduler-s-executeTick-checks-if-there-i.patch
+++ b/patches/server/0008-Skip-EntityScheduler-s-executeTick-checks-if-there-i.patch
@@ -11,7 +11,7 @@ To avoid the hefty ArrayDeque's size() call, we check if we *really* need to exe
Most entities won't have any scheduled tasks, so this is a nice performance bonus. These optimizations, however, wouldn't work in a Folia environment, but because in SparklyPaper executeTick is always executed on the main thread, it ain't an issue for us (yay).
diff --git a/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java b/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java
-index 62484ebf4550b05182f693a3180bbac5d5fd906d..67800e426445060a8343e27a7452b8d7ed27ac5f 100644
+index c03608fec96b51e1867f43d8f42e5aefb1520e46..15b21fa3907db1b77ed5b5d1050a37f42d27d5ab 100644
--- a/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java
+++ b/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java
@@ -36,6 +36,7 @@ public final class EntityScheduler {
@@ -73,10 +73,10 @@ index 62484ebf4550b05182f693a3180bbac5d5fd906d..67800e426445060a8343e27a7452b8d7
throw new IllegalStateException("Ticking retired scheduler");
}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 0ed42fa899721f83b598db05be1b5f321af3614a..1148b3ab0a582fff17f0101516df4b5037b49aba 100644
+index 23ddd26af762c1cd7fb3920669abb96b3213ab37..7f2e25b2ebb8fb698a4adb12d77670e126549405 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
-@@ -316,7 +316,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) {
AtomicReference atomicreference = new AtomicReference();
- Thread thread = new io.papermc.paper.util.TickThread(() -> { // Paper - rewrite chunk system
-@@ -1700,6 +1701,18 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { // Paper - rewrite chunk system
+@@ -1727,6 +1728,18 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop {
- for (final Entity entity : level.getEntityLookup().getAllCopy()) { // Paper - rewrite chunk system
+ for (final Entity entity : level.moonrise$getEntityLookup().getAllCopy()) { // Paper - rewrite chunk system
if (entity.isRemoved()) {
-@@ -1711,6 +1724,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop entitiesWithScheduledTasks = java.util.concurrent.ConcurrentHashMap.newKeySet(); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run (concurrent because plugins may schedule tasks async)
@@ -22,12 +22,12 @@ index 1148b3ab0a582fff17f0101516df4b5037b49aba..b635a473d2a19bbefc24e86455ec6735
+
public static S spin(Function serverFactory) {
AtomicReference atomicreference = new AtomicReference();
- Thread thread = new io.papermc.paper.util.TickThread(() -> { // Paper - rewrite chunk system
+ Thread thread = new ca.spottedleaf.moonrise.common.util.TickThread(() -> { // Paper - rewrite chunk system
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
-index ac8565be2334efe48d5bdc3f58bf60fb9f715da7..859faaf21635caca2a2ab471ac3d4569f04ba69b 100644
+index b7c39d2e93abbc5f988271d738490de68ce50b3b..1395e8f98bd87a060fb609c65a3311c220f5e9a8 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
-@@ -241,6 +241,10 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
+@@ -247,6 +247,10 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
}
net.sparklypower.sparklypaper.SparklyPaperCommands.INSTANCE.registerCommands(this);
// SparklyPaper end
@@ -69,10 +69,10 @@ index dc27ddf5131e7398a5390a5187261d4c7fb6ccaa..6c8664c9cf75a88007e43348059fad7e
private void setupAnimationStates() {
if (this.isResting()) {
diff --git a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
-index 0c5fe46d2da113beff3e220843593d616e37d4ca..26b81b6a0111e2149020b8a8f934f2660f59780e 100644
+index 3b5cf6ffb74d11bea5eb21bd66d679734ff5000c..97bdeb56fee6fb4ae924973730e34dbf933eef68 100644
--- a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
+++ b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
-@@ -154,10 +154,12 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
+@@ -157,10 +157,12 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
this.setCanPickUpLoot(this.level().paperConfig().entities.behavior.mobsCanAlwaysPickUpLoot.skeletons || randomsource.nextFloat() < 0.55F * difficulty.getSpecialMultiplier()); // Paper - Add world settings for mobs picking up loot
if (this.getItemBySlot(EquipmentSlot.HEAD).isEmpty()) {
LocalDate localdate = LocalDate.now();
@@ -89,10 +89,10 @@ index 0c5fe46d2da113beff3e220843593d616e37d4ca..26b81b6a0111e2149020b8a8f934f266
this.armorDropChances[EquipmentSlot.HEAD.getIndex()] = 0.0F;
}
diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
-index e42dfc62bb179be1ab01b0096c05c6549d38abbc..14292ee06e065b0043f5cb087072e3d0fa11291a 100644
+index 2280004638fd19ed018cb3e77d53a018b34ec516..fb15112f920174d7ea6a3bd683418772c0910780 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
-@@ -542,10 +542,11 @@ public class Zombie extends Monster {
+@@ -553,10 +553,11 @@ public class Zombie extends Monster {
if (this.getItemBySlot(EquipmentSlot.HEAD).isEmpty()) {
LocalDate localdate = LocalDate.now();
diff --git a/patches/server/0013-Optimize-canSee-checks.patch b/patches/server/0011-Optimize-canSee-checks.patch
similarity index 91%
rename from patches/server/0013-Optimize-canSee-checks.patch
rename to patches/server/0011-Optimize-canSee-checks.patch
index cfa6ee3..d29f0bd 100644
--- a/patches/server/0013-Optimize-canSee-checks.patch
+++ b/patches/server/0011-Optimize-canSee-checks.patch
@@ -14,10 +14,10 @@ This seems stupid, but it does seem that it improves the performance a bit, and
We also create a "canSee" method tailored for "ChunkMap#updatePlayer()", a method without the equals check (the "updatePlayer()" already checks if the entity is the same entity) because the CraftPlayer's `equals()` check is a *bit* expensive compared to only checking the object's identity, and because the identity has already been check, we don't need to check it twice.
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 7fb9ba3dadb1eca4a1000ea8cf4d13fed2b7db1e..b1301d9b6467ba8700e4d86a8fe83fa48ec829e0 100644
+index 1e0a6e5a3c907ab55ee6f2780a7d43bd455f2b7b..15bc677119ae394e0334e2570bc01d774fe1a264 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -1439,7 +1439,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1257,7 +1257,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
// Paper end - Configurable entity tracking range by Y
// CraftBukkit start - respect vanish API
@@ -27,10 +27,10 @@ index 7fb9ba3dadb1eca4a1000ea8cf4d13fed2b7db1e..b1301d9b6467ba8700e4d86a8fe83fa4
}
// CraftBukkit end
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index 32c3c2c6b2eaa90b149d9b425341e75b85bd9764..2eb99dbb2c2574c5339686c0c105ceb8bf5beee9 100644
+index a0d5082590ee03060f0dbb4770d196efc316c328..00c6e2ab7e79750a7eef8d25c03caa787b011b14 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-@@ -198,7 +198,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
+@@ -200,7 +200,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
private boolean hasPlayedBefore = false;
private final ConversationTracker conversationTracker = new ConversationTracker();
private final Set channels = new HashSet();
@@ -39,7 +39,7 @@ index 32c3c2c6b2eaa90b149d9b425341e75b85bd9764..2eb99dbb2c2574c5339686c0c105ceb8
private final Set unlistedEntities = new HashSet<>(); // Paper - Add Listing API for Player
private static final WeakHashMap> pluginWeakReferences = new WeakHashMap<>();
private int hash = 0;
-@@ -2229,9 +2229,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
+@@ -2248,9 +2248,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@Override
public boolean canSee(org.bukkit.entity.Entity entity) {
diff --git a/patches/server/0012-Cache-coordinate-key-used-for-nearby-players-when-ti.patch b/patches/server/0012-Cache-coordinate-key-used-for-nearby-players-when-ti.patch
deleted file mode 100644
index 023254b..0000000
--- a/patches/server/0012-Cache-coordinate-key-used-for-nearby-players-when-ti.patch
+++ /dev/null
@@ -1,66 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: MrPowerGamerBR
-Date: Wed, 22 Nov 2023 11:07:07 -0300
-Subject: [PATCH] Cache coordinate key used for nearby players when ticking
- chunks
-
-The "getChunkKey(...)" call is a bit expensive, using 0.24% of CPU time with 19k chunks loaded
-
-So instead of paying the price on each tick, we pay the price when the chunk is loaded
-
-Which, if you think about it, is actually better, since we tick chunks more than we load chunks
-
-diff --git a/src/main/java/io/papermc/paper/util/player/NearbyPlayers.java b/src/main/java/io/papermc/paper/util/player/NearbyPlayers.java
-index f164256d59b761264876ca0c85f812d101bfd5de..10465a33d90a1e43b9dbd7764c895dd39ef11b1a 100644
---- a/src/main/java/io/papermc/paper/util/player/NearbyPlayers.java
-+++ b/src/main/java/io/papermc/paper/util/player/NearbyPlayers.java
-@@ -106,6 +106,14 @@ public final class NearbyPlayers {
- return chunk == null ? null : chunk.players[type.ordinal()];
- }
-
-+ // SparklyPaper start - cache coordinate key used for nearby players
-+ public ReferenceList getPlayers(final long nearbyPlayersCoordinateKey, final NearbyMapType type) {
-+ final TrackedChunk chunk = this.byChunk.get(nearbyPlayersCoordinateKey);
-+
-+ return chunk == null ? null : chunk.players[type.ordinal()];
-+ }
-+ // SparklyPaper end
-+
- public ReferenceList getPlayersByChunk(final int chunkX, final int chunkZ, final NearbyMapType type) {
- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ));
-
-diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-index b99f50604bafecbc68835974c9ed0caa91911a40..07fa0b2c43f395a5d9a8f90d5b517e2eb39ce4ba 100644
---- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-@@ -607,7 +607,7 @@ public class ServerChunkCache extends ChunkSource {
-
- // Paper start - optimise chunk tick iteration
- com.destroystokyo.paper.util.maplist.ReferenceList playersNearby
-- = nearbyPlayers.getPlayers(chunkcoordintpair, io.papermc.paper.util.player.NearbyPlayers.NearbyMapType.SPAWN_RANGE);
-+ = nearbyPlayers.getPlayers(chunk1.nearbyPlayersCoordinateKey, io.papermc.paper.util.player.NearbyPlayers.NearbyMapType.SPAWN_RANGE); // nearbyPlayers.getPlayers(chunkcoordintpair, io.papermc.paper.util.player.NearbyPlayers.NearbyMapType.SPAWN_RANGE); // SparklyPaper - cache coordinate key used for nearby players
- if (playersNearby == null) {
- continue;
- }
-diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
-index 1aac95b03a9e2e37c24f2a30bcb259c1424e1c78..1ac1af72a71bbf402f0d1633a4b8c9a408917d73 100644
---- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
-+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
-@@ -65,7 +65,7 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom
- protected final ShortList[] postProcessing;
- protected volatile boolean unsaved;
- private volatile boolean isLightCorrect;
-- protected final ChunkPos chunkPos; public final long coordinateKey; public final int locX; public final int locZ; // Paper - cache coordinate key
-+ protected final ChunkPos chunkPos; public final long coordinateKey; public final long nearbyPlayersCoordinateKey; public final int locX; public final int locZ; // Paper - cache coordinate key // SparklyPaper - cache coordinate key used for nearby players
- private long inhabitedTime;
- /** @deprecated */
- @Nullable
-@@ -139,7 +139,7 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom
- }
- // Paper end - rewrite light engine
- this.locX = pos.x; this.locZ = pos.z; // Paper - reduce need for field lookups
-- this.chunkPos = pos; this.coordinateKey = ChunkPos.asLong(locX, locZ); // Paper - cache long key
-+ this.chunkPos = pos; this.coordinateKey = ChunkPos.asLong(locX, locZ); this.nearbyPlayersCoordinateKey = io.papermc.paper.util.CoordinateUtils.getChunkKey(locX, locZ); // Paper - cache long key // SparklyPaper - cache coordinate key used for nearby players
- this.upgradeData = upgradeData;
- this.levelHeightAccessor = heightLimitView;
- this.sections = new LevelChunkSection[heightLimitView.getSectionsCount()];
diff --git a/patches/server/0014-Revert-Fix-MC-117075-Block-entity-unload-lag-spike.patch b/patches/server/0012-Revert-Fix-MC-117075-Block-entity-unload-lag-spike.patch
similarity index 77%
rename from patches/server/0014-Revert-Fix-MC-117075-Block-entity-unload-lag-spike.patch
rename to patches/server/0012-Revert-Fix-MC-117075-Block-entity-unload-lag-spike.patch
index a0e95b3..269f90a 100644
--- a/patches/server/0014-Revert-Fix-MC-117075-Block-entity-unload-lag-spike.patch
+++ b/patches/server/0012-Revert-Fix-MC-117075-Block-entity-unload-lag-spike.patch
@@ -6,11 +6,11 @@ Subject: [PATCH] Revert "Fix MC-117075: Block entity unload lag spike"
This reverts commit f3453b204569ea865cc1d1302edb6d125e7f0cb3.
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
-index 5ff499481583d4cb68297b8600d5ea210eceece9..2144ffc34b2fc233f85c8ff56eefefde2a4b16ef 100644
+index e086114c3d4b1d8ed46eec98e4b66cfc21451139..2d44c17a63b12df0e3c5b39cb9a80924470a8428 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
-@@ -1268,8 +1268,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
- boolean flag = this.tickRateManager().runsNormally();
+@@ -1387,8 +1387,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
+ int tickedEntities = 0; // Paper - rewrite chunk system
int tilesThisCycle = 0;
- var toRemove = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet(); // Paper - Fix MC-117075; use removeAll
@@ -18,7 +18,7 @@ index 5ff499481583d4cb68297b8600d5ea210eceece9..2144ffc34b2fc233f85c8ff56eefefde
for (tileTickPosition = 0; tileTickPosition < this.blockEntityTickers.size(); tileTickPosition++) { // Paper - Disable tick limiters
this.tileTickPosition = (this.tileTickPosition < this.blockEntityTickers.size()) ? this.tileTickPosition : 0;
TickingBlockEntity tickingblockentity = (TickingBlockEntity) this.blockEntityTickers.get(this.tileTickPosition);
-@@ -1278,7 +1276,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+@@ -1397,7 +1395,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
if (tickingblockentity.isRemoved()) {
// Spigot start
tilesThisCycle--;
@@ -27,8 +27,8 @@ index 5ff499481583d4cb68297b8600d5ea210eceece9..2144ffc34b2fc233f85c8ff56eefefde
// Spigot end
} else if (flag && this.shouldTickBlocksAt(tickingblockentity.getPos())) {
tickingblockentity.tick();
-@@ -1289,7 +1287,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
- // Paper end - execute chunk tasks during tick
+@@ -1408,7 +1406,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
+ // Paper end - rewrite chunk system
}
}
- this.blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075
diff --git a/patches/server/0015-Fix-MC-117075-TE-Unload-Lag-Spike.patch b/patches/server/0013-Fix-MC-117075-TE-Unload-Lag-Spike.patch
similarity index 94%
rename from patches/server/0015-Fix-MC-117075-TE-Unload-Lag-Spike.patch
rename to patches/server/0013-Fix-MC-117075-TE-Unload-Lag-Spike.patch
index c8a41cd..49e6f3b 100644
--- a/patches/server/0015-Fix-MC-117075-TE-Unload-Lag-Spike.patch
+++ b/patches/server/0013-Fix-MC-117075-TE-Unload-Lag-Spike.patch
@@ -8,10 +8,10 @@ We replaced the `blockEntityTickers` list with a custom list based on fastutil's
This is WAY FASTER than using `removeAll` with a list of entries to be removed, because we don't need to calculate the identity of each block entity to be removed, and we can jump directly to where the search should begin, giving a performance boost for small removals (because we don't need to loop thru the entire list to find what element should be removed) and a performance boost for big removals (no need to calculate the identity of each block entity).
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
-index 2144ffc34b2fc233f85c8ff56eefefde2a4b16ef..65d1d84bf4c381492d394bb61055cfa308ce24f7 100644
+index 2d44c17a63b12df0e3c5b39cb9a80924470a8428..32b782bab750351caddafe6d6327e406bb26fb93 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
-@@ -114,7 +114,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+@@ -116,7 +116,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
public static final int TICKS_PER_DAY = 24000;
public static final int MAX_ENTITY_SPAWN_Y = 20000000;
public static final int MIN_ENTITY_SPAWN_Y = -20000000;
@@ -20,7 +20,7 @@ index 2144ffc34b2fc233f85c8ff56eefefde2a4b16ef..65d1d84bf4c381492d394bb61055cfa3
protected final NeighborUpdater neighborUpdater;
private final List pendingBlockEntityTickers = Lists.newArrayList();
private boolean tickingBlockEntities;
-@@ -1276,7 +1276,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+@@ -1395,7 +1395,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
if (tickingblockentity.isRemoved()) {
// Spigot start
tilesThisCycle--;
@@ -29,8 +29,8 @@ index 2144ffc34b2fc233f85c8ff56eefefde2a4b16ef..65d1d84bf4c381492d394bb61055cfa3
// Spigot end
} else if (flag && this.shouldTickBlocksAt(tickingblockentity.getPos())) {
tickingblockentity.tick();
-@@ -1287,7 +1287,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
- // Paper end - execute chunk tasks during tick
+@@ -1406,7 +1406,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
+ // Paper end - rewrite chunk system
}
}
-
diff --git a/patches/server/0016-Optimize-tickBlockEntities.patch b/patches/server/0014-Optimize-tickBlockEntities.patch
similarity index 84%
rename from patches/server/0016-Optimize-tickBlockEntities.patch
rename to patches/server/0014-Optimize-tickBlockEntities.patch
index 44ac47e..d904a76 100644
--- a/patches/server/0016-Optimize-tickBlockEntities.patch
+++ b/patches/server/0014-Optimize-tickBlockEntities.patch
@@ -12,11 +12,11 @@ But here's the thing: We don't care if we have a small performance penalty if th
And finally, we also cache the chunk's coordinate key when creating the block entity, which is actually "free" because we just reuse the already cached chunk coordinate key from the chunk!
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
-index 65d1d84bf4c381492d394bb61055cfa308ce24f7..6ed4efec4eda74af9472e6e3fc637251f9c2a21c 100644
+index 32b782bab750351caddafe6d6327e406bb26fb93..38d73f50360685a573740e811f186d7fa582003c 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
-@@ -1268,6 +1268,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
- boolean flag = this.tickRateManager().runsNormally();
+@@ -1387,6 +1387,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
+ int tickedEntities = 0; // Paper - rewrite chunk system
int tilesThisCycle = 0;
+ // SparklyPaper start - optimize tickBlockEntities
@@ -26,7 +26,7 @@ index 65d1d84bf4c381492d394bb61055cfa308ce24f7..6ed4efec4eda74af9472e6e3fc637251
for (tileTickPosition = 0; tileTickPosition < this.blockEntityTickers.size(); tileTickPosition++) { // Paper - Disable tick limiters
this.tileTickPosition = (this.tileTickPosition < this.blockEntityTickers.size()) ? this.tileTickPosition : 0;
TickingBlockEntity tickingblockentity = (TickingBlockEntity) this.blockEntityTickers.get(this.tileTickPosition);
-@@ -1278,13 +1282,25 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+@@ -1397,13 +1401,25 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
tilesThisCycle--;
this.blockEntityTickers.markAsRemoved(this.tileTickPosition); // this.blockEntityTickers.remove(this.tileTickPosition--); // SparklyPaper - optimize block entity removals
// Spigot end
@@ -44,11 +44,11 @@ index 65d1d84bf4c381492d394bb61055cfa308ce24f7..6ed4efec4eda74af9472e6e3fc637251
+ }
+ if (shouldTick) {
tickingblockentity.tick();
- // Paper start - execute chunk tasks during tick
- if ((this.tileTickPosition & 7) == 0) {
- MinecraftServer.getServer().executeMidTickTasks();
+ // Paper start - rewrite chunk system
+ if ((++tickedEntities & 7) == 0) {
+ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)(Level)(Object)this).moonrise$midTickTasks();
}
- // Paper end - execute chunk tasks during tick
+ // Paper end - rewrite chunk system
+ } // SparklyPaper end
}
}
@@ -65,10 +65,10 @@ index 28e3b73507b988f7234cbf29c4024c88180d0aef..427cf73383155c52bca8fb4b32f43029
+ long getChunkCoordinateKey(); // SparklyPaper - optimize tickBlockEntities
}
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
-index 14ee7b5b9b804bebd4e2a846b238547a28a36035..9af0da6c3a9805542b1b31fb32f0b3bcb1efe1c8 100644
+index 7c11853c5090fbc4fa5b3e73a69acf166158fdec..d7fe57e9a5aa59a7a9d611bcaa6152e72ec4c300 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
-@@ -75,6 +75,13 @@ public class LevelChunk extends ChunkAccess {
+@@ -74,6 +74,13 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
public String getType() {
return "";
}
@@ -82,7 +82,7 @@ index 14ee7b5b9b804bebd4e2a846b238547a28a36035..9af0da6c3a9805542b1b31fb32f0b3bc
};
private final Map tickersInLevel;
public boolean loaded;
-@@ -1087,7 +1094,7 @@ public class LevelChunk extends ChunkAccess {
+@@ -952,7 +959,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
}
private TickingBlockEntity createTicker(T blockEntity, BlockEntityTicker blockEntityTicker) {
@@ -91,7 +91,7 @@ index 14ee7b5b9b804bebd4e2a846b238547a28a36035..9af0da6c3a9805542b1b31fb32f0b3bc
}
@FunctionalInterface
-@@ -1138,6 +1145,13 @@ public class LevelChunk extends ChunkAccess {
+@@ -1003,6 +1010,13 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
public String toString() {
return String.valueOf(this.ticker) + " ";
}
@@ -105,7 +105,7 @@ index 14ee7b5b9b804bebd4e2a846b238547a28a36035..9af0da6c3a9805542b1b31fb32f0b3bc
}
private class BoundTickingBlockEntity implements TickingBlockEntity {
-@@ -1145,10 +1159,12 @@ public class LevelChunk extends ChunkAccess {
+@@ -1010,10 +1024,12 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
private final T blockEntity;
private final BlockEntityTicker ticker;
private boolean loggedInvalidBlockState;
@@ -119,7 +119,7 @@ index 14ee7b5b9b804bebd4e2a846b238547a28a36035..9af0da6c3a9805542b1b31fb32f0b3bc
}
@Override
-@@ -1216,5 +1232,12 @@ public class LevelChunk extends ChunkAccess {
+@@ -1081,5 +1097,12 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
return "Level ticker for " + s + "@" + String.valueOf(this.getPos());
}
diff --git a/patches/server/0017-Track-how-much-MSPT-each-world-used.patch b/patches/server/0015-Track-how-much-MSPT-each-world-used.patch
similarity index 88%
rename from patches/server/0017-Track-how-much-MSPT-each-world-used.patch
rename to patches/server/0015-Track-how-much-MSPT-each-world-used.patch
index dafa2ee..fcd643e 100644
--- a/patches/server/0017-Track-how-much-MSPT-each-world-used.patch
+++ b/patches/server/0015-Track-how-much-MSPT-each-world-used.patch
@@ -56,10 +56,10 @@ index 8b5293b0c696ef21d0101493ffa41b60bf0bc86b..601198a33adb29316b0617d5390d1620
}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index b635a473d2a19bbefc24e86455ec6735b9a8c9cc..8394e89af7b8aa2638a6ccf711897470484b47ef 100644
+index b198e2b7a1a96972ecf761e1713085d618aadead..1633d2b2816d3cf958f13d2613812f582b2d1591 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
-@@ -1792,7 +1792,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop> {
+@@ -450,6 +450,18 @@ public class Connection extends SimpleChannelInboundHandler> {
return;
}
diff --git a/patches/server/0020-Helpful-NMS-packet-changes.patch b/patches/server/0018-Helpful-NMS-packet-changes.patch
similarity index 96%
rename from patches/server/0020-Helpful-NMS-packet-changes.patch
rename to patches/server/0018-Helpful-NMS-packet-changes.patch
index 12fa7b1..d476f6b 100644
--- a/patches/server/0020-Helpful-NMS-packet-changes.patch
+++ b/patches/server/0018-Helpful-NMS-packet-changes.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Helpful NMS packet changes
Some nice changes to the packet internals to make packet sending and manipulation easier for us to avoid Reflection and JVM internals (ooo theUnsafe spooky) usage
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java
-index ee43eb8887835fbd016d28f91b2239dfeb25508e..e945e0752b41e10d16d8c766a2f919767b7b0b82 100644
+index 792b9a72a610cc512a8920d61013b6ba02f71e47..6e273098d9f2c0a78e9e98d7bbd8ed4c8de4ebc1 100644
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java
-@@ -21,7 +21,7 @@ public class ClientboundAddEntityPacket implements Packet recipeHolder = optional.get();
- ItemStack itemStack = recipeHolder.value().assemble(crafterBlockEntity, world.registryAccess());
-- if (itemStack.isEmpty()) {
+@@ -202,6 +202,13 @@ public class CrafterBlock extends BaseEntityBlock {
+ }
+ itemstack = CraftItemStack.asNMSCopy(event.getResult());
+ // CraftBukkit end
+ // SparklyPaper - add CraftItemRecipeEvent
-+ net.sparklypower.sparklypaper.event.inventory.CraftItemRecipeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callCraftItemRecipeEvent(crafterBlockEntity, recipeHolder.toBukkitRecipe(), itemStack);
-+ itemStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getResult());
-+ if (itemStack.isEmpty() || event.isCancelled()) { // SparklyPaper - add CraftItemRecipeEvent
++ net.sparklypower.sparklypaper.event.inventory.CraftItemRecipeEvent sparklyEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callCraftItemRecipeEvent(crafterblockentity, recipeholder.toBukkitRecipe(), itemstack);
++ if (sparklyEvent.isCancelled()) {
++ return;
++ }
++ itemstack = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(sparklyEvent.getResult());
++ // SparklyPaper end
+ if (itemstack.isEmpty()) {
world.levelEvent(1050, pos, 0);
} else {
- crafterBlockEntity.setCraftingTicksRemaining(6);
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
-index 0cba343989d6d33026a8e94f2b58ca93571721a9..4de9187d66d10b5a2c0ee8fe11b585f5d369df4f 100644
+index 44bec90466967933b5322a8ca8b5e86e0c96d443..6d166a6662ed2badfdc9cb42ca4374dc8d640404 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
-@@ -1442,6 +1442,23 @@ public class CraftEventFactory {
- return CraftItemStack.asNMSCopy(bitem);
+@@ -1467,6 +1467,24 @@ public class CraftEventFactory {
+ Bukkit.getPluginManager().callEvent(crafterCraftEvent);
+ return crafterCraftEvent;
}
-
++
+ // SparklyPaper start - add CraftItemRecipeEvent
+ public static net.sparklypower.sparklypaper.event.inventory.CraftItemRecipeEvent callCraftItemRecipeEvent(net.minecraft.world.inventory.CraftingContainer container, Recipe recipe, ItemStack result) {
+ org.bukkit.inventory.ItemStack[] matrix = new org.bukkit.inventory.ItemStack[container.getItems().size()];
diff --git a/patches/server/0023-Allow-item-version-downgrades.patch b/patches/server/0021-Allow-item-version-downgrades.patch
similarity index 83%
rename from patches/server/0023-Allow-item-version-downgrades.patch
rename to patches/server/0021-Allow-item-version-downgrades.patch
index 81a9b04..41d7c13 100644
--- a/patches/server/0023-Allow-item-version-downgrades.patch
+++ b/patches/server/0021-Allow-item-version-downgrades.patch
@@ -6,18 +6,18 @@ Subject: [PATCH] Allow item version downgrades
The server WON'T convert the item data from a newer version to an older version, so proceed with caution
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
-index f99353a60e3f236735ef6e2e6f13381b50ae9b7b..c285b9ab77f53270d570c55b007b57597eff8c03 100644
+index 28dbe30a98a6730839949bc9a6a90b78619ff84d..48e0c6fec6f847ce030ec79655d866be47364c73 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
-@@ -78,6 +78,7 @@ import org.bukkit.potion.PotionType;
- @SuppressWarnings("deprecation")
+@@ -75,6 +75,7 @@ import org.bukkit.potion.PotionType;
public final class CraftMagicNumbers implements UnsafeValues {
public static final UnsafeValues INSTANCE = new CraftMagicNumbers();
+ public static final boolean DISABLE_OLD_API_SUPPORT = Boolean.getBoolean("paper.disableOldApiSupport"); // Paper
+ private static final boolean JUST_CORRUPT_IT = Boolean.getBoolean("sparklypaper.ignoreItemDataVersion"); // SparklyPaper - allow item downgrades
private CraftMagicNumbers() {}
-@@ -256,7 +257,7 @@ public final class CraftMagicNumbers implements UnsafeValues {
+@@ -236,7 +237,7 @@ public final class CraftMagicNumbers implements UnsafeValues {
@Override
public Material getMaterial(String material, int version) {
Preconditions.checkArgument(material != null, "material == null");
@@ -26,7 +26,7 @@ index f99353a60e3f236735ef6e2e6f13381b50ae9b7b..c285b9ab77f53270d570c55b007b5759
// Fastpath up to date materials
if (version == this.getDataVersion()) {
-@@ -576,7 +577,7 @@ public final class CraftMagicNumbers implements UnsafeValues {
+@@ -559,7 +560,7 @@ public final class CraftMagicNumbers implements UnsafeValues {
throw new RuntimeException(ex);
}
int dataVersion = compound.getInt("DataVersion");
diff --git a/patches/server/0024-Parallel-world-ticking.patch b/patches/server/0022-Parallel-world-ticking.patch
similarity index 69%
rename from patches/server/0024-Parallel-world-ticking.patch
rename to patches/server/0022-Parallel-world-ticking.patch
index 8ff4370..dd68fcc 100644
--- a/patches/server/0024-Parallel-world-ticking.patch
+++ b/patches/server/0022-Parallel-world-ticking.patch
@@ -5,116 +5,53 @@ Subject: [PATCH] Parallel world ticking
"mom can we have folia?" "we already have folia at home" folia at home:
-diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java
-index 6bc7c6f16a1649fc9e24e7cf90fca401e5bd4875..a6082e925ad1e27d6a5089356af1840ee8852a9a 100644
---- a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java
-+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java
-@@ -1024,7 +1024,7 @@ public final class ChunkHolderManager {
- if (changedFullStatus.isEmpty()) {
- return;
- }
-- if (!TickThread.isTickThread()) {
-+ if (!TickThread.isTickThreadFor(world)) { // SparklyPaper - parallel world ticking
- this.taskScheduler.scheduleChunkTask(() -> {
- final ArrayDeque pendingFullLoadUpdate = ChunkHolderManager.this.pendingFullLoadUpdate;
- for (int i = 0, len = changedFullStatus.size(); i < len; ++i) {
-@@ -1053,7 +1053,7 @@ public final class ChunkHolderManager {
-
- // note: never call while inside the chunk system, this will absolutely break everything
- public void processUnloads() {
-- TickThread.ensureTickThread("Cannot unload chunks off-main");
-+ TickThread.ensureTickThread(world, "Cannot unload chunks off-main"); // SparklyPaper - parallel world ticking
-
- if (BLOCK_TICKET_UPDATES.get() == Boolean.TRUE) {
- throw new IllegalStateException("Cannot unload chunks recursively");
-@@ -1328,14 +1328,14 @@ public final class ChunkHolderManager {
- }
-
- private boolean processTicketUpdates(final boolean checkLocks, final boolean processFullUpdates, List scheduledTasks) {
-- TickThread.ensureTickThread("Cannot process ticket levels off-main");
-+ TickThread.ensureTickThread(world, "Cannot process ticket levels off-main"); // SparklyPaper - parallel world ticking
- if (BLOCK_TICKET_UPDATES.get() == Boolean.TRUE) {
- throw new IllegalStateException("Cannot update ticket level while unloading chunks or updating entity manager");
- }
-
- List changedFullStatus = null;
-
-- final boolean isTickThread = TickThread.isTickThread();
-+ final boolean isTickThread = TickThread.isTickThreadFor(world);
-
- boolean ret = false;
- final boolean canProcessFullUpdates = processFullUpdates & isTickThread;
-diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkTaskScheduler.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkTaskScheduler.java
-index 049e20407033073b06fcdeb46c38485f4926d778..d2ce10f8d8724626612a05938fb61f16d73afd16 100644
---- a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkTaskScheduler.java
-+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkTaskScheduler.java
-@@ -330,7 +330,7 @@ public final class ChunkTaskScheduler {
- public void scheduleTickingState(final int chunkX, final int chunkZ, final FullChunkStatus toStatus,
- final boolean addTicket, final PrioritisedExecutor.Priority priority,
- final Consumer onComplete) {
-- if (!TickThread.isTickThread()) {
-+ if (!TickThread.isTickThreadFor(world, chunkX, chunkZ)) { // SparklyPaper - parallel world ticking (other threads may call this method, such as the container stillValid check, which may trigger a chunk load in a different thread)
- this.scheduleChunkTask(chunkX, chunkZ, () -> {
- ChunkTaskScheduler.this.scheduleTickingState(chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
- }, priority);
-@@ -486,7 +486,7 @@ public final class ChunkTaskScheduler {
-
- public void scheduleChunkLoad(final int chunkX, final int chunkZ, final ChunkStatus toStatus, final boolean addTicket,
- final PrioritisedExecutor.Priority priority, final Consumer onComplete) {
-- if (!TickThread.isTickThread()) {
-+ if (!TickThread.isTickThreadFor(world, chunkX, chunkZ)) { // SparklyPaper - parallel world ticking
- this.scheduleChunkTask(chunkX, chunkZ, () -> {
- ChunkTaskScheduler.this.scheduleChunkLoad(chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
- }, priority);
-diff --git a/src/main/java/io/papermc/paper/util/TickThread.java b/src/main/java/io/papermc/paper/util/TickThread.java
-index bdaf062f9b66ceab303a0807eca301342886a8ea..205034bf47e5be6bd151bb538408d76a91633273 100644
---- a/src/main/java/io/papermc/paper/util/TickThread.java
-+++ b/src/main/java/io/papermc/paper/util/TickThread.java
-@@ -17,6 +17,7 @@ import java.util.concurrent.atomic.AtomicInteger;
+diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java
+index 11b7f15755dde766140c29bedca456c80d53293f..0bddee29c63d63d3cfd02a299456430f4e4f3dd7 100644
+--- a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java
++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java
+@@ -14,6 +14,7 @@ import java.util.concurrent.atomic.AtomicInteger;
public class TickThread extends Thread {
- public static final boolean STRICT_THREAD_CHECKS = Boolean.getBoolean("paper.strict-thread-checks");
+ private static final Logger LOGGER = LoggerFactory.getLogger(TickThread.class);
+ public static final boolean HARD_THROW = !Boolean.getBoolean("sparklypaper.disableHardThrow"); // SparklyPaper - parallel world ticking - THIS SHOULD NOT BE DISABLED SINCE IT CAN CAUSE DATA CORRUPTION!!! Anyhow, for production servers, if you want to make a test run to see if the server could crash, you can test it with this disabled
- static {
- if (STRICT_THREAD_CHECKS) {
-@@ -41,50 +42,93 @@ public class TickThread extends Thread {
- @Deprecated
+ /**
+ * @deprecated
+@@ -22,52 +23,121 @@ public class TickThread extends Thread {
public static void ensureTickThread(final String reason) {
if (!isTickThread()) {
-- MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable());
+ LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable());
- throw new IllegalStateException(reason);
-+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason + " - " + getTickThreadInformation(), new Throwable());
+ if (HARD_THROW)
+ throw new IllegalStateException(reason);
}
}
- public static void ensureTickThread(final ServerLevel world, final BlockPos pos, final String reason) {
+ public static void ensureTickThread(final Level world, final BlockPos pos, final String reason) {
if (!isTickThreadFor(world, pos)) {
-- MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable());
+- LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable());
- throw new IllegalStateException(reason);
-+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason + " @ world " + world.getWorld().getName() + " blockPos: " + pos + " - " + getTickThreadInformation(), new Throwable());
++ LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason + " @ world " + world.getWorld().getName() + " blockPos: " + pos + " - " + getTickThreadInformation(world.getServer()), new Throwable());
+ if (HARD_THROW)
+ throw new IllegalStateException(reason);
}
}
- public static void ensureTickThread(final ServerLevel world, final ChunkPos pos, final String reason) {
+ public static void ensureTickThread(final Level world, final ChunkPos pos, final String reason) {
if (!isTickThreadFor(world, pos)) {
-- MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable());
+- LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable());
- throw new IllegalStateException(reason);
-+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason + " @ world " + world.getWorld().getName() + " chunkPos: " + pos + " - " + getTickThreadInformation(), new Throwable());
++ LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason + " @ world " + world.getWorld().getName() + " chunkPos: " + pos + " - " + getTickThreadInformation(world.getServer()), new Throwable());
+ if (HARD_THROW)
+ throw new IllegalStateException(reason);
}
}
- public static void ensureTickThread(final ServerLevel world, final int chunkX, final int chunkZ, final String reason) {
+ public static void ensureTickThread(final Level world, final int chunkX, final int chunkZ, final String reason) {
if (!isTickThreadFor(world, chunkX, chunkZ)) {
-- MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable());
+- LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable());
- throw new IllegalStateException(reason);
-+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason + " @ world " + world.getWorld().getName() + " chunkX: " + chunkX + " chunkZ: " + chunkZ + " - " + getTickThreadInformation(), new Throwable());
++ LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason + " @ world " + world.getWorld().getName() + " chunkX: " + chunkX + " chunkZ: " + chunkZ + " - " + getTickThreadInformation(world.getServer()), new Throwable());
+ if (HARD_THROW)
+ throw new IllegalStateException(reason);
}
@@ -122,40 +59,40 @@ index bdaf062f9b66ceab303a0807eca301342886a8ea..205034bf47e5be6bd151bb538408d76a
public static void ensureTickThread(final Entity entity, final String reason) {
if (!isTickThreadFor(entity)) {
-- MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable());
+- LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable());
- throw new IllegalStateException(reason);
-+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason + " @ entity " + entity.getStringUUID() + " - " + getTickThreadInformation(), new Throwable());
++ LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason + " @ entity " + entity.getStringUUID() + " - " + getTickThreadInformation(entity.getServer()), new Throwable());
+ if (HARD_THROW)
+ throw new IllegalStateException(reason);
}
}
- public static void ensureTickThread(final ServerLevel world, final AABB aabb, final String reason) {
+ public static void ensureTickThread(final Level world, final AABB aabb, final String reason) {
if (!isTickThreadFor(world, aabb)) {
-- MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable());
+- LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable());
- throw new IllegalStateException(reason);
-+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason + " @ world " + world.getWorld().getName() + " aabb: " + aabb + " - " + getTickThreadInformation(), new Throwable());
++ LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason + " @ world " + world.getWorld().getName() + " aabb: " + aabb + " - " + getTickThreadInformation(world.getServer()), new Throwable());
+ if (HARD_THROW)
+ throw new IllegalStateException(reason);
}
}
- public static void ensureTickThread(final ServerLevel world, final double blockX, final double blockZ, final String reason) {
+ public static void ensureTickThread(final Level world, final double blockX, final double blockZ, final String reason) {
if (!isTickThreadFor(world, blockX, blockZ)) {
-- MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable());
+- LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable());
- throw new IllegalStateException(reason);
-+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason + " @ world " + world.getWorld().getName() + " blockX: " + blockX + " blockZ: " + blockZ + " - " + getTickThreadInformation(), new Throwable());
++ LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason + " @ world " + world.getWorld().getName() + " blockX: " + blockX + " blockZ: " + blockZ + " - " + getTickThreadInformation(world.getServer()), new Throwable());
+ if (HARD_THROW)
+ throw new IllegalStateException(reason);
-+ }
-+ }
-+
+ }
+ }
+
+ // SparklyPaper - parallel world ticking
+ // This is an additional method to check if the tick thread is bound to a specific world because, by default, Paper's isTickThread methods do not provide this information
+ // Because we only tick worlds in parallel (instead of regions), we can use this for our checks
-+ public static void ensureTickThread(final ServerLevel world, final String reason) {
++ public static void ensureTickThread(final net.minecraft.server.level.ServerLevel world, final String reason) {
+ if (!isTickThreadFor(world)) {
-+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason + " @ world " + world.getWorld().getName() + " - " + getTickThreadInformation(), new Throwable());
++ LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason + " @ world " + world.getWorld().getName() + " - " + getTickThreadInformation(world.getServer()), new Throwable());
+ if (HARD_THROW)
+ throw new IllegalStateException(reason);
+ }
@@ -167,7 +104,7 @@ index bdaf062f9b66ceab303a0807eca301342886a8ea..205034bf47e5be6bd151bb538408d76a
+ boolean isTickThread = isTickThread();
+ boolean isServerLevelTickThread = isServerLevelTickThread();
+ if (!isTickThread || isServerLevelTickThread) {
-+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread ONLY tick thread check: " + reason + " - " + getTickThreadInformation(), new Throwable());
++ LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread ONLY tick thread check: " + reason, new Throwable());
+ if (HARD_THROW)
+ throw new IllegalStateException(reason);
+ }
@@ -175,22 +112,18 @@ index bdaf062f9b66ceab303a0807eca301342886a8ea..205034bf47e5be6bd151bb538408d76a
+
+ // SparklyPaper - parallel world ticking
+ // This is an additional method to check if the tick thread is bound to a specific world or if it is an async thread.
-+ public static void ensureTickThreadOrAsyncThread(final ServerLevel world, final String reason) {
++ public static void ensureTickThreadOrAsyncThread(final net.minecraft.server.level.ServerLevel world, final String reason) {
+ boolean isValidTickThread = isTickThreadFor(world);
+ boolean isAsyncThread = !isTickThread();
+ boolean isValid = isAsyncThread || isValidTickThread;
+ if (!isValid) {
-+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread or async thread check: " + reason + " @ world " + world.getWorld().getName() + " - " + getTickThreadInformation(), new Throwable());
++ LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread or async thread check: " + reason + " @ world " + world.getWorld().getName() + " - " + getTickThreadInformation(world.getServer()), new Throwable());
+ if (HARD_THROW)
+ throw new IllegalStateException(reason);
- }
- }
-
-@@ -109,6 +153,32 @@ public class TickThread extends Thread {
- return (TickThread) Thread.currentThread();
- }
-
-+ public static String getTickThreadInformation() {
++ }
++ }
++
++ public static String getTickThreadInformation(net.minecraft.server.MinecraftServer minecraftServer) {
+ StringBuilder sb = new StringBuilder();
+ Thread currentThread = Thread.currentThread();
+ sb.append("Is tick thread? ");
@@ -206,7 +139,7 @@ index bdaf062f9b66ceab303a0807eca301342886a8ea..205034bf47e5be6bd151bb538408d76a
+ }
+ }
+ sb.append("; Is iterating over levels? ");
-+ sb.append(MinecraftServer.getServer().isIteratingOverLevels);
++ sb.append(minecraftServer.isIteratingOverLevels);
+ sb.append("; Are we going to hard throw? ");
+ sb.append(HARD_THROW);
+ return sb.toString();
@@ -216,13 +149,13 @@ index bdaf062f9b66ceab303a0807eca301342886a8ea..205034bf47e5be6bd151bb538408d76a
+ return Thread.currentThread() instanceof ServerLevelTickThread;
+ }
+
- public static boolean isTickThread() {
- return Thread.currentThread() instanceof TickThread;
- }
-@@ -118,42 +188,111 @@ public class TickThread extends Thread {
+ public final int id; /* We don't override getId as the spec requires that it be unique (with respect to all other threads) */
+
+ private static final AtomicInteger ID_GENERATOR = new AtomicInteger();
+@@ -98,42 +168,111 @@ public class TickThread extends Thread {
}
- public static boolean isTickThreadFor(final ServerLevel world, final BlockPos pos) {
+ public static boolean isTickThreadFor(final Level world, final BlockPos pos) {
- return isTickThread();
+ Thread currentThread = Thread.currentThread();
+
@@ -231,7 +164,7 @@ index bdaf062f9b66ceab303a0807eca301342886a8ea..205034bf47e5be6bd151bb538408d76a
+ } else return currentThread instanceof TickThread;
}
- public static boolean isTickThreadFor(final ServerLevel world, final ChunkPos pos) {
+ public static boolean isTickThreadFor(final Level world, final ChunkPos pos) {
- return isTickThread();
+ Thread currentThread = Thread.currentThread();
+
@@ -240,7 +173,7 @@ index bdaf062f9b66ceab303a0807eca301342886a8ea..205034bf47e5be6bd151bb538408d76a
+ } else return currentThread instanceof TickThread;
}
- public static boolean isTickThreadFor(final ServerLevel world, final Vec3 pos) {
+ public static boolean isTickThreadFor(final Level world, final Vec3 pos) {
- return isTickThread();
+ Thread currentThread = Thread.currentThread();
+
@@ -249,7 +182,7 @@ index bdaf062f9b66ceab303a0807eca301342886a8ea..205034bf47e5be6bd151bb538408d76a
+ } else return currentThread instanceof TickThread;
}
- public static boolean isTickThreadFor(final ServerLevel world, final int chunkX, final int chunkZ) {
+ public static boolean isTickThreadFor(final Level world, final int chunkX, final int chunkZ) {
- return isTickThread();
+ Thread currentThread = Thread.currentThread();
+
@@ -258,7 +191,7 @@ index bdaf062f9b66ceab303a0807eca301342886a8ea..205034bf47e5be6bd151bb538408d76a
+ } else return currentThread instanceof TickThread;
}
- public static boolean isTickThreadFor(final ServerLevel world, final AABB aabb) {
+ public static boolean isTickThreadFor(final Level world, final AABB aabb) {
- return isTickThread();
+ Thread currentThread = Thread.currentThread();
+
@@ -267,7 +200,7 @@ index bdaf062f9b66ceab303a0807eca301342886a8ea..205034bf47e5be6bd151bb538408d76a
+ } else return currentThread instanceof TickThread;
}
- public static boolean isTickThreadFor(final ServerLevel world, final double blockX, final double blockZ) {
+ public static boolean isTickThreadFor(final Level world, final double blockX, final double blockZ) {
- return isTickThread();
+ Thread currentThread = Thread.currentThread();
+
@@ -276,7 +209,7 @@ index bdaf062f9b66ceab303a0807eca301342886a8ea..205034bf47e5be6bd151bb538408d76a
+ } else return currentThread instanceof TickThread;
}
- public static boolean isTickThreadFor(final ServerLevel world, final Vec3 position, final Vec3 deltaMovement, final int buffer) {
+ public static boolean isTickThreadFor(final Level world, final Vec3 position, final Vec3 deltaMovement, final int buffer) {
- return isTickThread();
+ Thread currentThread = Thread.currentThread();
+
@@ -285,7 +218,7 @@ index bdaf062f9b66ceab303a0807eca301342886a8ea..205034bf47e5be6bd151bb538408d76a
+ } else return currentThread instanceof TickThread;
}
- public static boolean isTickThreadFor(final ServerLevel world, final int fromChunkX, final int fromChunkZ, final int toChunkX, final int toChunkZ) {
+ public static boolean isTickThreadFor(final Level world, final int fromChunkX, final int fromChunkZ, final int toChunkX, final int toChunkZ) {
- return isTickThread();
+ Thread currentThread = Thread.currentThread();
+
@@ -294,7 +227,7 @@ index bdaf062f9b66ceab303a0807eca301342886a8ea..205034bf47e5be6bd151bb538408d76a
+ } else return currentThread instanceof TickThread;
}
- public static boolean isTickThreadFor(final ServerLevel world, final int chunkX, final int chunkZ, final int radius) {
+ public static boolean isTickThreadFor(final Level world, final int chunkX, final int chunkZ, final int radius) {
- return isTickThread();
+ Thread currentThread = Thread.currentThread();
+
@@ -306,7 +239,7 @@ index bdaf062f9b66ceab303a0807eca301342886a8ea..205034bf47e5be6bd151bb538408d76a
+ // SparklyPaper - parallel world ticking
+ // This is an additional method to check if the tick thread is bound to a specific world because, by default, Paper's isTickThread methods do not provide this information
+ // Because we only tick worlds in parallel (instead of regions), we can use this for our checks
-+ public static boolean isTickThreadFor(final ServerLevel world) {
++ public static boolean isTickThreadFor(final Level world) {
+ Thread currentThread = Thread.currentThread();
+
+ if (currentThread instanceof ServerLevelTickThread serverLevelTickThread) {
@@ -337,10 +270,41 @@ index bdaf062f9b66ceab303a0807eca301342886a8ea..205034bf47e5be6bd151bb538408d76a
+ super(run, name);
+ }
+
-+ public ServerLevel currentlyTickingServerLevel;
++ public net.minecraft.server.level.ServerLevel currentlyTickingServerLevel;
}
+ // SparklyPaper end
}
+diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
+index 58d3d1a47e9f2423c467bb329c2d5f4b58a8b5ef..0055e299220c8e0f4fa8ce13d61db36f3c697a10 100644
+--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
+@@ -1010,7 +1010,7 @@ public final class ChunkHolderManager {
+ if (changedFullStatus.isEmpty()) {
+ return;
+ }
+- if (!TickThread.isTickThread()) {
++ if (!TickThread.isTickThreadFor(world)) { // SparklyPaper - parallel world ticking
+ this.taskScheduler.scheduleChunkTask(() -> {
+ final ArrayDeque pendingFullLoadUpdate = ChunkHolderManager.this.pendingFullLoadUpdate;
+ for (int i = 0, len = changedFullStatus.size(); i < len; ++i) {
+@@ -1037,7 +1037,7 @@ public final class ChunkHolderManager {
+
+ // note: never call while inside the chunk system, this will absolutely break everything
+ public void processUnloads() {
+- TickThread.ensureTickThread("Cannot unload chunks off-main");
++ TickThread.ensureTickThread(world, "Cannot unload chunks off-main"); // SparklyPaper - parallel world ticking
+
+ if (BLOCK_TICKET_UPDATES.get() == Boolean.TRUE) {
+ throw new IllegalStateException("Cannot unload chunks recursively");
+@@ -1316,7 +1316,7 @@ public final class ChunkHolderManager {
+
+ List changedFullStatus = null;
+
+- final boolean isTickThread = TickThread.isTickThread();
++ final boolean isTickThread = TickThread.isTickThreadFor(world);
+
+ boolean ret = false;
+ final boolean canProcessFullUpdates = processFullUpdates & isTickThread;
diff --git a/src/main/java/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java
index 6df0db8b4cdab23494ea34236949ece4989110a3..62943b954835fb30ce916c1a17fed39620a7882d 100644
--- a/src/main/java/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java
@@ -355,10 +319,10 @@ index 6df0db8b4cdab23494ea34236949ece4989110a3..62943b954835fb30ce916c1a17fed396
}
diff --git a/src/main/java/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java
-index f28705547a62da790f5df071400986aacba39367..f9800dce8f9e85ad11e4208d78d85a75dbcd1f72 100644
+index 39c96f5db6e90a470404c6387fa0c1d5531822e5..08fba180a1d9c6e2b96b049122ed24cac62528fd 100644
--- a/src/main/java/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java
+++ b/src/main/java/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java
-@@ -85,7 +85,7 @@ public class DefaultDispenseItemBehavior implements DispenseItemBehavior {
+@@ -87,7 +87,7 @@ public class DefaultDispenseItemBehavior implements DispenseItemBehavior {
CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack);
BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), CraftVector.toBukkit(entityitem.getDeltaMovement()));
@@ -368,10 +332,10 @@ index f28705547a62da790f5df071400986aacba39367..f9800dce8f9e85ad11e4208d78d85a75
}
diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java
-index 5dab1e10303177e5a4d97a91ee46ede66f30ae35..ed63d558893035d012308e4f0de4cd2aaf4d0135 100644
+index 60d3319016beb4f60cbc26dde165f64cf7577602..fed5a27daf1074207f3a79745e97c899a95d976f 100644
--- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java
+++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java
-@@ -114,7 +114,7 @@ public interface DispenseItemBehavior {
+@@ -115,7 +115,7 @@ public interface DispenseItemBehavior {
CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1);
BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0));
@@ -380,7 +344,7 @@ index 5dab1e10303177e5a4d97a91ee46ede66f30ae35..ed63d558893035d012308e4f0de4cd2a
worldserver.getCraftServer().getPluginManager().callEvent(event);
}
-@@ -173,7 +173,7 @@ public interface DispenseItemBehavior {
+@@ -174,7 +174,7 @@ public interface DispenseItemBehavior {
CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1);
BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0));
@@ -389,7 +353,7 @@ index 5dab1e10303177e5a4d97a91ee46ede66f30ae35..ed63d558893035d012308e4f0de4cd2a
worldserver.getCraftServer().getPluginManager().callEvent(event);
}
-@@ -228,7 +228,7 @@ public interface DispenseItemBehavior {
+@@ -229,7 +229,7 @@ public interface DispenseItemBehavior {
CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1);
BlockDispenseArmorEvent event = new BlockDispenseArmorEvent(block, craftItem.clone(), (org.bukkit.craftbukkit.entity.CraftLivingEntity) list.get(0).getBukkitEntity());
@@ -398,7 +362,7 @@ index 5dab1e10303177e5a4d97a91ee46ede66f30ae35..ed63d558893035d012308e4f0de4cd2a
world.getCraftServer().getPluginManager().callEvent(event);
}
-@@ -284,7 +284,7 @@ public interface DispenseItemBehavior {
+@@ -285,7 +285,7 @@ public interface DispenseItemBehavior {
CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1);
BlockDispenseArmorEvent event = new BlockDispenseArmorEvent(block, craftItem.clone(), (org.bukkit.craftbukkit.entity.CraftLivingEntity) entityhorseabstract.getBukkitEntity());
@@ -407,7 +371,7 @@ index 5dab1e10303177e5a4d97a91ee46ede66f30ae35..ed63d558893035d012308e4f0de4cd2a
world.getCraftServer().getPluginManager().callEvent(event);
}
-@@ -358,7 +358,7 @@ public interface DispenseItemBehavior {
+@@ -359,7 +359,7 @@ public interface DispenseItemBehavior {
CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1);
BlockDispenseArmorEvent event = new BlockDispenseArmorEvent(block, craftItem.clone(), (org.bukkit.craftbukkit.entity.CraftLivingEntity) entityhorsechestedabstract.getBukkitEntity());
@@ -416,7 +380,7 @@ index 5dab1e10303177e5a4d97a91ee46ede66f30ae35..ed63d558893035d012308e4f0de4cd2a
world.getCraftServer().getPluginManager().callEvent(event);
}
-@@ -430,7 +430,7 @@ public interface DispenseItemBehavior {
+@@ -431,7 +431,7 @@ public interface DispenseItemBehavior {
CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack.copyWithCount(1)); // Paper - single item in event
BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(x, y, z));
@@ -425,7 +389,7 @@ index 5dab1e10303177e5a4d97a91ee46ede66f30ae35..ed63d558893035d012308e4f0de4cd2a
worldserver.getCraftServer().getPluginManager().callEvent(event);
}
-@@ -506,7 +506,7 @@ public interface DispenseItemBehavior {
+@@ -496,7 +496,7 @@ public interface DispenseItemBehavior {
CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack.copyWithCount(1)); // Paper - single item in event
BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ()));
@@ -434,7 +398,7 @@ index 5dab1e10303177e5a4d97a91ee46ede66f30ae35..ed63d558893035d012308e4f0de4cd2a
worldserver.getCraftServer().getPluginManager().callEvent(event);
}
-@@ -553,7 +553,7 @@ public interface DispenseItemBehavior {
+@@ -534,7 +534,7 @@ public interface DispenseItemBehavior {
CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack); // Paper - ignore stack size on damageable items
BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0));
@@ -443,7 +407,7 @@ index 5dab1e10303177e5a4d97a91ee46ede66f30ae35..ed63d558893035d012308e4f0de4cd2a
worldserver.getCraftServer().getPluginManager().callEvent(event);
}
-@@ -616,7 +616,7 @@ public interface DispenseItemBehavior {
+@@ -596,7 +596,7 @@ public interface DispenseItemBehavior {
CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack.copyWithCount(1)); // Paper - single item in event
BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0));
@@ -452,7 +416,7 @@ index 5dab1e10303177e5a4d97a91ee46ede66f30ae35..ed63d558893035d012308e4f0de4cd2a
worldserver.getCraftServer().getPluginManager().callEvent(event);
}
-@@ -645,8 +645,8 @@ public interface DispenseItemBehavior {
+@@ -625,8 +625,8 @@ public interface DispenseItemBehavior {
// CraftBukkit start
worldserver.captureTreeGeneration = false;
if (worldserver.capturedBlockStates.size() > 0) {
@@ -463,7 +427,7 @@ index 5dab1e10303177e5a4d97a91ee46ede66f30ae35..ed63d558893035d012308e4f0de4cd2a
Location location = CraftLocation.toBukkit(blockposition, worldserver.getWorld());
List blocks = new java.util.ArrayList<>(worldserver.capturedBlockStates.values());
worldserver.capturedBlockStates.clear();
-@@ -685,7 +685,7 @@ public interface DispenseItemBehavior {
+@@ -665,7 +665,7 @@ public interface DispenseItemBehavior {
CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1);
BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector((double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D));
@@ -472,7 +436,7 @@ index 5dab1e10303177e5a4d97a91ee46ede66f30ae35..ed63d558893035d012308e4f0de4cd2a
worldserver.getCraftServer().getPluginManager().callEvent(event);
}
-@@ -742,7 +742,7 @@ public interface DispenseItemBehavior {
+@@ -722,7 +722,7 @@ public interface DispenseItemBehavior {
CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack.copyWithCount(1)); // Paper - single item in event
BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ()));
@@ -481,7 +445,7 @@ index 5dab1e10303177e5a4d97a91ee46ede66f30ae35..ed63d558893035d012308e4f0de4cd2a
worldserver.getCraftServer().getPluginManager().callEvent(event);
}
-@@ -791,7 +791,7 @@ public interface DispenseItemBehavior {
+@@ -771,7 +771,7 @@ public interface DispenseItemBehavior {
CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack.copyWithCount(1)); // Paper - single item in event
BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ()));
@@ -490,7 +454,7 @@ index 5dab1e10303177e5a4d97a91ee46ede66f30ae35..ed63d558893035d012308e4f0de4cd2a
worldserver.getCraftServer().getPluginManager().callEvent(event);
}
-@@ -864,7 +864,7 @@ public interface DispenseItemBehavior {
+@@ -833,7 +833,7 @@ public interface DispenseItemBehavior {
CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack.copyWithCount(1)); // Paper - only single item in event
BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ()));
@@ -499,7 +463,7 @@ index 5dab1e10303177e5a4d97a91ee46ede66f30ae35..ed63d558893035d012308e4f0de4cd2a
worldserver.getCraftServer().getPluginManager().callEvent(event);
}
-@@ -946,7 +946,7 @@ public interface DispenseItemBehavior {
+@@ -915,7 +915,7 @@ public interface DispenseItemBehavior {
CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1);
BlockDispenseEvent event = new BlockDispenseArmorEvent(block, craftItem.clone(), (org.bukkit.craftbukkit.entity.CraftLivingEntity) list.get(0).getBukkitEntity());
@@ -522,7 +486,7 @@ index e37d2d29f3ba67cfe28abe4847a3dca07121f0be..1635ae6106ee751704cbaaddcd7b3ad6
}
diff --git a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java
-index a024c697a65bbab27408da1d6a75e531d9719b47..8799ad0371c371396605e8ee4c1dd4066e07144a 100644
+index 44b79a7c2f8b95a484d1999fa2167ce588f7985b..5a2d9bbb702ba5844d2f9d36f3a5740c50edf938 100644
--- a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java
+++ b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java
@@ -41,7 +41,7 @@ public class ShearsDispenseItemBehavior extends OptionalDispenseItemBehavior {
@@ -548,10 +512,10 @@ index cb308808906a8cdb127df8284e106e00553473ca..323d41e2bed5e83a26dfe4c88dfce7ed
}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index cb1db5e105f685f8bda7e962dcde2523d8fbf454..3d5cf0a116a9d068fbb85732666c79e432bf6cf9 100644
+index 1633d2b2816d3cf958f13d2613812f582b2d1591..2a17896600e4405e4b533e8cb1d3caa389a7d059 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
-@@ -318,6 +318,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop entitiesWithScheduledTasks = java.util.concurrent.ConcurrentHashMap.newKeySet(); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run (concurrent because plugins may schedule tasks async)
public net.sparklypower.sparklypaper.HalloweenManager halloweenManager = new net.sparklypower.sparklypaper.HalloweenManager(); // SparklyPaper - Spooky month optimizations
@@ -561,16 +525,7 @@ index cb1db5e105f685f8bda7e962dcde2523d8fbf454..3d5cf0a116a9d068fbb85732666c79e4
public static S spin(Function serverFactory) {
AtomicReference atomicreference = new AtomicReference();
-@@ -1193,7 +1196,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop {
+ try {
-+ io.papermc.paper.util.TickThread.ServerLevelTickThread
-+ currentThread = (io.papermc.paper.util.TickThread.ServerLevelTickThread) Thread.currentThread();
++ ca.spottedleaf.moonrise.common.util.TickThread.ServerLevelTickThread currentThread = (ca.spottedleaf.moonrise.common.util.TickThread.ServerLevelTickThread) Thread.currentThread();
+ currentThread.currentlyTickingServerLevel = worldserver;
+
++ worldserver.timings.doTick.startTiming(); // Spigot
+ long i = Util.getNanos(); // SparklyPaper - track world's MSPT
+ worldserver.tick(shouldKeepTicking);
++ // SparklyPaper start - track world's MSPT
++ long j = Util.getNanos() - i;
+
-+ for (final io.papermc.paper.chunk.SingleThreadChunkRegionManager regionManager : worldserver.getChunkSource().chunkMap.regionManagers) {
-+ regionManager.recalculateRegions();
++ // These are from the "tickServer" function
++ worldserver.tickTimes5s.add(this.tickCount, j);
++ worldserver.tickTimes10s.add(this.tickCount, j);
++ worldserver.tickTimes60s.add(this.tickCount, j);
++ // SparklyPaper end
++ worldserver.timings.doTick.stopTiming(); // Spigot
++ } catch (Throwable throwable) {
++ // Spigot Start
++ CrashReport crashreport;
++ try {
++ crashreport = CrashReport.forThrowable(throwable, "Exception ticking world");
- this.profiler.push(() -> {
- String s = String.valueOf(worldserver);
++ } catch (Throwable t) {
++ if (throwable instanceof ThreadDeath) {
++ throw (ThreadDeath) throwable;
++ } // Paper
++ throw new RuntimeException("Error generating crash report", t);
+ }
-+ worldserver.explosionDensityCache.clear(); // Paper - Optimize explosions
++ // Spigot End
++ worldserver.fillReportDetails(crashreport);
++ throw new ReportedException(crashreport);
++ } finally {
++ serverLevelTickingSemaphore.release();
- return s + " " + String.valueOf(worldserver.dimension().location());
- });
@@ -616,18 +591,14 @@ index cb1db5e105f685f8bda7e962dcde2523d8fbf454..3d5cf0a116a9d068fbb85732666c79e4
- this.profiler.push("timeSync");
- this.synchronizeTime(worldserver);
- this.profiler.pop();
-- }
++ }
++ }, worldserver)
++ );
+ }
- // CraftBukkit end */
-+ // SparklyPaper start - track world's MSPT
-+ long j = Util.getNanos() - i;
-
+-
- this.profiler.push("tick");
-+ // These are from the "tickServer" function
-+ worldserver.tickTimes5s.add(this.tickCount, j);
-+ worldserver.tickTimes10s.add(this.tickCount, j);
-+ worldserver.tickTimes60s.add(this.tickCount, j);
-+ // SparklyPaper end
-
+-
- try {
- worldserver.timings.doTick.startTiming(); // Spigot
- long i = Util.getNanos(); // SparklyPaper - track world's MSPT
@@ -640,47 +611,19 @@ index cb1db5e105f685f8bda7e962dcde2523d8fbf454..3d5cf0a116a9d068fbb85732666c79e4
- worldserver.tickTimes10s.add(this.tickCount, j);
- worldserver.tickTimes60s.add(this.tickCount, j);
- // SparklyPaper end
-- // Paper start
-- for (final io.papermc.paper.chunk.SingleThreadChunkRegionManager regionManager : worldserver.getChunkSource().chunkMap.regionManagers) {
-- regionManager.recalculateRegions();
-- }
-- // Paper end
- worldserver.timings.doTick.stopTiming(); // Spigot
- } catch (Throwable throwable) {
- CrashReport crashreport = CrashReport.forThrowable(throwable, "Exception ticking world");
-+ currentThread.currentlyTickingServerLevel = null; // Reset current ticking level
- worldserver.fillReportDetails(crashreport);
- throw new ReportedException(crashreport);
-+ } catch (Throwable throwable) {
-+ // Spigot Start
-+ CrashReport crashreport;
-+ try {
-+ crashreport = CrashReport.forThrowable(throwable, "Exception ticking world");
-+
-+ } catch (Throwable t) {
-+ if (throwable instanceof ThreadDeath) {
-+ throw (ThreadDeath) throwable;
-+ } // Paper
-+ throw new RuntimeException("Error generating crash report", t);
-+ }
-+ // Spigot End
-+ worldserver.fillReportDetails(crashreport);
-+ throw new ReportedException(crashreport);
-+ } finally {
-+ serverLevelTickingSemaphore.release();
-+
-+ }
-+ }, worldserver)
-+ );
++ while (!tasks.isEmpty()) {
++ tasks.pop().get();
}
-
+-
- this.profiler.pop();
- this.profiler.pop();
- worldserver.explosionDensityCache.clear(); // Paper - Optimize explosions
-+ while (!tasks.isEmpty()) {
-+ tasks.pop().get();
-+ }
+ } catch (java.lang.InterruptedException | java.util.concurrent.ExecutionException e) {
+ throw new RuntimeException(e); // Propagate exception
}
@@ -688,20 +631,11 @@ index cb1db5e105f685f8bda7e962dcde2523d8fbf454..3d5cf0a116a9d068fbb85732666c79e4
this.isIteratingOverLevels = false; // Paper - Throw exception on world create while being ticked
this.profiler.popPush("connection");
-@@ -2958,7 +2978,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop {
- return this.getChunk(x, z, leastStatus, create);
- }, this.mainThreadProcessor).join();
-@@ -294,7 +303,7 @@ public class ServerChunkCache extends ChunkSource {
- @Nullable
- @Override
- public LevelChunk getChunkNow(int chunkX, int chunkZ) {
-- if (!io.papermc.paper.util.TickThread.isTickThread()) { // Paper - rewrite chunk system
-+ if (!io.papermc.paper.util.TickThread.isTickThreadFor(level, chunkX, chunkZ)) { // Paper - rewrite chunk system // SparklyPaper - parallel world ticking
- return null;
- } else {
- return this.getChunkAtIfLoadedMainThread(chunkX, chunkZ); // Paper - Perf: Optimise getChunkAt calls for loaded chunks
-@@ -308,7 +317,7 @@ public class ServerChunkCache extends ChunkSource {
- }
-
- public CompletableFuture> getChunkFuture(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) {
-- boolean flag1 = io.papermc.paper.util.TickThread.isTickThread(); // Paper - rewrite chunk system
-+ boolean flag1 = io.papermc.paper.util.TickThread.isTickThreadFor(level, chunkX, chunkZ); // Paper - rewrite chunk system // SparklyPaper - parallel world ticking
- CompletableFuture completablefuture;
-
- if (flag1) {
-@@ -636,7 +645,7 @@ public class ServerChunkCache extends ChunkSource {
-
- if (true || this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) { // Paper - optimise chunk tick iteration
- this.level.tickChunk(chunk1, l);
-- if ((chunksTicked++ & 1) == 0) net.minecraft.server.MinecraftServer.getServer().executeMidTickTasks(); // Paper
-+ // if ((chunksTicked++ & 1) == 0) net.minecraft.server.MinecraftServer.getServer().executeMidTickTasks(); // SparklyPaper - parallel world ticking (only run mid-tick at the end of each tick / fixes concurrency bugs related to executeMidTickTasks) // Paper
- }
- }
- }
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 172e835359ffa12abbc887d12be5af7403dae5ab..6070d3160ac4f43304bebbe87b6b3d9b15d57c07 100644
+index f162a3639f55d20bb691e34b60a7c8c55a99daf6..bfec87745b1790a83c46ab7c783206d26afd2521 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -222,6 +222,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -222,6 +222,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.
+ private final StructureCheck structureCheck;
private final boolean tickTime;
private final RandomSequences randomSequences;
- public long lastMidTickExecuteFailure; // Paper - execute chunk tasks mid tick
+ public java.util.concurrent.ExecutorService tickExecutor; // SparklyPaper - parallel world ticking
// CraftBukkit start
public final LevelStorageSource.LevelStorageAccess convertable;
-@@ -709,7 +710,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -515,7 +516,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.
this.uuid = WorldUUID.getUUID(convertable_conversionsession.levelDirectory.path().toFile());
// CraftBukkit end
this.players = Lists.newArrayList();
@@ -805,79 +681,52 @@ index 172e835359ffa12abbc887d12be5af7403dae5ab..6070d3160ac4f43304bebbe87b6b3d9b
this.blockTicks = new LevelTicks<>(this::isPositionTickingWithEntitiesLoaded, this.getProfilerSupplier());
this.fluidTicks = new LevelTicks<>(this::isPositionTickingWithEntitiesLoaded, this.getProfilerSupplier());
this.pathTypesByPosCache = new PathTypeCache();
-@@ -781,6 +782,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
-
- this.chunkTaskScheduler = new io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler(this, io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.workerThreads); // Paper - rewrite chunk system
- this.entityLookup = new io.papermc.paper.chunk.system.entity.EntityLookup(this, new EntityCallbacks()); // Paper - rewrite chunk system
+@@ -596,6 +597,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.
+ this.chunkTaskScheduler = new ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler((ServerLevel)(Object)this, ca.spottedleaf.moonrise.common.util.MoonriseCommon.WORKER_POOL);
+ // Paper end - rewrite chunk system
+ this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit
+ this.tickExecutor = java.util.concurrent.Executors.newSingleThreadExecutor(new net.sparklypower.sparklypaper.ServerLevelTickExecutorThreadFactory(getWorld().getName())); // SparklyPaper - parallel world ticking
}
// Paper start
-@@ -1358,7 +1360,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
- if (fluid1.is(fluid)) {
- fluid1.tick(this, pos);
- }
-- MinecraftServer.getServer().executeMidTickTasks(); // Paper - exec chunk tasks during world tick
-+ // MinecraftServer.getServer().executeMidTickTasks(); // SparklyPaper - parallel world ticking (only run mid-tick at the end of each tick / fixes concurrency bugs related to executeMidTickTasks) // Paper - exec chunk tasks during world tick
-
- }
-
-@@ -1368,7 +1370,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
- if (iblockdata.is(block)) {
- iblockdata.tick(this, pos, this.random);
- }
-- MinecraftServer.getServer().executeMidTickTasks(); // Paper - exec chunk tasks during world tick
-+ // MinecraftServer.getServer().executeMidTickTasks(); // SparklyPaper - parallel world ticking (only run mid-tick at the end of each tick / fixes concurrency bugs related to executeMidTickTasks) // Paper - exec chunk tasks during world tick
-
- }
-
-@@ -1386,7 +1388,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
-
- public void tickNonPassenger(Entity entity) {
- // Paper start - log detailed entity tick information
-- io.papermc.paper.util.TickThread.ensureTickThread("Cannot tick an entity off-main");
-+ io.papermc.paper.util.TickThread.ensureTickThread(entity, "Cannot tick an entity off-main"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
- try {
- if (currentlyTickingEntity.get() == null) {
- currentlyTickingEntity.lazySet(entity);
-@@ -1674,6 +1676,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1510,6 +1512,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.
}
private void addPlayer(ServerPlayer player) {
-+ io.papermc.paper.util.TickThread.ensureTickThread(this, "Cannot add player off-main"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this, "Cannot add player off-main"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
Entity entity = (Entity) this.getEntities().get(player.getUUID());
if (entity != null) {
-@@ -1687,7 +1690,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1523,7 +1526,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.
// CraftBukkit start
private boolean addEntity(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) {
- org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot
-+ io.papermc.paper.util.TickThread.ensureTickThread(this, "Cannot add entity off-main"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this, "Cannot add entity off-main"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
entity.generation = false; // Paper - Don't fire sync event during generation; Reset flag if it was added during a ServerLevel generation process
// Paper start - extra debug info
if (entity.valid) {
-@@ -2614,6 +2617,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
- @Override
+@@ -2427,6 +2430,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.
public void close() throws IOException {
super.close();
+ // Paper - rewrite chunk system
+ tickExecutor.shutdown(); // SparklyPaper - parallel world ticking
- //this.entityManager.close(); // Paper - rewrite chunk system
}
+ @Override
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index 6a4637eef14cbd84bbe26ef16f004b8f93367a3d..f359ecb161024ad8a6de6d20e9d6de51d29f1611 100644
+index 6c280abdef5f80b668d6090f9d35283a33e21e0c..078dc55c474c9f1e227c8ccd4f2b0bd4c0cde431 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -345,6 +345,7 @@ public class ServerPlayer extends Player {
- // Paper start - optimise chunk tick iteration
- public double lastEntitySpawnRadiusSquared = -1.0;
- // Paper end - optimise chunk tick iteration
+@@ -332,6 +332,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
+ return this.viewDistanceHolder;
+ }
+ // Paper end - rewrite chunk system
+ public boolean hasTickedAtLeastOnceInNewWorld = false; // SparklyPaper - parallel world ticking (fixes bug in DreamResourceReset where the inventory is opened AFTER the player has changed worlds, if you click with the quick tp torch in a chest, because the inventory is opened AFTER the player has teleported)
public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ClientInformation clientOptions) {
super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile);
-@@ -768,6 +769,7 @@ public class ServerPlayer extends Player {
+@@ -758,6 +759,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
@Override
public void tick() {
@@ -885,26 +734,15 @@ index 6a4637eef14cbd84bbe26ef16f004b8f93367a3d..f359ecb161024ad8a6de6d20e9d6de51
// CraftBukkit start
if (this.joining) {
this.joining = false;
-@@ -1263,6 +1265,7 @@ public class ServerPlayer extends Player {
- ResourceKey resourcekey = worldserver1.getTypeKey(); // CraftBukkit
-
- if (resourcekey == LevelStem.END && worldserver != null && worldserver.getTypeKey() == LevelStem.OVERWORLD) { // CraftBukkit
-+ io.papermc.paper.util.TickThread.ensureOnlyTickThread("Cannot change dimension of a player off-main, from world " + serverLevel().getWorld().getName() + " to world " + worldserver.getWorld().getName()); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
- this.isChangingDimension = true; // CraftBukkit - Moved down from above
- this.unRide();
- this.serverLevel().removePlayerImmediately(this, Entity.RemovalReason.CHANGED_DIMENSION);
-@@ -1275,6 +1278,10 @@ public class ServerPlayer extends Player {
-
- return this;
- } else {
-+ if (worldserver != null)
-+ io.papermc.paper.util.TickThread.ensureOnlyTickThread("Cannot change dimension of a player off-main, from world " + serverLevel().getWorld().getName() + " to world " + worldserver.getWorld().getName()); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
-+ else
-+ io.papermc.paper.util.TickThread.ensureOnlyTickThread("Cannot change dimension of a player off-main, from world " + serverLevel().getWorld().getName() + " to unknown world"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
+@@ -1335,6 +1337,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
+ ServerLevel worldserver1 = this.serverLevel();
// CraftBukkit start
- /*
- WorldData worlddata = worldserver.getLevelData();
-@@ -1700,6 +1707,12 @@ public class ServerPlayer extends Player {
+ ResourceKey resourcekey = worldserver1.getTypeKey();
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureOnlyTickThread("Cannot change dimension of a player off-main, from world " + serverLevel().getWorld().getName() + " to world " + worldserver.getWorld().getName()); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
+
+ if (worldserver != null && worldserver.dimension() == worldserver1.dimension()) { // CraftBukkit
+ // Paper start - gateway-specific teleport event
+@@ -1723,6 +1726,12 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
return OptionalInt.empty();
} else {
// CraftBukkit start
@@ -917,7 +755,7 @@ index 6a4637eef14cbd84bbe26ef16f004b8f93367a3d..f359ecb161024ad8a6de6d20e9d6de51
this.containerMenu = container;
if (!this.isImmobile()) this.connection.send(new ClientboundOpenScreenPacket(container.containerId, container.getType(), Objects.requireNonNullElseGet(title, container::getTitle))); // Paper - Add titleOverride to InventoryOpenEvent
// CraftBukkit end
-@@ -1761,6 +1774,11 @@ public class ServerPlayer extends Player {
+@@ -1786,6 +1795,11 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
}
@Override
public void closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
@@ -930,7 +768,7 @@ index 6a4637eef14cbd84bbe26ef16f004b8f93367a3d..f359ecb161024ad8a6de6d20e9d6de51
// Paper end - Inventory close reason
this.connection.send(new ClientboundContainerClosePacket(this.containerMenu.containerId));
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index a2142930b4d4b05987c90496fb9d733d99040aa0..3a3519403fab0b83aa98f95155c323c9079a8a3b 100644
+index 0368d6ba9cc9fe557d3c7172a87a7a5b15445e47..fdf15a1c82ddfc8fa2c9149095744eff82575258 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -137,7 +137,7 @@ public abstract class PlayerList {
@@ -955,50 +793,50 @@ index a2142930b4d4b05987c90496fb9d733d99040aa0..3a3519403fab0b83aa98f95155c323c9
abstract public void loadAndSaveFiles(); // Paper - fix converting txt to json file; moved from DedicatedPlayerList constructor
public void placeNewPlayer(Connection connection, ServerPlayer player, CommonListenerCookie clientData) {
-+ io.papermc.paper.util.TickThread.ensureOnlyTickThread("Cannot place new player off-main"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureOnlyTickThread("Cannot place new player off-main"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
player.isRealPlayer = true; // Paper
player.loginTime = System.currentTimeMillis(); // Paper - Replace OfflinePlayer#getLastPlayed
GameProfile gameprofile = player.getGameProfile();
-@@ -817,6 +818,8 @@ public abstract class PlayerList {
+@@ -806,6 +807,8 @@ public abstract class PlayerList {
}
- public ServerPlayer respawn(ServerPlayer entityplayer, ServerLevel worldserver, boolean flag, Location location, boolean avoidSuffocation, RespawnReason reason, org.bukkit.event.player.PlayerRespawnEvent.RespawnFlag...respawnFlags) {
+ public ServerPlayer respawn(ServerPlayer entityplayer, boolean flag, Entity.RemovalReason entity_removalreason, RespawnReason reason, Location location) {
+ System.out.println("respawning player - current player container is " + entityplayer.containerMenu + " but their inventory is " + entityplayer.inventoryMenu);
-+ io.papermc.paper.util.TickThread.ensureOnlyTickThread("Cannot respawn player off-main, from world " + entityplayer.serverLevel().getWorld().getName() + " to world " + worldserver.getWorld().getName()); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
- // Paper end - Expand PlayerRespawnEvent
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureOnlyTickThread("Cannot respawn player off-main, from world " + entityplayer.serverLevel().getWorld().getName() + " to world " + location.getWorld().getName()); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
entityplayer.stopRiding(); // CraftBukkit
this.players.remove(entityplayer);
-@@ -841,6 +844,7 @@ public abstract class PlayerList {
+ this.playersByName.remove(entityplayer.getScoreboardName().toLowerCase(java.util.Locale.ROOT)); // Spigot
+@@ -818,6 +821,7 @@ public abstract class PlayerList {
ServerPlayer entityplayer1 = entityplayer;
- org.bukkit.World fromWorld = entityplayer.getBukkitEntity().getWorld();
+ Level fromWorld = entityplayer.level();
entityplayer.wonGame = false;
+ entityplayer.hasTickedAtLeastOnceInNewWorld = false; // SparklyPaper - parallel world ticking (see: PARALLEL_NOTES.md - Opening an inventory after a world switch)
// CraftBukkit end
entityplayer1.connection = entityplayer.connection;
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 1d408e938173eb459f6bf1804c65de1141287868..a3c2c26371435d00980beed797ca058a167a51e2 100644
+index 490ee48346395fcbaf2eb0151e9248f18974fea6..43413e1ee5b0287da5c9a75b6a4d24807b89a656 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
-@@ -869,7 +869,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+@@ -851,7 +851,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
// CraftBukkit start
public void postTick() {
// No clean way to break out of ticking once the entity has been copied to a new world, so instead we move the portalling later in the tick cycle
- if (!(this instanceof ServerPlayer) && this.isAlive()) { // Paper - don't attempt to teleport dead entities
+ if (false && !(this instanceof ServerPlayer) && this.isAlive()) { // Paper - don't attempt to teleport dead entities // SparklyPaper - parallel world ticking (see issue #9, this is executed in the server level tick for non-player entities)
- this.handleNetherPortal();
+ this.handlePortal();
}
}
-@@ -4030,6 +4030,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+@@ -3992,6 +3992,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
this.teleportPassengers();
this.setYHeadRot(yaw);
} else {
-+ io.papermc.paper.util.TickThread.ensureTickThread(world, "Cannot teleport entity to another world off-main, from world " + level.getWorld().getName() + " to world " + world.getWorld().getName()); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(world, "Cannot teleport entity to another world off-main, from world " + level.getWorld().getName() + " to world " + world.getWorld().getName()); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
this.unRide();
Entity entity = this.getType().create(world);
diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
-index 32910f677b0522ac8ec513fa0d00b714b52cfae4..864bf4aa487372733da05a58be2c5b61fce18df5 100644
+index dd4218e108f87f3305b76fbc8d88f488b447c609..1f980e8336ad51056aed827ab43f634d60e4c7a1 100644
--- a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
+++ b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
@@ -102,8 +102,14 @@ public abstract class AbstractContainerMenu {
@@ -1017,10 +855,10 @@ index 32910f677b0522ac8ec513fa0d00b714b52cfae4..864bf4aa487372733da05a58be2c5b61
this.remoteSlots = NonNullList.create();
this.remoteDataSlots = new IntArrayList();
diff --git a/src/main/java/net/minecraft/world/item/ArmorItem.java b/src/main/java/net/minecraft/world/item/ArmorItem.java
-index 786e4a8700cb84b16dd9b8892a0d1d5803924d81..a54754c4ff7bfb5101d362bc3a8b3073bcc6efd9 100644
+index 647a4601deace52f8d855f512a73671f82b4762a..5b09aeb13537bb59017160cb4f4bffcc664ac80e 100644
--- a/src/main/java/net/minecraft/world/item/ArmorItem.java
+++ b/src/main/java/net/minecraft/world/item/ArmorItem.java
-@@ -77,7 +77,7 @@ public class ArmorItem extends Item implements Equipable {
+@@ -68,7 +68,7 @@ public class ArmorItem extends Item implements Equipable {
CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1);
BlockDispenseArmorEvent event = new BlockDispenseArmorEvent(block, craftItem.clone(), (org.bukkit.craftbukkit.entity.CraftLivingEntity) entityliving.getBukkitEntity());
@@ -1030,10 +868,10 @@ index 786e4a8700cb84b16dd9b8892a0d1d5803924d81..a54754c4ff7bfb5101d362bc3a8b3073
}
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
-index f8589837070039b4911a9532b92fa959c7af6352..0fb64d495e35e5ad16f2af35df3b683385d8a411 100644
+index b6a2f3e4f22f36e75a1630bd456c2f471edbb398..8a480c92536b33d91b0399cc776ef46bfccb2a3c 100644
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
-@@ -421,8 +421,8 @@ public final class ItemStack implements DataComponentHolder {
+@@ -442,8 +442,8 @@ public final class ItemStack implements DataComponentHolder {
if (enuminteractionresult.consumesAction() && world.captureTreeGeneration && world.capturedBlockStates.size() > 0) {
world.captureTreeGeneration = false;
Location location = CraftLocation.toBukkit(blockposition, world.getWorld());
@@ -1058,19 +896,10 @@ index d524fcc191cb95d6ec7f12ae7fceeb8077bb08fc..451e5719613fc31bacf49c37978d4e49
}
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
-index 6ed4efec4eda74af9472e6e3fc637251f9c2a21c..b51b3ae0774229d3b31471860b3a522ffdb4f5a2 100644
+index 38d73f50360685a573740e811f186d7fa582003c..fa057dc5a98af9067ac4e5f6f116be357cc3dc5a 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
-@@ -10,6 +10,8 @@ import java.util.function.Consumer;
- import java.util.function.Predicate;
- import java.util.function.Supplier;
- import javax.annotation.Nullable;
-+
-+import io.papermc.paper.util.TickThread;
- import net.minecraft.CrashReport;
- import net.minecraft.CrashReportCategory;
- import net.minecraft.ReportedException;
-@@ -172,6 +174,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+@@ -174,6 +174,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
public final com.destroystokyo.paper.antixray.ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray
public net.sparklypower.sparklypaper.configs.SparklyPaperWorldConfig sparklyPaperConfig; // SparklyPaper
@@ -1078,80 +907,48 @@ index 6ed4efec4eda74af9472e6e3fc637251f9c2a21c..b51b3ae0774229d3b31471860b3a522f
public final co.aikar.timings.WorldTimingsHandler timings; // Paper
public static BlockPos lastPhysicsProblem; // Spigot
private org.spigotmc.TickLimiter entityLimiter;
-@@ -814,7 +817,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
- public final LevelChunk getChunk(int chunkX, int chunkZ) { // Paper - final to help inline
- // Paper start - Perf: make sure loaded chunks get the inlined variant of this function
- net.minecraft.server.level.ServerChunkCache cps = ((ServerLevel)this).getChunkSource();
-- if (cps.mainThread == Thread.currentThread()) {
-+ if (TickThread.isTickThreadFor((ServerLevel) this, chunkX, chunkZ)) { // SparklyPaper - parallel world ticking, let tick threads load chunks via the main thread
- LevelChunk ifLoaded = cps.getChunkAtIfLoadedMainThread(chunkX, chunkZ);
- if (ifLoaded != null) {
- return ifLoaded;
-@@ -898,6 +901,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+@@ -1016,6 +1017,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
@Override
public boolean setBlock(BlockPos pos, BlockState state, int flags, int maxUpdateDepth) {
-+ io.papermc.paper.util.TickThread.ensureTickThread((ServerLevel)this, pos, "Updating block asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread((ServerLevel)this, pos, "Updating block asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
// CraftBukkit start - tree generation
if (this.captureTreeGeneration) {
// Paper start - Protect Bedrock and End Portal/Frames from being destroyed
-@@ -1297,7 +1301,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
- tickingblockentity.tick();
- // Paper start - execute chunk tasks during tick
- if ((this.tileTickPosition & 7) == 0) {
-- MinecraftServer.getServer().executeMidTickTasks();
-+ // MinecraftServer.getServer().executeMidTickTasks(); // SparklyPaper - parallel world ticking (only run mid-tick at the end of each tick / fixes concurrency bugs related to executeMidTickTasks)
- }
- // Paper end - execute chunk tasks during tick
- } // SparklyPaper end
-@@ -1314,7 +1318,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
- public void guardEntityTick(Consumer tickConsumer, T entity) {
- try {
- tickConsumer.accept(entity);
-- MinecraftServer.getServer().executeMidTickTasks(); // Paper - execute chunk tasks mid tick
-+ // MinecraftServer.getServer().executeMidTickTasks(); // SparklyPaper - parallel world ticking (only run mid-tick at the end of each tick / fixes concurrency bugs related to executeMidTickTasks) // Paper - execute chunk tasks mid tick
- } catch (Throwable throwable) {
- if (throwable instanceof ThreadDeath) throw throwable; // Paper
- // Paper start - Prevent block entity and entity crashes
-@@ -1426,6 +1430,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+@@ -1542,6 +1544,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
@Nullable
public BlockEntity getBlockEntity(BlockPos blockposition, boolean validate) {
-+ io.papermc.paper.util.TickThread.ensureTickThreadOrAsyncThread((ServerLevel) this, "Cannot read world asynchronously"); // SparklyPaper start - parallel world ticking
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThreadOrAsyncThread((ServerLevel) this, "Cannot read world asynchronously"); // SparklyPaper start - parallel world ticking
// Paper start - Perf: Optimize capturedTileEntities lookup
net.minecraft.world.level.block.entity.BlockEntity blockEntity;
if (!this.capturedTileEntities.isEmpty() && (blockEntity = this.capturedTileEntities.get(blockposition)) != null) {
-@@ -1433,10 +1438,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
- }
- // Paper end - Perf: Optimize capturedTileEntities lookup
- // CraftBukkit end
-- return this.isOutsideBuildHeight(blockposition) ? null : (!this.isClientSide && !io.papermc.paper.util.TickThread.isTickThread() ? null : this.getChunkAt(blockposition).getBlockEntity(blockposition, LevelChunk.EntityCreationType.IMMEDIATE)); // Paper - rewrite chunk system
-+ return this.isOutsideBuildHeight(blockposition) ? null : (!this.isClientSide && !io.papermc.paper.util.TickThread.isTickThread() ? null : this.getChunkAt(blockposition).getBlockEntity(blockposition, LevelChunk.EntityCreationType.IMMEDIATE)); // Paper - rewrite chunk system // SparklyPaper - parallel world ticking
+@@ -1553,6 +1556,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
}
public void setBlockEntity(BlockEntity blockEntity) {
-+ io.papermc.paper.util.TickThread.ensureTickThread((ServerLevel) this, "Cannot modify world asynchronously"); // SparklyPaper start - parallel world ticking
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread((ServerLevel) this, "Cannot modify world asynchronously"); // SparklyPaper start - parallel world ticking
BlockPos blockposition = blockEntity.getBlockPos();
if (!this.isOutsideBuildHeight(blockposition)) {
-@@ -1522,6 +1528,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+@@ -1638,6 +1642,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
@Override
public List getEntities(@Nullable Entity except, AABB box, Predicate super Entity> predicate) {
-+ io.papermc.paper.util.TickThread.ensureTickThread((ServerLevel)this, box, "Cannot getEntities asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread((ServerLevel)this, box, "Cannot getEntities asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
this.getProfiler().incrementCounter("getEntities");
- List list = Lists.newArrayList();
- ((ServerLevel)this).getEntityLookup().getEntities(except, box, list, predicate); // Paper - optimise this call
-@@ -1784,8 +1791,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
- }
- public final BlockPos.MutableBlockPos getRandomBlockPosition(int x, int y, int z, int l, BlockPos.MutableBlockPos out) {
- // Paper end
+ // Paper start - rewrite chunk system
+ final List ret = new java.util.ArrayList<>();
+@@ -1948,8 +1953,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
+ public abstract RecipeManager getRecipeManager();
+
+ public BlockPos getBlockRandomPos(int x, int y, int z, int l) {
- this.randValue = this.randValue * 3 + 1013904223;
- int i1 = this.randValue >> 2;
+ int i1 = this.random.nextInt() >> 2; // SparklyPaper - parallel world ticking
- out.set(x + (i1 & 15), y + (i1 >> 16 & l), z + (i1 >> 8 & 15)); // Paper - change to setValues call
- return out; // Paper
+ return new BlockPos(x + (i1 & 15), y + (i1 >> 16 & l), z + (i1 >> 8 & 15));
+ }
diff --git a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java
index f6edfea463b3725d3a79aca38825e86dbf82175c..c62d576a94308dece71eaef451280456dd87861c 100644
--- a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java
@@ -1260,7 +1057,7 @@ index d262a5a6da57ef9ba9a6fe0dfbc88f577105e74f..15db3fb971a944e856b3cde86035d290
java.util.List blocks = new java.util.ArrayList<>(world.capturedBlockStates.values());
world.capturedBlockStates.clear();
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
-index 15fd1fe1b55b6421d2c09e8385c9f69fa0152e56..0b6918cbeb39c50efc550b9c46e0da9a65e45a98 100644
+index 2ddf349fde5b310ec3f74baee1f3d33e09d5286c..fe9c3479b61f79ed8ce3659d4e1ead8c9598ea8b 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
@@ -82,6 +82,12 @@ public abstract class BaseContainerBlockEntity extends BlockEntity implements Co
@@ -1277,10 +1074,10 @@ index 15fd1fe1b55b6421d2c09e8385c9f69fa0152e56..0b6918cbeb39c50efc550b9c46e0da9a
final org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(blockEntity.getLevel(), blockEntity.getBlockPos());
net.kyori.adventure.text.Component lockedMessage = net.kyori.adventure.text.Component.translatable("container.isLocked", io.papermc.paper.adventure.PaperAdventure.asAdventure(containerName));
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
-index 81dd0aa6a90fd9dda9e7752f85b9cf4568e3b575..951bf47de0397b44cbe6a2c00a6675608dbdc122 100644
+index a74732902c0494c67e6acf2fc04581ff9c46b832..fe9d7f0f800222c6eaafa903562c6106c09e84f2 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
-@@ -45,9 +45,9 @@ public class SculkCatalystBlockEntity extends BlockEntity implements GameEventLi
+@@ -46,9 +46,9 @@ public class SculkCatalystBlockEntity extends BlockEntity implements GameEventLi
// Paper end - Fix NPE in SculkBloomEvent world access
public static void serverTick(Level world, BlockPos pos, BlockState state, SculkCatalystBlockEntity blockEntity) {
@@ -1372,25 +1169,25 @@ index 597599138f69c9ee05dc7657c51c25336337875e..c9876514091f5cd0fc9c24b4f1577b1a
// CraftBukkit end
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
-index 9af0da6c3a9805542b1b31fb32f0b3bcb1efe1c8..20a30a79f9412746a1b727730ddf3975affb25a0 100644
+index d7fe57e9a5aa59a7a9d611bcaa6152e72ec4c300..ca31e6bbb3a7af56b0cd08eaffc1c0e60042b8eb 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
-@@ -419,6 +419,7 @@ public class LevelChunk extends ChunkAccess {
+@@ -359,6 +359,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
@Nullable
public BlockState setBlockState(BlockPos blockposition, BlockState iblockdata, boolean flag, boolean doPlace) {
-+ io.papermc.paper.util.TickThread.ensureTickThread(this.level, blockposition, "Updating block asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.level, blockposition, "Updating block asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
// CraftBukkit end
int i = blockposition.getY();
LevelChunkSection chunksection = this.getSection(this.getSectionIndex(i));
diff --git a/src/main/java/net/minecraft/world/level/entity/EntityTickList.java b/src/main/java/net/minecraft/world/level/entity/EntityTickList.java
-index 83a39f900551e39d5af6f17a339a386ddee4feef..1f3ae0cc95a7e9ca9380493315ace4e127e4e5c0 100644
+index d8b4196adf955f8d414688dc451caac2d9c609d9..56089483da1313d2da90c1921af33c2d81024680 100644
--- a/src/main/java/net/minecraft/world/level/entity/EntityTickList.java
+++ b/src/main/java/net/minecraft/world/level/entity/EntityTickList.java
-@@ -10,19 +10,26 @@ import net.minecraft.world.entity.Entity;
+@@ -10,17 +10,26 @@ import net.minecraft.world.entity.Entity;
public class EntityTickList {
- private final io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet entities = new io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet<>(true); // Paper - rewrite this, always keep this updated - why would we EVER tick an entity that's not ticking?
+ private final ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet entities = new ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet<>(); // Paper - rewrite chunk system
+ // SparklyPaper start - parallel world ticking
+ // Used to track async entity additions/removals/loops
+ private final net.minecraft.server.level.ServerLevel serverLevel;
@@ -1400,31 +1197,29 @@ index 83a39f900551e39d5af6f17a339a386ddee4feef..1f3ae0cc95a7e9ca9380493315ace4e1
+ // SparklyPaper end
private void ensureActiveIsNotIterated() {
- // Paper - replace with better logic, do not delay removals
+ // Paper - rewrite chunk system
}
public void add(Entity entity) {
-- io.papermc.paper.util.TickThread.ensureTickThread("Asynchronous entity ticklist addition"); // Paper
-+ io.papermc.paper.util.TickThread.ensureTickThread(entity, "Asynchronous entity ticklist addition"); // Paper // SparklyPaper - parallel world ticking (additional concurrency issues logs)
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(entity, "Asynchronous entity ticklist addition"); // Paper // SparklyPaper - parallel world ticking (additional concurrency issues logs)
this.ensureActiveIsNotIterated();
- this.entities.add(entity); // Paper - replace with better logic, do not delay removals/additions
+ this.entities.add(entity); // Paper - rewrite chunk system
}
public void remove(Entity entity) {
-- io.papermc.paper.util.TickThread.ensureTickThread("Asynchronous entity ticklist removal"); // Paper
-+ io.papermc.paper.util.TickThread.ensureTickThread(entity, "Asynchronous entity ticklist removal"); // Paper // SparklyPaper - parallel world ticking (additional concurrency issues logs)
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(entity, "Asynchronous entity ticklist removal"); // Paper // SparklyPaper - parallel world ticking (additional concurrency issues logs)
this.ensureActiveIsNotIterated();
- this.entities.remove(entity); // Paper - replace with better logic, do not delay removals/additions
+ this.entities.remove(entity); // Paper - rewrite chunk system
}
-@@ -32,7 +39,7 @@ public class EntityTickList {
+@@ -30,7 +39,7 @@ public class EntityTickList {
}
public void forEach(Consumer action) {
-- io.papermc.paper.util.TickThread.ensureTickThread("Asynchronous entity ticklist iteration"); // Paper
-+ io.papermc.paper.util.TickThread.ensureTickThread(serverLevel, "Asynchronous entity ticklist iteration"); // Paper // SparklyPaper - parallel world ticking (additional concurrency issues logs)
- // Paper start - replace with better logic, do not delay removals/additions
+- // Paper start - rewrite chunk system
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverLevel, "Asynchronous entity ticklist iteration"); // Paper // SparklyPaper - parallel world ticking (additional concurrency issues logs)
// To ensure nothing weird happens with dimension travelling, do not iterate over new entries...
// (by dfl iterator() is configured to not iterate over new entries)
+ final ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet.Iterator iterator = this.entities.iterator();
diff --git a/src/main/java/net/minecraft/world/level/saveddata/maps/MapIndex.java b/src/main/java/net/minecraft/world/level/saveddata/maps/MapIndex.java
index 763b315b1d761bc3bd82d9b847ed3f64fd5ce991..b67dddabbae835cbe7261768fb14bfac4ad6c921 100644
--- a/src/main/java/net/minecraft/world/level/saveddata/maps/MapIndex.java
@@ -1452,103 +1247,102 @@ index 763b315b1d761bc3bd82d9b847ed3f64fd5ce991..b67dddabbae835cbe7261768fb14bfac
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index 6303760f10af17f1da1d92d6c4dc7dd6f5778f94..8037850766e76ff92941eb071b4154fba9163ddc 100644
+index 362ca138a5cd5ad19f1300015c2571794adc3649..77b22e34355cfe0054c1bc78a48d5289ff9e45ee 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -449,7 +449,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -428,7 +428,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
}
private boolean unloadChunk0(int x, int z, boolean save) {
- org.spigotmc.AsyncCatcher.catchOp("chunk unload"); // Spigot
-+ io.papermc.paper.util.TickThread.ensureTickThread(this.world, x, z, "Cannot unload chunk asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, x, z, "Cannot unload chunk asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
if (!this.isChunkLoaded(x, z)) {
return true;
}
-@@ -464,7 +464,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
-
- @Override
- public boolean regenerateChunk(int x, int z) {
-- org.spigotmc.AsyncCatcher.catchOp("chunk regenerate"); // Spigot
-+ io.papermc.paper.util.TickThread.ensureTickThread(this.world, x, z, "Cannot regenerate chunk asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
+@@ -449,6 +449,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+ if (!unloadChunk0(x, z, false)) {
+ return false;
+ }
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, x, z, "Cannot regenerate chunk asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
warnUnsafeChunk("regenerating a faraway chunk", x, z); // Paper
- // Paper start - implement regenerateChunk method
- final ServerLevel serverLevel = this.world;
-@@ -529,6 +529,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+
+ final long chunkKey = ChunkCoordIntPair.pair(x, z);
+@@ -470,6 +471,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public boolean refreshChunk(int x, int z) {
-+ io.papermc.paper.util.TickThread.ensureTickThread(this.world, x, z, "Cannot refresh chunk asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, x, z, "Cannot refresh chunk asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
ChunkHolder playerChunk = this.world.getChunkSource().chunkMap.getVisibleChunkIfPresent(ChunkPos.asLong(x, z));
if (playerChunk == null) return false;
-@@ -589,7 +590,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -530,7 +532,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public boolean loadChunk(int x, int z, boolean generate) {
- org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot
-+ io.papermc.paper.util.TickThread.ensureTickThread(this.getHandle(), x, z, "May not sync load chunks asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.getHandle(), x, z, "May not sync load chunks asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
warnUnsafeChunk("loading a faraway chunk", x, z); // Paper
- // Paper start - Optimize this method
- ChunkPos chunkPos = new ChunkPos(x, z);
-@@ -868,6 +869,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+ ChunkAccess chunk = this.world.getChunkSource().getChunk(x, z, generate || isChunkGenerated(x, z) ? ChunkStatus.FULL : ChunkStatus.EMPTY, true); // Paper
+
+@@ -782,6 +784,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public boolean generateTree(Location loc, TreeType type, BlockChangeDelegate delegate) {
-+ io.papermc.paper.util.TickThread.ensureTickThread(this.world, loc.getX(), loc.getZ(), "Cannot generate tree asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, loc.getX(), loc.getZ(), "Cannot generate tree asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
this.world.captureTreeGeneration = true;
this.world.captureBlockStates = true;
boolean grownTree = this.generateTree(loc, type);
-@@ -978,6 +980,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -892,6 +895,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public boolean createExplosion(double x, double y, double z, float power, boolean setFire, boolean breakBlocks, Entity source) {
-+ io.papermc.paper.util.TickThread.ensureTickThread(this.world, x, z, "Cannot create explosion asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, x, z, "Cannot create explosion asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
net.minecraft.world.level.Level.ExplosionInteraction explosionType;
if (!breakBlocks) {
explosionType = net.minecraft.world.level.Level.ExplosionInteraction.NONE; // Don't break blocks
-@@ -992,6 +995,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -906,6 +910,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
// Paper start
@Override
public boolean createExplosion(Entity source, Location loc, float power, boolean setFire, boolean breakBlocks) {
-+ io.papermc.paper.util.TickThread.ensureTickThread(world, loc.getX(), loc.getZ(), "Cannot create explosion asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(world, loc.getX(), loc.getZ(), "Cannot create explosion asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
return !world.explode(source != null ? ((org.bukkit.craftbukkit.entity.CraftEntity) source).getHandle() : null, loc.getX(), loc.getY(), loc.getZ(), power, setFire, breakBlocks ? net.minecraft.world.level.Level.ExplosionInteraction.MOB : net.minecraft.world.level.Level.ExplosionInteraction.NONE).wasCanceled;
}
// Paper end
-@@ -1068,6 +1072,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -982,6 +987,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public int getHighestBlockYAt(int x, int z, org.bukkit.HeightMap heightMap) {
-+ io.papermc.paper.util.TickThread.ensureTickThread(this.world, x >> 4, z >> 4, "Cannot retrieve chunk asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, x >> 4, z >> 4, "Cannot retrieve chunk asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
warnUnsafeChunk("getting a faraway chunk", x >> 4, z >> 4); // Paper
// Transient load for this tick
return this.world.getChunk(x >> 4, z >> 4).getHeight(CraftHeightMap.toNMS(heightMap), x, z);
-@@ -1098,6 +1103,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -1012,6 +1018,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public void setBiome(int x, int y, int z, Holder bb) {
BlockPos pos = new BlockPos(x, 0, z);
-+ io.papermc.paper.util.TickThread.ensureTickThread(this.world, pos, "Cannot retrieve chunk asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, pos, "Cannot retrieve chunk asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
if (this.world.hasChunkAt(pos)) {
net.minecraft.world.level.chunk.LevelChunk chunk = this.world.getChunkAt(pos);
-@@ -2392,6 +2398,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -2281,6 +2288,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public void sendGameEvent(Entity sourceEntity, org.bukkit.GameEvent gameEvent, Vector position) {
-+ io.papermc.paper.util.TickThread.ensureTickThread(this.world, position.getX(), position.getZ(), "Cannot send game event asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, position.getX(), position.getZ(), "Cannot send game event asynchronously"); // SparklyPaper - parallel world ticking (additional concurrency issues logs)
getHandle().gameEvent(sourceEntity != null ? ((CraftEntity) sourceEntity).getHandle(): null, net.minecraft.core.registries.BuiltInRegistries.GAME_EVENT.getHolder(org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(gameEvent.getKey())).orElseThrow(), org.bukkit.craftbukkit.util.CraftVector.toBlockPos(position));
}
// Paper end
-@@ -2520,7 +2527,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -2409,7 +2417,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
// Paper start
public java.util.concurrent.CompletableFuture getChunkAtAsync(int x, int z, boolean gen, boolean urgent) {
warnUnsafeChunk("getting a faraway chunk async", x, z); // Paper
- if (Bukkit.isPrimaryThread()) {
-+ if (io.papermc.paper.util.TickThread.isTickThreadFor(this.getHandle(), x, z)) { // SparklyPaper - parallel world ticking
++ if (ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(this.getHandle(), x, z)) { // SparklyPaper - parallel world ticking
net.minecraft.world.level.chunk.LevelChunk immediate = this.world.getChunkSource().getChunkAtIfLoadedImmediately(x, z);
if (immediate != null) {
return java.util.concurrent.CompletableFuture.completedFuture(new CraftChunk(immediate));
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
-index ac11f18690434922179b61ffcc3036dea025b0cb..f6470c32af48f73c2668d2014e736d827f947379 100644
+index ac11f18690434922179b61ffcc3036dea025b0cb..59b8136ebd0100f0f8e6ded002486b37415ddc73 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -75,6 +75,11 @@ public class CraftBlock implements Block {
@@ -1557,7 +1351,7 @@ index ac11f18690434922179b61ffcc3036dea025b0cb..f6470c32af48f73c2668d2014e736d82
public net.minecraft.world.level.block.state.BlockState getNMS() {
+ // Folia start - parallel world ticking
+ if (world instanceof ServerLevel serverWorld) {
-+ io.papermc.paper.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously");
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously");
+ }
+ // Folia end - parallel world ticking
return this.world.getBlockState(this.position);
@@ -1569,7 +1363,7 @@ index ac11f18690434922179b61ffcc3036dea025b0cb..f6470c32af48f73c2668d2014e736d82
private void setData(final byte data, int flag) {
+ // SparklyPaper start - parallel world ticking
+ if (world instanceof ServerLevel serverWorld) {
-+ io.papermc.paper.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously");
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously");
+ }
+ // SparklyPaper end - parallel world ticking
this.world.setBlock(this.position, CraftMagicNumbers.getBlock(this.getType(), data), flag);
@@ -1581,7 +1375,7 @@ index ac11f18690434922179b61ffcc3036dea025b0cb..f6470c32af48f73c2668d2014e736d82
public static boolean setTypeAndData(LevelAccessor world, BlockPos position, net.minecraft.world.level.block.state.BlockState old, net.minecraft.world.level.block.state.BlockState blockData, boolean applyPhysics) {
+ // SparklyPaper start - parallel world ticking
+ if (world instanceof ServerLevel serverWorld) {
-+ io.papermc.paper.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously");
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously");
+ }
+ // SparklyPaper end - parallel world ticking
+
@@ -1594,7 +1388,7 @@ index ac11f18690434922179b61ffcc3036dea025b0cb..f6470c32af48f73c2668d2014e736d82
public Biome getBiome() {
+ // SparklyPaper start - parallel world ticking
+ if (world instanceof ServerLevel serverWorld) {
-+ io.papermc.paper.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously");
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously");
+ }
+ // SparklyPaper end - parallel world ticking
return this.getWorld().getBiome(this.getX(), this.getY(), this.getZ());
@@ -1605,7 +1399,7 @@ index ac11f18690434922179b61ffcc3036dea025b0cb..f6470c32af48f73c2668d2014e736d82
public Biome getComputedBiome() {
+ // SparklyPaper start - parallel world ticking
+ if (world instanceof ServerLevel serverWorld) {
-+ io.papermc.paper.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously");
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously");
+ }
+ // SparklyPaper end - parallel world ticking
return this.getWorld().getComputedBiome(this.getX(), this.getY(), this.getZ());
@@ -1616,7 +1410,7 @@ index ac11f18690434922179b61ffcc3036dea025b0cb..f6470c32af48f73c2668d2014e736d82
public void setBiome(Biome bio) {
+ // SparklyPaper start - parallel world ticking
+ if (world instanceof ServerLevel serverWorld) {
-+ io.papermc.paper.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously");
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously");
+ }
+ // SparklyPaper end - parallel world ticking
this.getWorld().setBiome(this.getX(), this.getY(), this.getZ(), bio);
@@ -1628,7 +1422,7 @@ index ac11f18690434922179b61ffcc3036dea025b0cb..f6470c32af48f73c2668d2014e736d82
public boolean isBlockFaceIndirectlyPowered(BlockFace face) {
+ // SparklyPaper start - parallel world ticking
+ if (world instanceof ServerLevel serverWorld) {
-+ io.papermc.paper.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously");
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously");
+ }
+ // SparklyPaper end - parallel world ticking
int power = this.world.getMinecraftWorld().getSignal(this.position, CraftBlock.blockFaceToNotch(face));
@@ -1640,7 +1434,7 @@ index ac11f18690434922179b61ffcc3036dea025b0cb..f6470c32af48f73c2668d2014e736d82
public int getBlockPower(BlockFace face) {
+ // SparklyPaper start - parallel world ticking
+ if (world instanceof ServerLevel serverWorld) {
-+ io.papermc.paper.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously");
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously");
+ }
+ // SparklyPaper end - parallel world ticking
int power = 0;
@@ -1652,7 +1446,7 @@ index ac11f18690434922179b61ffcc3036dea025b0cb..f6470c32af48f73c2668d2014e736d82
public boolean breakNaturally() {
+ // SparklyPaper start - parallel world ticking
+ if (world instanceof ServerLevel serverWorld) {
-+ io.papermc.paper.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously");
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously");
+ }
+ // SparklyPaper end - parallel world ticking
return this.breakNaturally(null);
@@ -1664,7 +1458,7 @@ index ac11f18690434922179b61ffcc3036dea025b0cb..f6470c32af48f73c2668d2014e736d82
public boolean applyBoneMeal(BlockFace face) {
+ // SparklyPaper start - parallel world ticking
+ if (world instanceof ServerLevel serverWorld) {
-+ io.papermc.paper.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously");
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously");
+ }
+ // SparklyPaper end - parallel world ticking
Direction direction = CraftBlock.blockFaceToNotch(face);
@@ -1687,7 +1481,7 @@ index ac11f18690434922179b61ffcc3036dea025b0cb..f6470c32af48f73c2668d2014e736d82
public RayTraceResult rayTrace(Location start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode) {
+ // SparklyPaper start - parallel world ticking
+ if (world instanceof ServerLevel serverWorld) {
-+ io.papermc.paper.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously");
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously");
+ }
+ // SparklyPaper end - parallel world ticking
Preconditions.checkArgument(start != null, "Location start cannot be null");
@@ -1699,7 +1493,7 @@ index ac11f18690434922179b61ffcc3036dea025b0cb..f6470c32af48f73c2668d2014e736d82
public boolean canPlace(BlockData data) {
+ // SparklyPaper start - parallel world ticking
+ if (world instanceof ServerLevel serverWorld) {
-+ io.papermc.paper.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously");
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot read world asynchronously");
+ }
+ // SparklyPaper end - parallel world ticking
Preconditions.checkArgument(data != null, "BlockData cannot be null");
@@ -1711,7 +1505,7 @@ index ac11f18690434922179b61ffcc3036dea025b0cb..f6470c32af48f73c2668d2014e736d82
public void tick() {
+ // SparklyPaper start - parallel world ticking
+ if (world instanceof ServerLevel serverWorld) {
-+ io.papermc.paper.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously");
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously");
+ }
+ // SparklyPaper end - parallel world ticking
final ServerLevel level = this.world.getMinecraftWorld();
@@ -1742,7 +1536,7 @@ index cee3fe00cc662f095e7d726b5f1a913cd8199210..bf1be2997d72767f0e953e735a7c4812
} else {
this.snapshot = this.createSnapshot(tileEntity);
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
-index fa63a6cfcfcc4eee4503a82d85333c139c8c8b2b..1f784235d3471acbf0a3ffe3ab551d7fd899e9ef 100644
+index fa63a6cfcfcc4eee4503a82d85333c139c8c8b2b..9856860ee2987738bbcad5d752670e30f569ba74 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
@@ -215,6 +215,12 @@ public class CraftBlockState implements BlockState {
@@ -1751,7 +1545,7 @@ index fa63a6cfcfcc4eee4503a82d85333c139c8c8b2b..1f784235d3471acbf0a3ffe3ab551d7f
+ // SparklyPaper start - parallel world ticking
+ if (access instanceof net.minecraft.server.level.ServerLevel serverWorld) {
-+ io.papermc.paper.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously");
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(serverWorld, position, "Cannot modify world asynchronously");
+ }
+ // SparklyPaper end - parallel world ticking
+
@@ -1762,7 +1556,7 @@ index fa63a6cfcfcc4eee4503a82d85333c139c8c8b2b..1f784235d3471acbf0a3ffe3ab551d7f
@Override
public java.util.Collection getDrops(org.bukkit.inventory.ItemStack item, org.bukkit.entity.Entity entity) {
-+ io.papermc.paper.util.TickThread.ensureTickThread(world.getHandle(), position, "Cannot modify world asynchronously"); // SparklyPaper - parallel world ticking
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(world.getHandle(), position, "Cannot modify world asynchronously"); // SparklyPaper - parallel world ticking
this.requirePlaced();
net.minecraft.world.item.ItemStack nms = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(item);
@@ -1791,10 +1585,10 @@ index b7ff7af2513204b151340538d50a65c850bdb75f..45f9b2594e449926d7f00f64bf12fef2
// Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
-index 4de9187d66d10b5a2c0ee8fe11b585f5d369df4f..d40f9fa716eed3f9fda532d39037a293727d694b 100644
+index 6d166a6662ed2badfdc9cb42ca4374dc8d640404..22461fbf08a1eeede52ae2a170517cd914f3cfea 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
-@@ -942,7 +942,7 @@ public class CraftEventFactory {
+@@ -953,7 +953,7 @@ public class CraftEventFactory {
return CraftEventFactory.handleBlockSpreadEvent(world, source, target, block, 2);
}
@@ -1803,7 +1597,7 @@ index 4de9187d66d10b5a2c0ee8fe11b585f5d369df4f..d40f9fa716eed3f9fda532d39037a293
public static boolean handleBlockSpreadEvent(LevelAccessor world, BlockPos source, BlockPos target, net.minecraft.world.level.block.state.BlockState block, int flag) {
// Suppress during worldgen
-@@ -954,7 +954,7 @@ public class CraftEventFactory {
+@@ -965,7 +965,7 @@ public class CraftEventFactory {
CraftBlockState state = CraftBlockStates.getBlockState(world, target, flag);
state.setData(block);
@@ -1812,7 +1606,25 @@ index 4de9187d66d10b5a2c0ee8fe11b585f5d369df4f..d40f9fa716eed3f9fda532d39037a293
Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()) {
-@@ -2171,7 +2171,7 @@ public class CraftEventFactory {
+@@ -992,7 +992,7 @@ public class CraftEventFactory {
+ // Paper end
+ CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity();
+ CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource);
+- EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(damageSource.getEntity())); // Paper - Restore vanilla drops behavior
++ EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, new ca.spottedleaf.moonrise.common.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(damageSource.getEntity())); // Paper - Restore vanilla drops behavior
+ populateFields(victim, event); // Paper - make cancellable
+ CraftWorld world = (CraftWorld) entity.getWorld();
+ Bukkit.getServer().getPluginManager().callEvent(event);
+@@ -1023,7 +1023,7 @@ public class CraftEventFactory {
+ public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, DamageSource damageSource, List drops, net.kyori.adventure.text.Component deathMessage, boolean keepInventory) { // Paper - Adventure & Restore vanilla drops behavior
+ CraftPlayer entity = victim.getBukkitEntity();
+ CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource);
+- PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(damageSource.getEntity()), 0, deathMessage); // Paper - Restore vanilla drops behavior
++ PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, new ca.spottedleaf.moonrise.common.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(damageSource.getEntity()), 0, deathMessage); // Paper - Restore vanilla drops behavior
+ event.setKeepInventory(keepInventory);
+ event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel
+ populateFields(victim, event); // Paper - make cancellable
+@@ -2243,7 +2243,7 @@ public class CraftEventFactory {
CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemStack.copyWithCount(1));
org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(bukkitBlock, craftItem.clone(), CraftVector.toBukkit(to));
@@ -1823,15 +1635,14 @@ index 4de9187d66d10b5a2c0ee8fe11b585f5d369df4f..d40f9fa716eed3f9fda532d39037a293
}
diff --git a/src/main/kotlin/net/sparklypower/sparklypaper/ServerLevelTickExecutorThreadFactory.kt b/src/main/kotlin/net/sparklypower/sparklypaper/ServerLevelTickExecutorThreadFactory.kt
new file mode 100644
-index 0000000000000000000000000000000000000000..3d536f724ffdae462e3af39e85e4e39190696c37
+index 0000000000000000000000000000000000000000..9a40afbd7e5085179dc016c900ecb60e98250daf
--- /dev/null
+++ b/src/main/kotlin/net/sparklypower/sparklypaper/ServerLevelTickExecutorThreadFactory.kt
-@@ -0,0 +1,21 @@
+@@ -0,0 +1,20 @@
+package net.sparklypower.sparklypaper
+
-+import io.papermc.paper.util.TickThread
++import ca.spottedleaf.moonrise.common.util.TickThread
+import java.util.concurrent.ThreadFactory
-+import java.util.concurrent.atomic.AtomicInteger
+
+class ServerLevelTickExecutorThreadFactory(private val worldName: String) : ThreadFactory {
+ override fun newThread(p0: Runnable): Thread {
@@ -1861,3 +1672,16 @@ index 8b78f0e8b1de1a6a2506e686be9d71ced72352dd..ce608ca9640cdea0fe690ef610213558
fun init(configFile: File) {
// Write default config if the file doesn't exist
+diff --git a/src/test/java/io/papermc/paper/adventure/AdventureCodecsTest.java b/src/test/java/io/papermc/paper/adventure/AdventureCodecsTest.java
+index 69b3aa957161e75d6344e437a8b4a4533ef00523..4b6252c9403dba1f2443ebbec4fa8fd29ba154cf 100644
+--- a/src/test/java/io/papermc/paper/adventure/AdventureCodecsTest.java
++++ b/src/test/java/io/papermc/paper/adventure/AdventureCodecsTest.java
+@@ -6,7 +6,7 @@ import com.mojang.serialization.DataResult;
+ import com.mojang.serialization.DynamicOps;
+ import com.mojang.serialization.JavaOps;
+ import com.mojang.serialization.JsonOps;
+-import io.papermc.paper.util.MethodParameterSource;
++import ca.spottedleaf.moonrise.common.util.MethodParameterSource;
+ import java.io.IOException;
+ import java.lang.annotation.ElementType;
+ import java.lang.annotation.Retention;
diff --git a/patches/server/0025-SPARKLYPOWER-Remap-SparklyPower-hacky-legacy-NBT-tag.patch b/patches/server/0023-SPARKLYPOWER-Remap-SparklyPower-hacky-legacy-NBT-tag.patch
similarity index 97%
rename from patches/server/0025-SPARKLYPOWER-Remap-SparklyPower-hacky-legacy-NBT-tag.patch
rename to patches/server/0023-SPARKLYPOWER-Remap-SparklyPower-hacky-legacy-NBT-tag.patch
index 9509c1d..0691e20 100644
--- a/patches/server/0025-SPARKLYPOWER-Remap-SparklyPower-hacky-legacy-NBT-tag.patch
+++ b/patches/server/0023-SPARKLYPOWER-Remap-SparklyPower-hacky-legacy-NBT-tag.patch
@@ -6,7 +6,7 @@ Subject: [PATCH] SPARKLYPOWER Remap SparklyPower hacky legacy NBT tags
This is only useful for us in SparklyPower, but yeah...
diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterItemStackToDataComponents.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterItemStackToDataComponents.java
-index a5a21d1c7579e45b78eae4b42a9f023db74acc0a..921947048648ff4555b80be4ef669a6dd53b12af 100644
+index 2d29d89cc45866822189a62bffbe1a8fe57c477b..f54dd842ed40f2a2854c232b17009f932a1926a8 100644
--- a/src/main/java/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterItemStackToDataComponents.java
+++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterItemStackToDataComponents.java
@@ -9,6 +9,7 @@ import ca.spottedleaf.dataconverter.types.ObjectType;
@@ -17,7 +17,7 @@ index a5a21d1c7579e45b78eae4b42a9f023db74acc0a..921947048648ff4555b80be4ef669a6d
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
-@@ -1220,6 +1221,7 @@ public final class ConverterItemStackToDataComponents {
+@@ -1221,6 +1222,7 @@ public final class ConverterItemStackToDataComponents {
ret.setString("id", this.id);
ret.setInt("count", this.count);
if (!this.tag.isEmpty()) {
diff --git a/patches/server/0026-SPARKLYPOWER-Add-custom-blocks.patch b/patches/server/0024-SPARKLYPOWER-Add-custom-blocks.patch
similarity index 87%
rename from patches/server/0026-SPARKLYPOWER-Add-custom-blocks.patch
rename to patches/server/0024-SPARKLYPOWER-Add-custom-blocks.patch
index aeef9b8..6ad7023 100644
--- a/patches/server/0026-SPARKLYPOWER-Add-custom-blocks.patch
+++ b/patches/server/0024-SPARKLYPOWER-Add-custom-blocks.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] SPARKLYPOWER Add custom blocks
diff --git a/src/main/java/net/minecraft/world/level/block/Blocks.java b/src/main/java/net/minecraft/world/level/block/Blocks.java
-index 260906f493416d98ab574a7262fce5e9b7e40c64..92b6f69e60bfafe5f325b9b16df0e56a73c52124 100644
+index 223259e7a09ada681b6181c898f6857888594f85..ad5ad428b72f696a68a9ed1436bede7135c534e5 100644
--- a/src/main/java/net/minecraft/world/level/block/Blocks.java
+++ b/src/main/java/net/minecraft/world/level/block/Blocks.java
-@@ -42,9 +42,9 @@ import net.minecraft.world.level.material.PushReaction;
+@@ -41,9 +41,9 @@ import net.minecraft.world.level.material.PushReaction;
public class Blocks {
private static final BlockBehaviour.StatePredicate NOT_CLOSED_SHULKER = (state, world, pos) -> !(
@@ -21,8 +21,8 @@ index 260906f493416d98ab574a7262fce5e9b7e40c64..92b6f69e60bfafe5f325b9b16df0e56a
public static final Block AIR = register("air", new AirBlock(BlockBehaviour.Properties.of().replaceable().noCollission().noLootTable().air()));
public static final Block STONE = register(
"stone",
-@@ -7658,6 +7658,48 @@ public class Blocks {
- .requiredFeatures(FeatureFlags.UPDATE_1_21)
+@@ -7623,6 +7623,48 @@ public class Blocks {
+ .explosionResistance(1200.0F)
)
);
+ // SparklyPaper start - SparklyPower Survival custom blocks
@@ -71,13 +71,13 @@ index 260906f493416d98ab574a7262fce5e9b7e40c64..92b6f69e60bfafe5f325b9b16df0e56a
private static ToIntFunction litBlockEmission(int litLevel) {
return state -> state.getValue(BlockStateProperties.LIT) ? litLevel : 0;
diff --git a/src/test/java/org/bukkit/craftbukkit/legacy/LegacyTest.java b/src/test/java/org/bukkit/craftbukkit/legacy/LegacyTest.java
-index 2652359438399f2c3b1092f5dcb37a106ab22068..b5ae0f4f68fc2d90043cbbe092310bd6eb8e004d 100644
+index ef3c97ea99ddf20e9219999927ae80a31dffa7a5..f2f73dd240a703e19e502178f901c61de269ff1b 100644
--- a/src/test/java/org/bukkit/craftbukkit/legacy/LegacyTest.java
+++ b/src/test/java/org/bukkit/craftbukkit/legacy/LegacyTest.java
-@@ -123,7 +123,9 @@ public class LegacyTest extends AbstractTestingBase {
- // 1.20.5
- Material.ARMADILLO_SCUTE, Material.ARMADILLO_SPAWN_EGG, Material.BOGGED_SPAWN_EGG, Material.WIND_CHARGE, Material.WOLF_ARMOR, Material.VAULT, Material.HEAVY_CORE, Material.MACE, Material.FLOW_BANNER_PATTERN, Material.GUSTER_BANNER_PATTERN,
+@@ -125,7 +125,9 @@ public class LegacyTest extends AbstractTestingBase {
Material.FLOW_ARMOR_TRIM_SMITHING_TEMPLATE, Material.BOLT_ARMOR_TRIM_SMITHING_TEMPLATE, Material.FLOW_POTTERY_SHERD, Material.GUSTER_POTTERY_SHERD, Material.SCRAPE_POTTERY_SHERD, Material.BREEZE_ROD, Material.OMINOUS_TRIAL_KEY, Material.OMINOUS_BOTTLE,
+ // 1.21
+ Material.MUSIC_DISC_CREATOR, Material.MUSIC_DISC_CREATOR_MUSIC_BOX, Material.MUSIC_DISC_PRECIPICE,
- //
+ // SparklyPaper start - custom blocks
+ Material.SPARKLYPOWER_RAINBOW_WOOL, Material.SPARKLYPOWER_RAINBOW_CONCRETE, Material.SPARKLYPOWER_RAINBOW_TERRACOTTA, Material.SPARKLYPOWER_ASPHALT_SERVER, Material.SPARKLYPOWER_ASPHALT_SERVER_SLAB, Material.SPARKLYPOWER_ASPHALT_PLAYER, Material.SPARKLYPOWER_ASPHALT_PLAYER_SLAB,
@@ -86,10 +86,10 @@ index 2652359438399f2c3b1092f5dcb37a106ab22068..b5ae0f4f68fc2d90043cbbe092310bd6
private final Set INVERSION_FAILS = new HashSet<>(Arrays.asList(Material.LEGACY_DOUBLE_STEP, Material.LEGACY_GLOWING_REDSTONE_ORE, Material.LEGACY_DIODE_BLOCK_ON, Material.LEGACY_REDSTONE_LAMP_ON, Material.LEGACY_WOOD_DOUBLE_STEP,
diff --git a/src/test/java/org/bukkit/support/AbstractTestingBase.java b/src/test/java/org/bukkit/support/AbstractTestingBase.java
-index 1b1d51a68c0abe7d8f0aa1172064192c71ae645e..5d694ef3ff1bc1e193ff321a09eb86a6239c4bb5 100644
+index 4e9612600822bc1b52b8528dff2783d43385ec73..315dfaf65994fd071c5434a78a8a8d91ea508cc8 100644
--- a/src/test/java/org/bukkit/support/AbstractTestingBase.java
+++ b/src/test/java/org/bukkit/support/AbstractTestingBase.java
-@@ -74,6 +74,6 @@ public abstract class AbstractTestingBase {
+@@ -79,6 +79,6 @@ public abstract class AbstractTestingBase {
}
}
INVALIDATED_MATERIALS = builder.build();