diff --git a/README.md b/README.md index 55cc0d5..c93c794 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@

✨ SparklyPaper ✨

+![Minecraft Version](https://badgen.now.sh/badge/minecraft%20version/1.20.4/blue) ![Blazing Fast](https://badgen.now.sh/badge/speed/blazing%20%F0%9F%94%A5/green) + 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. Our fork has handmade patches to add and optimize some of the things that we have in our server, with some cherry-picked patches from other forks. diff --git a/build.gradle.kts b/build.gradle.kts index 3f12bd1..744c3f1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { id("com.github.johnrengelman.shadow") version "8.1.1" apply false // In general, keep this version in sync with upstream. Sometimes a newer version than upstream might work, but an older version is extremely likely to break. - id("io.papermc.paperweight.patcher") version "1.5.7" + id("io.papermc.paperweight.patcher") version "1.5.11" } val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/" @@ -19,7 +19,7 @@ repositories { } dependencies { - remapper("net.fabricmc:tiny-remapper:0.8.6:fat") // Must be kept in sync with upstream + remapper("net.fabricmc:tiny-remapper:0.8.10:fat") // Must be kept in sync with upstream decompiler("net.minecraftforge:forgeflower:2.0.627.2") // 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 cbc79ba..3b5785e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,8 +1,8 @@ group=net.sparklypower.sparklypaper -version=1.20.2-R0.1-SNAPSHOT +version=1.20.4-R0.1-SNAPSHOT -mcVersion=1.20.2 -paperRef=ffa41152390b121b919454b64f99097f356b25bf +mcVersion=1.20.4 +paperRef=b42a1da8737895f4fcacfae9b4d49a96b1445972 org.gradle.caching=true org.gradle.parallel=true 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 5fb6dfe..ececaaf 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 79beac737c17412913983614bd478d33e3c6ed58..5812c7056d11be2cc966728de6b07cd903e8d320 100644 +index 170a915098f09ace226648da342a04c5c7583d11..5c2c47b6e01c65ade4da9df65e8a799fb2654989 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,6 +3,8 @@ import io.papermc.paperweight.util.* @@ -17,16 +17,16 @@ index 79beac737c17412913983614bd478d33e3c6ed58..5812c7056d11be2cc966728de6b07cd9 id("com.github.johnrengelman.shadow") } -@@ -13,8 +15,15 @@ configurations.named(log4jPlugins.compileClasspathConfigurationName) { - val alsoShade: Configuration by configurations.creating +@@ -27,8 +29,15 @@ repositories { dependencies { + extraRuntime(platform("net.kyori:adventure-bom:4.15.0-SNAPSHOT")) - implementation(project(":paper-api")) - implementation(project(":paper-mojangapi")) + // SparklyPaper start + implementation(project(":sparklypaper-api")) + implementation(kotlin("reflect")) -+ implementation("io.papermc.paper:paper-mojangapi:1.20.2-R0.1-SNAPSHOT") { ++ implementation("io.papermc.paper:paper-mojangapi:1.20.4-R0.1-SNAPSHOT") { + exclude("io.papermc.paper", "paper-api") + } + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0") @@ -35,7 +35,7 @@ index 79beac737c17412913983614bd478d33e3c6ed58..5812c7056d11be2cc966728de6b07cd9 // Paper start implementation("org.jline:jline-terminal-jansi:3.21.0") implementation("net.minecrell:terminalconsoleappender:1.3.0") -@@ -64,13 +73,18 @@ tasks.jar { +@@ -78,13 +87,18 @@ tasks.jar { manifest { val git = Git(rootProject.layout.projectDirectory.path) val gitHash = git("rev-parse", "--short=7", "HEAD").getText().trim() @@ -56,7 +56,7 @@ index 79beac737c17412913983614bd478d33e3c6ed58..5812c7056d11be2cc966728de6b07cd9 "Implementation-Vendor" to date, // Paper "Specification-Title" to "Bukkit", "Specification-Version" to project.version, -@@ -154,7 +168,7 @@ fun TaskContainer.registerRunTask( +@@ -168,7 +182,7 @@ fun TaskContainer.registerRunTask( name: String, block: JavaExec.() -> Unit ): TaskProvider = register(name) { @@ -66,10 +66,10 @@ index 79beac737c17412913983614bd478d33e3c6ed58..5812c7056d11be2cc966728de6b07cd9 standardInput = System.`in` workingDir = rootProject.layout.projectDirectory diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 8f31413c939cc2b0454ad3d9a1b618dbae449d00..25367df06a8a6e8b0b3a56652a5fb1c70a15632d 100644 +index 34f19ac897a30c0c4e3ab406013fcca1c8b7db93..f1c65967b74e79452870438eea0942cc700fe0e9 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1697,7 +1697,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 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 - Async-Anti-Xray - Pass executor this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper @@ -116,10 +116,10 @@ index 0000000000000000000000000000000000000000..bc0ec96f91f7c9ab9f9a865a50f69707 + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 73e373c04986582d8841ec896a4ee9565eee2e95..d03563baf1e9e25fce8bab1f9fe3f2e57358590b 100644 +index e81a3a5e9aab6cb0c76d9e557a31d94536680ce4..ec838fa5248743ccd96f2c19b25b17d9a2ace3d0 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -117,6 +117,7 @@ import net.minecraft.world.level.storage.WorldData; +@@ -118,6 +118,7 @@ import net.minecraft.world.level.storage.PrimaryLevelData; import net.minecraft.world.level.storage.loot.LootDataManager; import net.minecraft.world.level.validation.ContentValidationException; import net.minecraft.world.phys.Vec3; @@ -127,7 +127,7 @@ index 73e373c04986582d8841ec896a4ee9565eee2e95..d03563baf1e9e25fce8bab1f9fe3f2e5 import org.bukkit.BanList; import org.bukkit.Bukkit; import org.bukkit.ChatColor; -@@ -1041,6 +1042,7 @@ public final class CraftServer implements Server { +@@ -1036,6 +1037,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 73e373c04986582d8841ec896a4ee9565eee2e95..d03563baf1e9e25fce8bab1f9fe3f2e5 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)) -@@ -1056,6 +1058,7 @@ public final class CraftServer implements Server { +@@ -1051,6 +1053,7 @@ public final class CraftServer implements Server { } } world.spigotConfig.init(); // Spigot @@ -143,7 +143,7 @@ index 73e373c04986582d8841ec896a4ee9565eee2e95..d03563baf1e9e25fce8bab1f9fe3f2e5 } Plugin[] pluginClone = pluginManager.getPlugins().clone(); // Paper -@@ -1071,6 +1074,7 @@ public final class CraftServer implements Server { +@@ -1066,6 +1069,7 @@ public final class CraftServer implements Server { this.reloadData(); org.spigotmc.SpigotConfig.registerCommands(); // Spigot io.papermc.paper.command.PaperCommands.registerCommands(this.console); // Paper @@ -152,7 +152,7 @@ index 73e373c04986582d8841ec896a4ee9565eee2e95..d03563baf1e9e25fce8bab1f9fe3f2e5 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 c737c5d62407337d3db2899cfc01713a058a6467..5e3033fe176d161ed5a18a73bae752d6689a3e01 100644 +index 4b457cbfc56e55e0ae0fee5b69e2e75349702aab..2791bd21e570c6bbcb3be19fac4a520a810f952d 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -174,6 +174,14 @@ public class Main { diff --git a/patches/server/0003-Optimize-entity-coordinate-key.patch b/patches/server/0003-Optimize-entity-coordinate-key.patch index db89a48..7176a94 100644 --- a/patches/server/0003-Optimize-entity-coordinate-key.patch +++ b/patches/server/0003-Optimize-entity-coordinate-key.patch @@ -11,7 +11,7 @@ data is already available in the blockPosition struct, so we use that instead of re-doing the casting. diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java -index d02546b18cb689724887b4e85e8d32a18828a4ad..91eaff58bb422ba188e6cfaa9c20b45bec211edd 100644 +index 8240bb085b619f257f8c0a25775e0b15068e440f..6d9668d993bb922ae9d2b76a4d766903cc3f98a4 100644 --- a/src/main/java/io/papermc/paper/util/MCUtil.java +++ b/src/main/java/io/papermc/paper/util/MCUtil.java @@ -213,7 +213,7 @@ public final class MCUtil { @@ -24,10 +24,10 @@ index d02546b18cb689724887b4e85e8d32a18828a4ad..91eaff58bb422ba188e6cfaa9c20b45b public static long getCoordinateKey(final ChunkPos pair) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index d435d04ab50b2f64e6438c6c26639b6048322013..9906cde792a07a433e45613518e741801026077d 100644 +index 9abe817ae202edaa2d88cd59ae5c7db0b1c634be..cfb4daaa28263aef1c74eac574b4f0e8b2f87776 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -306,7 +306,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -307,7 +307,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S public double yo; public double zo; private Vec3 position; diff --git a/patches/server/0004-Rewrite-framed-map-tracker-ticking.patch b/patches/server/0004-Rewrite-framed-map-tracker-ticking.patch index 5638000..bac861f 100644 --- a/patches/server/0004-Rewrite-framed-map-tracker-ticking.patch +++ b/patches/server/0004-Rewrite-framed-map-tracker-ticking.patch @@ -83,10 +83,10 @@ index 35674f92a67f93382103c2766df4b678ba5c862f..bfdd0ce9acfae75a403d3689b391dd8f private void sendDirtyEntityData() { 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 759ecd79534a7706f7d4a63eb9dacbefcfe54674..0780dd4abf035cdd4001fb9702494c54be83361a 100644 +index 69912c5b300b67394dce3876d2d96872033cf156..bde22dcbc67211a62c2280b0c6cf5b85aa3b96eb 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java -@@ -488,6 +488,16 @@ public class ItemFrame extends HangingEntity { +@@ -483,6 +483,16 @@ public class ItemFrame extends HangingEntity { } this.setItem(ItemStack.fromBukkitCopy(event.getItemStack())); // Paper end @@ -104,7 +104,7 @@ index 759ecd79534a7706f7d4a63eb9dacbefcfe54674..0780dd4abf035cdd4001fb9702494c54 if (!player.getAbilities().instabuild) { itemstack.shrink(1); 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 e4c4948e076cd64686dfd16ae0568fafc1437140..0e7c7593eec47bc266f53ee8b2053917a84ae61e 100644 +index e4c4948e076cd64686dfd16ae0568fafc1437140..fec7d474df8cfc8c36f5a69faac7ad03ad648d45 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 @@ -67,6 +67,16 @@ public class MapItemSavedData extends SavedData { diff --git a/patches/server/0006-Skip-MapItem-update-if-the-map-does-not-have-the-Cra.patch b/patches/server/0006-Skip-MapItem-update-if-the-map-does-not-have-the-Cra.patch index 4760d5c..b2a7801 100644 --- a/patches/server/0006-Skip-MapItem-update-if-the-map-does-not-have-the-Cra.patch +++ b/patches/server/0006-Skip-MapItem-update-if-the-map-does-not-have-the-Cra.patch @@ -9,10 +9,10 @@ Optimizes "image in map" maps, without requiring the map to be locked, which som This has the disadvantage that the vanilla map data will never be updated while the CraftMapRenderer is not present, but that's not a huuuge problem for us diff --git a/src/main/java/net/minecraft/world/item/MapItem.java b/src/main/java/net/minecraft/world/item/MapItem.java -index c368b437597edf7e165326727ae778a69c3fcc83..190716ea7857c7ad5427a527ad8d6b5a241a00b6 100644 +index 797415866a7f182d804f6b8e57ceb07a6ac2a20a..fc824f471e5d814cb3eee48516731c2b001fb54e 100644 --- a/src/main/java/net/minecraft/world/item/MapItem.java +++ b/src/main/java/net/minecraft/world/item/MapItem.java -@@ -332,7 +332,7 @@ public class MapItem extends ComplexItem { +@@ -324,7 +324,7 @@ public class MapItem extends ComplexItem { worldmap.tickCarriedBy(entityhuman, stack); } diff --git a/patches/server/0009-Skip-EntityScheduler-s-executeTick-checks-if-there-i.patch b/patches/server/0009-Skip-EntityScheduler-s-executeTick-checks-if-there-i.patch index f9062e5..775a413 100644 --- a/patches/server/0009-Skip-EntityScheduler-s-executeTick-checks-if-there-i.patch +++ b/patches/server/0009-Skip-EntityScheduler-s-executeTick-checks-if-there-i.patch @@ -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 25367df06a8a6e8b0b3a56652a5fb1c70a15632d..d83b2f3c03c2e22a3e7c97dc4e4b156d1b321738 100644 +index f1c65967b74e79452870438eea0942cc700fe0e9..4820e5ae050966d89a0d0b587c83537d4a1e1393 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -308,6 +308,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); -@@ -1471,6 +1472,18 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { for (final Entity entity : level.getEntityLookup().getAllCopy()) { if (entity.isRemoved()) { -@@ -1482,6 +1495,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0 && world.paperConfig().tickRates.wetFarmland != 1 && (world.paperConfig().tickRates.wetFarmland < 1 || (net.minecraft.server.MinecraftServer.currentTick + pos.hashCode()) % world.paperConfig().tickRates.wetFarmland != 0)) { return; } // Paper if (i == 0 && world.paperConfig().tickRates.dryFarmland != 1 && (world.paperConfig().tickRates.dryFarmland < 1 || (net.minecraft.server.MinecraftServer.currentTick + pos.hashCode()) % world.paperConfig().tickRates.dryFarmland != 0)) { return; } // Paper -@@ -143,7 +156,7 @@ public class FarmBlock extends Block { +@@ -150,7 +163,7 @@ public class FarmBlock extends Block { return world.getBlockState(pos.above()).is(BlockTags.MAINTAINS_FARMLAND); } @@ -109,10 +109,10 @@ index 502dcba14da9d3dcefc61fdc349a4e1e1d94b478..fc8d56f02e8b22261cf2f205b39dfa1a int xOff = pos.getX(); int yOff = pos.getY(); diff --git a/src/main/java/net/minecraft/world/level/block/StemBlock.java b/src/main/java/net/minecraft/world/level/block/StemBlock.java -index 0d9be3b28ba4957c3f4da5455283fca903836c91..d20af373521636a0fb42712effd09619b9c78960 100644 +index 121a872cd750a87b779895687ae1abf5bb77b088..a5d1931dc80febe74601d7a8f2d975c702b357aa 100644 --- a/src/main/java/net/minecraft/world/level/block/StemBlock.java +++ b/src/main/java/net/minecraft/world/level/block/StemBlock.java -@@ -51,6 +51,50 @@ public class StemBlock extends BushBlock implements BonemealableBlock { +@@ -73,6 +73,56 @@ public class StemBlock extends BushBlock implements BonemealableBlock { @Override public void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { if (world.getRawBrightness(pos, 0) >= 9) { @@ -144,18 +144,24 @@ index 0d9be3b28ba4957c3f4da5455283fca903836c91..d20af373521636a0fb42712effd09619 + BlockState iblockdata1 = world.getBlockState(blockposition1.below()); + + if (world.getBlockState(blockposition1).isAir() && (iblockdata1.is(Blocks.FARMLAND) || iblockdata1.is(BlockTags.DIRT))) { -+ // CraftBukkit start -+ if (!CraftEventFactory.handleBlockGrowEvent(world, blockposition1, this.fruit.defaultBlockState())) { -+ return; ++ Registry iregistry = world.registryAccess().registryOrThrow(Registries.BLOCK); ++ Optional optional = iregistry.getOptional(this.fruit); ++ Optional optional1 = iregistry.getOptional(this.attachedStem); ++ ++ if (optional.isPresent() && optional1.isPresent()) { ++ // CraftBukkit start ++ if (!CraftEventFactory.handleBlockGrowEvent(world, blockposition1, ((Block) optional.get()).defaultBlockState())) { ++ return; ++ } ++ // CraftBukkit end ++ // Now that we know that the crop will grow... is the next stage the crop's max age? If yes, we are going to check if the farm land is moist! ++ if (isCurrentFarmlandStateMoist && !FarmBlock.isNearWater(world, farmlandBelowTheCurrentBlock)) { ++ // Whoops, farm land ain't moist! ++ // From FarmBlock, set the moisture to 0 ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleMoistureChangeEvent(world, farmlandBelowTheCurrentBlock, (BlockState) farmlandBelowTheCurrentBlockData.setValue(FarmBlock.MOISTURE, 0), 2); // CraftBukkit ++ } ++ world.setBlockAndUpdate(pos, (BlockState) ((Block) optional1.get()).defaultBlockState().setValue(HorizontalDirectionalBlock.FACING, enumdirection)); + } -+ // CraftBukkit end -+ // Now that we know that the crop will grow... is the next stage the crop's max age? If yes, we are going to check if the farm land is moist! -+ if (isCurrentFarmlandStateMoist && !FarmBlock.isNearWater(world, farmlandBelowTheCurrentBlock)) { -+ // Whoops, farm land ain't moist! -+ // From FarmBlock, set the moisture to 0 -+ org.bukkit.craftbukkit.event.CraftEventFactory.handleMoistureChangeEvent(world, farmlandBelowTheCurrentBlock, (BlockState) farmlandBelowTheCurrentBlockData.setValue(FarmBlock.MOISTURE, 0), 2); // CraftBukkit -+ } -+ world.setBlockAndUpdate(pos, (BlockState) this.fruit.getAttachedStem().defaultBlockState().setValue(HorizontalDirectionalBlock.FACING, enumdirection)); + } + } + } @@ -163,7 +169,7 @@ index 0d9be3b28ba4957c3f4da5455283fca903836c91..d20af373521636a0fb42712effd09619 float f = CropBlock.getGrowthSpeed(this, world, pos); if (random.nextFloat() < ((this == Blocks.PUMPKIN_STEM ? world.spigotConfig.pumpkinModifier : world.spigotConfig.melonModifier) / (100.0f * (Math.floor((25.0F / f) + 1))))) { // Spigot - SPIGOT-7159: Better modifier resolution -@@ -74,7 +118,8 @@ public class StemBlock extends BushBlock implements BonemealableBlock { +@@ -102,7 +152,8 @@ public class StemBlock extends BushBlock implements BonemealableBlock { } } } diff --git a/patches/server/0011-Spooky-month-optimizations.patch b/patches/server/0011-Spooky-month-optimizations.patch index 01ad112..1fd6cf4 100644 --- a/patches/server/0011-Spooky-month-optimizations.patch +++ b/patches/server/0011-Spooky-month-optimizations.patch @@ -10,10 +10,10 @@ Caches when Bat's spooky season starts and ends, and when Skeleton and Zombies h Avoids unnecessary date checks, even tho that this shouldn't really improve performance that much... unless you have a lot of bats/zombies/skeletons spawning. diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index d83b2f3c03c2e22a3e7c97dc4e4b156d1b321738..cebda87d198edc844f5629a5cd4c71cd6dd75caf 100644 +index 4820e5ae050966d89a0d0b587c83537d4a1e1393..f43060555bf02f13268b284606045fce2b3e911a 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -309,6 +309,7 @@ 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,7 +22,7 @@ index d83b2f3c03c2e22a3e7c97dc4e4b156d1b321738..cebda87d198edc844f5629a5cd4c71cd public static S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index 9a6915a87ae8aa4ffefea575d7a7d5199c800799..7f90783254d4178e02baf6b5b0a60508a4ce2806 100644 +index b69860955a6c1efb68b17e1fc9b0c42771f40e15..734fd1ced38a16649177bb941e76d9ca66dceac5 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java @@ -227,6 +227,10 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface @@ -37,10 +37,10 @@ index 9a6915a87ae8aa4ffefea575d7a7d5199c800799..7f90783254d4178e02baf6b5b0a60508 io.papermc.paper.brigadier.PaperBrigadierProviderImpl.INSTANCE.getClass(); // init PaperBrigadierProvider // Paper end diff --git a/src/main/java/net/minecraft/world/entity/ambient/Bat.java b/src/main/java/net/minecraft/world/entity/ambient/Bat.java -index 5beaa849a250ea005733250ad3edfa8382224667..02060f41c17dd22f27bdbf930ab7580984c5c841 100644 +index 6b614818b14ecfc8fc82b523eeb7e21fdf9bf1ba..2588e7eb1f55d3f01f4f8d794a59f3ba16f5985a 100644 --- a/src/main/java/net/minecraft/world/entity/ambient/Bat.java +++ b/src/main/java/net/minecraft/world/entity/ambient/Bat.java -@@ -227,7 +227,7 @@ public class Bat extends AmbientCreature { +@@ -231,7 +231,7 @@ public class Bat extends AmbientCreature { int i = world.getMaxLocalRawBrightness(pos); byte b0 = 4; @@ -49,7 +49,7 @@ index 5beaa849a250ea005733250ad3edfa8382224667..02060f41c17dd22f27bdbf930ab75809 b0 = 7; } else if (random.nextBoolean()) { return false; -@@ -237,6 +237,8 @@ public class Bat extends AmbientCreature { +@@ -241,6 +241,8 @@ public class Bat extends AmbientCreature { } } @@ -58,7 +58,7 @@ index 5beaa849a250ea005733250ad3edfa8382224667..02060f41c17dd22f27bdbf930ab75809 private static boolean isHalloween() { LocalDate localdate = LocalDate.now(); int i = localdate.get(ChronoField.DAY_OF_MONTH); -@@ -244,6 +246,7 @@ public class Bat extends AmbientCreature { +@@ -248,6 +250,7 @@ public class Bat extends AmbientCreature { return j == 10 && i >= 20 || j == 11 && i <= 3; } @@ -87,7 +87,7 @@ index b319021b22c5dceba6199ed27814b2dcf47b8d50..4e7f19215bafc8ff6b06abc08076a154 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 5fdad1600cc7a7c22d1d9a58b6b2dda605521b97..852be41caa3434c898ef2b0731e6f864e817c02b 100644 +index 753defa8f8b48d004a2a53b2fc322fd9c083d95e..cc7073efaa9984c95b125878df94556b1e865c7a 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java @@ -553,10 +553,11 @@ public class Zombie extends Monster { 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 index 80f3bcb..33e9a20 100644 --- 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 @@ -30,18 +30,18 @@ index 17ba07cbd4792f63d88ce29d00da280f30c4abff..8e8aad958c96fa1df3d906ec120a89ad 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 8c33a12ca879c46893150d6adfb8aa4d397c6b4c..66d9358c30b827a1299e9d9b0d3793a0eb62d67b 100644 +index 6e212f672579a3e08dc362c287be59ca5170d717..a9763733a0026f7785349dcdd845a01f50a022b1 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -621,7 +621,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -647,7 +647,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); + // 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; - } + 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 f7e5e016a7028a9196e689e950805b0d5b31fe38..d0285843920f78e05ce07b1b0b2d8ce97ec8041e 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java diff --git a/patches/server/0013-Optimize-canSee-checks.patch b/patches/server/0013-Optimize-canSee-checks.patch index 284e212..99f67ed 100644 --- a/patches/server/0013-Optimize-canSee-checks.patch +++ b/patches/server/0013-Optimize-canSee-checks.patch @@ -27,10 +27,10 @@ index caa73632aee15583c6b6ed12a668c8f49b794708..fa4c8a52a57775ef8f23e48e57b76ff7 } // 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 3a792ddc31e76038b84e8f87088c4cd94c349138..e1fb00bd5f4a2849026c6c9c50423810a494f925 100644 +index fd84786f3e72875e79df46416f47f3403876cef3..a26150660b70442444d7dbcb5cae4ccab19838d5 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -183,7 +183,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -184,7 +184,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 3a792ddc31e76038b84e8f87088c4cd94c349138..e1fb00bd5f4a2849026c6c9c50423810 private final Set unlistedEntities = new HashSet<>(); // Paper private static final WeakHashMap> pluginWeakReferences = new WeakHashMap<>(); private int hash = 0; -@@ -2086,9 +2086,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2094,9 +2094,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public boolean canSee(org.bukkit.entity.Entity entity) { diff --git a/patches/server/0014-Revert-Fix-MC-117075-TE-Unload-Lag-Spike.patch b/patches/server/0014-Revert-Fix-MC-117075-TE-Unload-Lag-Spike.patch index 598573b..226c463 100644 --- a/patches/server/0014-Revert-Fix-MC-117075-TE-Unload-Lag-Spike.patch +++ b/patches/server/0014-Revert-Fix-MC-117075-TE-Unload-Lag-Spike.patch @@ -6,19 +6,19 @@ Subject: [PATCH] Revert "Fix MC-117075: TE Unload Lag Spike" This reverts commit 188c1c5b77133f7c3da9c67a97432d79d50d2b34. diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index b9e0822638a3979bd43392efdb595153e6f34675..ddb618fce875b1a337b139c9c47433453654017b 100644 +index f5e3c87581cbdc762806ad4412b68d3c84612b88..0740a7e90c8b7947448990cd9e76328d7d4a7e95 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -1270,8 +1270,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - // Spigot start - // Iterator iterator = this.blockEntityTickers.iterator(); +@@ -1281,8 +1281,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + boolean flag = this.tickRateManager().runsNormally(); + int tilesThisCycle = 0; -- var toRemove = new it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet(net.minecraft.Util.identityStrategy()); // Paper - use removeAll +- var toRemove = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet(); // Paper - use removeAll - toRemove.add(null); 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); -@@ -1279,6 +1277,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1290,6 +1288,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { if (tickingblockentity == null) { this.getCraftServer().getLogger().severe("Spigot has detected a null entity and has removed it, preventing a crash"); tilesThisCycle--; @@ -26,16 +26,16 @@ index b9e0822638a3979bd43392efdb595153e6f34675..ddb618fce875b1a337b139c9c4743345 continue; } // Spigot end -@@ -1286,7 +1285,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1297,7 +1296,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { if (tickingblockentity.isRemoved()) { // Spigot start tilesThisCycle--; - toRemove.add(tickingblockentity); // Paper - use removeAll + this.blockEntityTickers.remove(this.tileTickPosition--); // Spigot end - } else if (this.shouldTickBlocksAt(tickingblockentity.getPos())) { + } else if (flag && this.shouldTickBlocksAt(tickingblockentity.getPos())) { tickingblockentity.tick(); -@@ -1297,7 +1296,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1308,7 +1307,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // Paper end - execute chunk tasks during tick } } diff --git a/patches/server/0015-Fix-MC-117075-TE-Unload-Lag-Spike.patch b/patches/server/0015-Fix-MC-117075-TE-Unload-Lag-Spike.patch index 363d965..be07198 100644 --- a/patches/server/0015-Fix-MC-117075-TE-Unload-Lag-Spike.patch +++ b/patches/server/0015-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 ddb618fce875b1a337b139c9c47433453654017b..f50a66841fd8c798cd881612be302c292afcfa65 100644 +index 0740a7e90c8b7947448990cd9e76328d7d4a7e95..d9acec6352adf9e7d774cf3ea9486e57fc02ff83 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -117,7 +117,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -120,7 +120,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { 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 ddb618fce875b1a337b139c9c47433453654017b..f50a66841fd8c798cd881612be302c29 protected final NeighborUpdater neighborUpdater; private final List pendingBlockEntityTickers = Lists.newArrayList(); private boolean tickingBlockEntities; -@@ -1277,7 +1277,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1288,7 +1288,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { if (tickingblockentity == null) { this.getCraftServer().getLogger().severe("Spigot has detected a null entity and has removed it, preventing a crash"); tilesThisCycle--; @@ -29,16 +29,16 @@ index ddb618fce875b1a337b139c9c47433453654017b..f50a66841fd8c798cd881612be302c29 continue; } // Spigot end -@@ -1285,7 +1285,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1296,7 +1296,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { if (tickingblockentity.isRemoved()) { // Spigot start tilesThisCycle--; - this.blockEntityTickers.remove(this.tileTickPosition--); + this.blockEntityTickers.markAsRemoved(this.tileTickPosition); // this.blockEntityTickers.remove(this.tileTickPosition--); // SparklyPaper - optimize block entity removals // Spigot end - } else if (this.shouldTickBlocksAt(tickingblockentity.getPos())) { + } else if (flag && this.shouldTickBlocksAt(tickingblockentity.getPos())) { tickingblockentity.tick(); -@@ -1296,7 +1296,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1307,7 +1307,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { // Paper end - execute chunk tasks during tick } } diff --git a/patches/server/0016-Optimize-tickBlockEntities.patch b/patches/server/0016-Optimize-tickBlockEntities.patch index fa49e67..4897402 100644 --- a/patches/server/0016-Optimize-tickBlockEntities.patch +++ b/patches/server/0016-Optimize-tickBlockEntities.patch @@ -12,12 +12,12 @@ 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 f50a66841fd8c798cd881612be302c292afcfa65..6048e9ed03b633eb545a82a506e5033c61d8176f 100644 +index d9acec6352adf9e7d774cf3ea9486e57fc02ff83..4c0aa4b4c79562d43df9fc07a56731056f6a2348 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -1270,6 +1270,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - // Spigot start - // Iterator iterator = this.blockEntityTickers.iterator(); +@@ -1281,6 +1281,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable { + boolean flag = this.tickRateManager().runsNormally(); + int tilesThisCycle = 0; + // SparklyPaper start - optimize tickBlockEntities + int shouldTickBlocksAtLastResult = -1; // -1 = undefined @@ -26,13 +26,13 @@ index f50a66841fd8c798cd881612be302c292afcfa65..6048e9ed03b633eb545a82a506e5033c 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); -@@ -1287,13 +1291,25 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1298,13 +1302,25 @@ public abstract class Level implements LevelAccessor, AutoCloseable { tilesThisCycle--; this.blockEntityTickers.markAsRemoved(this.tileTickPosition); // this.blockEntityTickers.remove(this.tileTickPosition--); // SparklyPaper - optimize block entity removals // Spigot end -- } else if (this.shouldTickBlocksAt(tickingblockentity.getPos())) { -+ // } else if (this.shouldTickBlocksAt(tickingblockentity.getPos())) { // SparklyPaper start - optimize tickBlockEntities -+ } else { +- } else if (flag && this.shouldTickBlocksAt(tickingblockentity.getPos())) { ++ // } else if (flag && this.shouldTickBlocksAt(tickingblockentity.getPos())) { // SparklyPaper start - optimize tickBlockEntities ++ } else if (flag) { + long chunkPos = tickingblockentity.getChunkCoordinateKey(); + boolean shouldTick; + if (shouldTickBlocksAtChunkPos == chunkPos && shouldTickBlocksAtLastResult != -1) { diff --git a/patches/server/0017-Track-how-much-MSPT-each-world-used.patch b/patches/server/0017-Track-how-much-MSPT-each-world-used.patch index 1058337..b43ca6d 100644 --- a/patches/server/0017-Track-how-much-MSPT-each-world-used.patch +++ b/patches/server/0017-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 cebda87d198edc844f5629a5cd4c71cd6dd75caf..53284b2b0d0a2546e8c045a960a1db9b8d06e3f7 100644 +index f43060555bf02f13268b284606045fce2b3e911a..f34a9d3a255ee72e2c467376bd1f7bc2a1309443 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1561,7 +1561,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0) { @@ -494,7 +494,7 @@ index a0c7c6208314d981e8577ad69ef1c5193290a085..5be8039092cd6a2a787fdfaf9d516a18 Location location = CraftLocation.toBukkit(blockposition, worldserver.getWorld()); List blocks = new java.util.ArrayList<>(worldserver.capturedBlockStates.values()); worldserver.capturedBlockStates.clear(); -@@ -884,7 +884,7 @@ public interface DispenseItemBehavior { +@@ -888,7 +888,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)); @@ -503,7 +503,7 @@ index a0c7c6208314d981e8577ad69ef1c5193290a085..5be8039092cd6a2a787fdfaf9d516a18 worldserver.getCraftServer().getPluginManager().callEvent(event); } -@@ -941,7 +941,7 @@ public interface DispenseItemBehavior { +@@ -945,7 +945,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())); @@ -512,7 +512,7 @@ index a0c7c6208314d981e8577ad69ef1c5193290a085..5be8039092cd6a2a787fdfaf9d516a18 worldserver.getCraftServer().getPluginManager().callEvent(event); } -@@ -990,7 +990,7 @@ public interface DispenseItemBehavior { +@@ -996,7 +996,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())); @@ -521,7 +521,7 @@ index a0c7c6208314d981e8577ad69ef1c5193290a085..5be8039092cd6a2a787fdfaf9d516a18 worldserver.getCraftServer().getPluginManager().callEvent(event); } -@@ -1063,7 +1063,7 @@ public interface DispenseItemBehavior { +@@ -1070,7 +1070,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())); @@ -557,18 +557,18 @@ index 6f2adf2334e35e8a617a4ced0c1af2abf32bbd8d..a5ea9df0a021ed820c0c1ccb612caebd } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 53284b2b0d0a2546e8c045a960a1db9b8d06e3f7..a29af1d5005ce1a52693ce9acc6686e0a537fd7d 100644 +index f34a9d3a255ee72e2c467376bd1f7bc2a1309443..cbb830d36c5ad753a650667f7fd178fca83d49fb 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -160,6 +160,7 @@ import net.minecraft.world.level.storage.PrimaryLevelData; - import net.minecraft.world.level.storage.ServerLevelData; +@@ -152,6 +152,7 @@ import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; + import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager; import net.minecraft.world.level.storage.WorldData; import net.minecraft.world.level.storage.loot.LootDataManager; +import org.bukkit.craftbukkit.event.CraftEventFactory; import org.slf4j.Logger; // CraftBukkit start -@@ -310,6 +311,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 @@ -578,7 +578,7 @@ index 53284b2b0d0a2546e8c045a960a1db9b8d06e3f7..a29af1d5005ce1a52693ce9acc6686e0 public static S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); -@@ -1539,63 +1543,124 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { return this.getChunk(x, z, leastStatus, create); }, this.mainThreadProcessor).join(); -@@ -317,7 +326,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -315,7 +324,7 @@ public class ServerChunkCache extends ChunkSource { @Nullable @Override public LevelChunk getChunkNow(int chunkX, int chunkZ) { @@ -822,7 +822,7 @@ index 66d9358c30b827a1299e9d9b0d3793a0eb62d67b..33504d860c8ac8397863cee401b2718c return null; } else { return this.getChunkAtIfLoadedMainThread(chunkX, chunkZ); // Paper - optimise for loaded chunks -@@ -331,7 +340,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -329,7 +338,7 @@ public class ServerChunkCache extends ChunkSource { } public CompletableFuture> getChunkFuture(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) { @@ -831,20 +831,20 @@ index 66d9358c30b827a1299e9d9b0d3793a0eb62d67b..33504d860c8ac8397863cee401b2718c CompletableFuture completablefuture; if (flag1) { -@@ -650,7 +659,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -677,7 +686,7 @@ public class ServerChunkCache extends ChunkSource { - if (true || this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) { // Paper - optimise chunk tick iteration - this.level.tickChunk(chunk1, k); -- 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 + 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 3721a45fbc38d6fc92cc8ba5080c7bd18b8d006c..add727490a4513342914e94a57e4674310777b5a 100644 +index 094a6ddebf79aa49b3e3cd8a032db7b8d23607c4..e640ad5dd3f1caab04a8a99f967ef20b9c30c79e 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -216,6 +216,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -218,6 +218,7 @@ public class ServerLevel extends Level implements WorldGenLevel { private final boolean tickTime; private final RandomSequences randomSequences; public long lastMidTickExecuteFailure; // Paper - execute chunk tasks mid tick @@ -852,7 +852,7 @@ index 3721a45fbc38d6fc92cc8ba5080c7bd18b8d006c..add727490a4513342914e94a57e46743 // CraftBukkit start public final LevelStorageSource.LevelStorageAccess convertable; -@@ -703,7 +704,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -705,7 +706,7 @@ public class ServerLevel extends Level implements WorldGenLevel { this.uuid = WorldUUID.getUUID(convertable_conversionsession.levelDirectory.path().toFile()); // CraftBukkit end this.players = Lists.newArrayList(); @@ -861,7 +861,7 @@ index 3721a45fbc38d6fc92cc8ba5080c7bd18b8d006c..add727490a4513342914e94a57e46743 this.blockTicks = new LevelTicks<>(this::isPositionTickingWithEntitiesLoaded, this.getProfilerSupplier()); this.fluidTicks = new LevelTicks<>(this::isPositionTickingWithEntitiesLoaded, this.getProfilerSupplier()); this.navigatingMobs = new ObjectOpenHashSet(); -@@ -774,6 +775,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -776,6 +777,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 @@ -869,7 +869,7 @@ index 3721a45fbc38d6fc92cc8ba5080c7bd18b8d006c..add727490a4513342914e94a57e46743 } // Paper start -@@ -1329,7 +1331,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1353,7 +1355,7 @@ public class ServerLevel extends Level implements WorldGenLevel { if (fluid1.is(fluid)) { fluid1.tick(this, pos); } @@ -878,7 +878,7 @@ index 3721a45fbc38d6fc92cc8ba5080c7bd18b8d006c..add727490a4513342914e94a57e46743 } -@@ -1339,7 +1341,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1363,7 +1365,7 @@ public class ServerLevel extends Level implements WorldGenLevel { if (iblockdata.is(block)) { iblockdata.tick(this, pos, this.random); } @@ -887,7 +887,7 @@ index 3721a45fbc38d6fc92cc8ba5080c7bd18b8d006c..add727490a4513342914e94a57e46743 } -@@ -1357,7 +1359,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1381,7 +1383,7 @@ public class ServerLevel extends Level implements WorldGenLevel { public void tickNonPassenger(Entity entity) { // Paper start - log detailed entity tick information @@ -896,7 +896,7 @@ index 3721a45fbc38d6fc92cc8ba5080c7bd18b8d006c..add727490a4513342914e94a57e46743 try { if (currentlyTickingEntity.get() == null) { currentlyTickingEntity.lazySet(entity); -@@ -1645,6 +1647,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1669,6 +1671,7 @@ public class ServerLevel extends Level implements WorldGenLevel { } private void addPlayer(ServerPlayer player) { @@ -904,7 +904,7 @@ index 3721a45fbc38d6fc92cc8ba5080c7bd18b8d006c..add727490a4513342914e94a57e46743 Entity entity = (Entity) this.getEntities().get(player.getUUID()); if (entity != null) { -@@ -1658,7 +1661,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1682,7 +1685,7 @@ public class ServerLevel extends Level implements WorldGenLevel { // CraftBukkit start private boolean addEntity(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) { @@ -913,7 +913,7 @@ index 3721a45fbc38d6fc92cc8ba5080c7bd18b8d006c..add727490a4513342914e94a57e46743 // Paper start if (entity.valid) { MinecraftServer.LOGGER.error("Attempted Double World add on " + entity, new Throwable()); -@@ -2632,6 +2635,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2667,6 +2670,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @Override public void close() throws IOException { super.close(); @@ -922,12 +922,12 @@ index 3721a45fbc38d6fc92cc8ba5080c7bd18b8d006c..add727490a4513342914e94a57e46743 } diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 08980763020a13ab49dc7d637625a4fba56da8c9..8a0cae8acd552c8d8ab7dea9da08b8c5d855bb62 100644 +index 8efbbd379244e3ed54d4aba199037cc20ccd096a..131192d2eb8d0b3224b9c76f43e842861888ea09 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -18,6 +18,7 @@ import java.util.Optional; - import java.util.OptionalInt; +@@ -17,6 +17,7 @@ import java.util.OptionalInt; import java.util.Set; + import java.util.stream.Collectors; import javax.annotation.Nullable; + import net.minecraft.BlockUtil; @@ -941,9 +941,9 @@ index 08980763020a13ab49dc7d637625a4fba56da8c9..8a0cae8acd552c8d8ab7dea9da08b8c5 import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.Entity; -@@ -114,12 +114,7 @@ import net.minecraft.world.entity.player.Inventory; - import net.minecraft.world.entity.player.Player; - import net.minecraft.world.entity.projectile.AbstractArrow; +@@ -118,12 +118,7 @@ import net.minecraft.world.entity.projectile.AbstractArrow; + import net.minecraft.world.entity.vehicle.AbstractMinecart; + import net.minecraft.world.entity.vehicle.Boat; import net.minecraft.world.food.FoodData; -import net.minecraft.world.inventory.AbstractContainerMenu; -import net.minecraft.world.inventory.ContainerListener; @@ -955,7 +955,7 @@ index 08980763020a13ab49dc7d637625a4fba56da8c9..8a0cae8acd552c8d8ab7dea9da08b8c5 import net.minecraft.world.item.ComplexItem; import net.minecraft.world.item.ItemCooldowns; import net.minecraft.world.item.ItemStack; -@@ -321,6 +316,7 @@ public class ServerPlayer extends Player { +@@ -328,6 +323,7 @@ public class ServerPlayer extends Player { // Paper start - optimise chunk tick iteration public double lastEntitySpawnRadiusSquared = -1.0; // Paper end - optimise chunk tick iteration @@ -963,7 +963,7 @@ index 08980763020a13ab49dc7d637625a4fba56da8c9..8a0cae8acd552c8d8ab7dea9da08b8c5 public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ClientInformation clientOptions) { super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile); -@@ -710,6 +706,7 @@ public class ServerPlayer extends Player { +@@ -717,6 +713,7 @@ public class ServerPlayer extends Player { @Override public void tick() { @@ -971,7 +971,7 @@ index 08980763020a13ab49dc7d637625a4fba56da8c9..8a0cae8acd552c8d8ab7dea9da08b8c5 // CraftBukkit start if (this.joining) { this.joining = false; -@@ -728,6 +725,7 @@ public class ServerPlayer extends Player { +@@ -735,6 +732,7 @@ public class ServerPlayer extends Player { containerUpdateDelay = this.level().paperConfig().tickRates.containerUpdate; } // Paper end @@ -979,7 +979,7 @@ index 08980763020a13ab49dc7d637625a4fba56da8c9..8a0cae8acd552c8d8ab7dea9da08b8c5 if (!this.level().isClientSide && this.containerMenu != this.inventoryMenu && (this.isImmobile() || !this.containerMenu.stillValid(this))) { // Paper - auto close while frozen this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); // Paper this.containerMenu = this.inventoryMenu; -@@ -1182,6 +1180,7 @@ public class ServerPlayer extends Player { +@@ -1184,6 +1182,7 @@ public class ServerPlayer extends Player { ResourceKey resourcekey = worldserver1.getTypeKey(); // CraftBukkit if (resourcekey == LevelStem.END && worldserver != null && worldserver.getTypeKey() == LevelStem.OVERWORLD) { // CraftBukkit @@ -987,7 +987,7 @@ index 08980763020a13ab49dc7d637625a4fba56da8c9..8a0cae8acd552c8d8ab7dea9da08b8c5 this.isChangingDimension = true; // CraftBukkit - Moved down from above this.unRide(); this.serverLevel().removePlayerImmediately(this, Entity.RemovalReason.CHANGED_DIMENSION); -@@ -1194,6 +1193,10 @@ public class ServerPlayer extends Player { +@@ -1196,6 +1195,10 @@ public class ServerPlayer extends Player { return this; } else { @@ -998,7 +998,7 @@ index 08980763020a13ab49dc7d637625a4fba56da8c9..8a0cae8acd552c8d8ab7dea9da08b8c5 // CraftBukkit start /* WorldData worlddata = worldserver.getLevelData(); -@@ -1594,6 +1597,12 @@ public class ServerPlayer extends Player { +@@ -1604,6 +1607,12 @@ public class ServerPlayer extends Player { return OptionalInt.empty(); } else { // CraftBukkit start @@ -1011,7 +1011,7 @@ index 08980763020a13ab49dc7d637625a4fba56da8c9..8a0cae8acd552c8d8ab7dea9da08b8c5 this.containerMenu = container; if (!this.isImmobile()) this.connection.send(new ClientboundOpenScreenPacket(container.containerId, container.getType(), Objects.requireNonNullElseGet(title, container::getTitle))); // Paper // CraftBukkit end -@@ -1655,6 +1664,11 @@ public class ServerPlayer extends Player { +@@ -1665,6 +1674,11 @@ public class ServerPlayer extends Player { } @Override public void closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) { @@ -1024,10 +1024,10 @@ index 08980763020a13ab49dc7d637625a4fba56da8c9..8a0cae8acd552c8d8ab7dea9da08b8c5 // Paper end 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 33abcf12b4426572b74ca4c813e4392c823494bc..07198f2f8f7cb082c9e575a5c1e56c14aca31a87 100644 +index a35638a92479b90afa89cf201fc45b49c9e767f3..b842dc3d286a98d40267bac141749c4aaf3f082d 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -111,7 +111,6 @@ import org.bukkit.Location; +@@ -109,7 +109,6 @@ import org.bukkit.Location; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.entity.CraftPlayer; @@ -1035,7 +1035,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..07198f2f8f7cb082c9e575a5c1e56c14 import org.bukkit.craftbukkit.util.CraftLocation; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerChangedWorldEvent; -@@ -120,7 +119,6 @@ import org.bukkit.event.player.PlayerLoginEvent; +@@ -118,7 +117,6 @@ import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerRespawnEvent; import org.bukkit.event.player.PlayerRespawnEvent.RespawnReason; @@ -1043,7 +1043,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..07198f2f8f7cb082c9e575a5c1e56c14 // CraftBukkit end public abstract class PlayerList { -@@ -136,7 +134,7 @@ public abstract class PlayerList { +@@ -134,7 +132,7 @@ public abstract class PlayerList { private static final SimpleDateFormat BAN_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z"); private final MinecraftServer server; public final List players = new java.util.concurrent.CopyOnWriteArrayList(); // CraftBukkit - ArrayList -> CopyOnWriteArrayList: Iterator safety @@ -1052,7 +1052,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..07198f2f8f7cb082c9e575a5c1e56c14 private final UserBanList bans; private final IpBanList ipBans; private final ServerOpList ops; -@@ -157,7 +155,7 @@ public abstract class PlayerList { +@@ -155,7 +153,7 @@ public abstract class PlayerList { // CraftBukkit start private CraftServer cserver; @@ -1061,7 +1061,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..07198f2f8f7cb082c9e575a5c1e56c14 public @Nullable String collideRuleTeamName; // Paper - Team name used for collideRule public PlayerList(MinecraftServer server, LayeredRegistryAccess registryManager, PlayerDataStorage saveHandler, int maxPlayers) { -@@ -181,6 +179,7 @@ public abstract class PlayerList { +@@ -179,6 +177,7 @@ public abstract class PlayerList { abstract public void loadAndSaveFiles(); // Paper - moved from DedicatedPlayerList constructor public void placeNewPlayer(Connection connection, ServerPlayer player, CommonListenerCookie clientData) { @@ -1069,7 +1069,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..07198f2f8f7cb082c9e575a5c1e56c14 player.isRealPlayer = true; // Paper player.loginTime = System.currentTimeMillis(); // Paper GameProfile gameprofile = player.getGameProfile(); -@@ -820,6 +819,8 @@ public abstract class PlayerList { +@@ -818,6 +817,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) { @@ -1078,7 +1078,7 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..07198f2f8f7cb082c9e575a5c1e56c14 // Paper end entityplayer.stopRiding(); // CraftBukkit this.players.remove(entityplayer); -@@ -844,6 +845,7 @@ public abstract class PlayerList { +@@ -842,6 +843,7 @@ public abstract class PlayerList { ServerPlayer entityplayer1 = entityplayer; org.bukkit.World fromWorld = entityplayer.getBukkitEntity().getWorld(); entityplayer.wonGame = false; @@ -1087,10 +1087,10 @@ index 33abcf12b4426572b74ca4c813e4392c823494bc..07198f2f8f7cb082c9e575a5c1e56c14 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 e544081e8214802facb77defc1e9aa765834be2a..f979d22f5bf83492133a87119686a4e136923bc0 100644 +index cfb4daaa28263aef1c74eac574b4f0e8b2f87776..7393add59bade50479843353ef9492de8e47548f 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -934,11 +934,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -939,11 +939,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S // This will be called every single tick the entity is in lava, so don't throw an event this.setSecondsOnFire(15, false); } @@ -1104,7 +1104,7 @@ index e544081e8214802facb77defc1e9aa765834be2a..f979d22f5bf83492133a87119686a4e1 // CraftBukkit end - we also don't throw an event unless the object in lava is living, to save on some event calls } -@@ -3390,9 +3390,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3445,9 +3445,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S if (this.fireImmune()) { return; } @@ -1116,7 +1116,7 @@ index e544081e8214802facb77defc1e9aa765834be2a..f979d22f5bf83492133a87119686a4e1 return; } // CraftBukkit end -@@ -3903,6 +3903,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3963,6 +3963,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S this.teleportPassengers(); this.setYHeadRot(yaw); } else { @@ -1125,10 +1125,10 @@ index e544081e8214802facb77defc1e9aa765834be2a..f979d22f5bf83492133a87119686a4e1 Entity entity = this.getType().create(world); diff --git a/src/main/java/net/minecraft/world/entity/animal/Turtle.java b/src/main/java/net/minecraft/world/entity/animal/Turtle.java -index 490472bb618e9ac07da5883a71dff8920525b1e2..73e4d849d151ec3adec80a96c1e6efbe35b5044a 100644 +index d8056421249c8e75e96a55ec07dce84d2bba9c5c..b7150ab57334ca4dcecb7ce5510cd19e5ca2e087 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java +++ b/src/main/java/net/minecraft/world/entity/animal/Turtle.java -@@ -341,9 +341,9 @@ public class Turtle extends Animal { +@@ -336,9 +336,9 @@ public class Turtle extends Animal { @Override public void thunderHit(ServerLevel world, LightningBolt lightning) { @@ -1141,7 +1141,7 @@ index 490472bb618e9ac07da5883a71dff8920525b1e2..73e4d849d151ec3adec80a96c1e6efbe @Override diff --git a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java -index e6f75a9cac46c8e3ddba664a9d5b27b665a94cb4..07df7ce695452409b4ac132d8fb72bed2415b08e 100644 +index 45c07733f03b5c11f6d8e820f65dc950c70d9a67..60b9219778472e489192ca3259b4649a254187eb 100644 --- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java @@ -295,9 +295,9 @@ public class FallingBlockEntity extends Entity { @@ -1200,45 +1200,11 @@ index b2f08889139dc447f7071f1c81456035bf8de31e..f816f197df8f36c83d5fe5b6d677da91 } } } -diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -index a90317100d32974e481e14476843f66997a2cf3a..981a73abdef08bf4a2de274abbccff35415f3a95 100644 ---- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -+++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -@@ -78,16 +78,19 @@ public abstract class Projectile extends Entity implements TraceableEntity { - } else if (this.ownerUUID != null && this.level() instanceof ServerLevel) { - this.cachedOwner = ((ServerLevel) this.level()).getEntity(this.ownerUUID); - // Paper start - check all worlds -- if (this.cachedOwner == null) { -- for (final ServerLevel level : this.level().getServer().getAllLevels()) { -- if (level == this.level()) continue; -- final Entity entity = level.getEntity(this.ownerUUID); -- if (entity != null) { -- this.cachedOwner = entity; -- break; -- } -- } -- } -+ // SparklyPaper start - parallel world ticking -+ // This is from the "MC-50319: Check other worlds for shooter of projectiles" patch, however, accessing the entities in other worlds will cause concurrency issues -+ // if (this.cachedOwner == null) { -+ // for (final ServerLevel level : this.level().getServer().getAllLevels()) { -+ // if (level == this.level()) continue; -+ // final Entity entity = level.getEntity(this.ownerUUID); -+ // if (entity != null) { -+ // this.cachedOwner = entity; -+ // break; -+ // } -+ // } -+ // } -+ // SparklyPaper end - // Paper end - this.refreshProjectileSource(false); // Paper - return this.cachedOwner; diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java -index f5db60cbecbe69941873e064315931089fe0e48a..6c4a1de4f2606439348dbdb620a1aff63b848028 100644 +index af4da25c9b13c114179fab3254aea5323210d7da..92347924a1ccea98daee9c0fe2bb403d6b3aad22 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java -@@ -82,9 +82,9 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { +@@ -85,9 +85,9 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { entityplayer.connection.teleport(teleEvent.getTo()); entity.resetFallDistance(); @@ -1249,9 +1215,9 @@ index f5db60cbecbe69941873e064315931089fe0e48a..6c4a1de4f2606439348dbdb620a1aff6 + CraftEventFactory.entityDamageRT.set(null); // SparklyPaper - parallel world ticking } // CraftBukkit end - } + this.level().playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_TELEPORT, SoundSource.PLAYERS); diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java -index 82f18790b9dc55b039ae03600a80a46d56a87521..4d9e1085c3218cf8b8f84f607983a5fc6b1a2cec 100644 +index 8fd82051bba33b4703e4d99fff886b63a319a5ba..ffdea352e973858931bdd4c3f7e81d179f9edfdf 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 { @@ -1283,10 +1249,10 @@ index 42d87800a328f71c5127ce5599ca4c71cc9bb1cd..466526dfe8f81379bccf640f2c3a7064 } diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index 4697df75fdee2023c41260bed211e3e3d90d2b9b..618a0a4d479c73fd0ca7e9d770ea01deb10c004a 100644 +index de277d61b718fe07a87d75a2547bb1c7f8553aa1..d4499bc920ec8c8f59b39d0ed0ff58df5e6b089c 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -378,8 +378,8 @@ public final class ItemStack { +@@ -399,8 +399,8 @@ public final class ItemStack { if (enuminteractionresult.consumesAction() && world.captureTreeGeneration && world.capturedBlockStates.size() > 0) { world.captureTreeGeneration = false; Location location = CraftLocation.toBukkit(blockposition, world.getWorld()); @@ -1298,10 +1264,10 @@ index 4697df75fdee2023c41260bed211e3e3d90d2b9b..618a0a4d479c73fd0ca7e9d770ea01de world.capturedBlockStates.clear(); StructureGrowEvent structureEvent = null; diff --git a/src/main/java/net/minecraft/world/item/MinecartItem.java b/src/main/java/net/minecraft/world/item/MinecartItem.java -index a33395dc5a94d89b5ab273c7832813b6ff9ea3b7..31abddcd78672814de8d1e6289da67782675081a 100644 +index 3aa73cd44aa8c86b78c35bc1788e4f83018c49ed..eac9b4148d0951f7c54ce4ad8ab4d97eb5f74578 100644 --- a/src/main/java/net/minecraft/world/item/MinecartItem.java +++ b/src/main/java/net/minecraft/world/item/MinecartItem.java -@@ -69,7 +69,7 @@ public class MinecartItem extends Item { +@@ -70,7 +70,7 @@ public class MinecartItem extends Item { CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); BlockDispenseEvent event = new BlockDispenseEvent(block2, craftItem.clone(), new org.bukkit.util.Vector(d0, d1 + d3, d2)); @@ -1311,29 +1277,29 @@ index a33395dc5a94d89b5ab273c7832813b6ff9ea3b7..31abddcd78672814de8d1e6289da6778 } diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java -index 45243249a561440512ef2a620c60b02e159c80e2..849b9b4336d2ac99324dacf6ad8a2e34e7e65797 100644 +index 9442f58dff89ec843c321533965fbee2727d02f8..ab30f345381e32a1751adbd2344d8f3c473553ae 100644 --- a/src/main/java/net/minecraft/world/level/Explosion.java +++ b/src/main/java/net/minecraft/world/level/Explosion.java -@@ -566,7 +566,7 @@ public class Explosion { - continue; - } +@@ -584,7 +584,7 @@ public class Explosion { + continue; + } -- CraftEventFactory.entityDamage = this.source; -+ CraftEventFactory.entityDamageRT.set(this.source); // SparklyPaper - parallel world ticking - entity.lastDamageCancelled = false; +- CraftEventFactory.entityDamage = this.source; ++ CraftEventFactory.entityDamageRT.set(this.source); // SparklyPaper - parallel world ticking + entity.lastDamageCancelled = false; - if (entity instanceof EnderDragon) { -@@ -582,7 +582,7 @@ public class Explosion { - entity.hurt(this.getDamageSource(), (float) ((int) ((d13 * d13 + d13) / 2.0D * 7.0D * (double) f2 + 1.0D))); - } + if (entity instanceof EnderDragon) { +@@ -598,7 +598,7 @@ public class Explosion { + entity.hurt(this.damageSource, this.damageCalculator.getEntityDamageAmount(this, entity, getSeenFraction(vec3d, entity, blockCache, blockPos))); // Paper - actually optimise explosions + } -- CraftEventFactory.entityDamage = null; -+ CraftEventFactory.entityDamageRT.set(null); // SparklyPaper - parallel world ticking - if (entity.lastDamageCancelled) { // SPIGOT-5339, SPIGOT-6252, SPIGOT-6777: Skip entity if damage event was cancelled - continue; - } +- CraftEventFactory.entityDamage = null; ++ CraftEventFactory.entityDamageRT.set(null); // SparklyPaper - parallel world ticking + if (entity.lastDamageCancelled) { // SPIGOT-5339, SPIGOT-6252, SPIGOT-6777: Skip entity if damage event was cancelled + continue; + } diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 6048e9ed03b633eb545a82a506e5033c61d8176f..114e6cc9d2245f7362aa0c63dba890f38a0722ca 100644 +index 4c0aa4b4c79562d43df9fc07a56731056f6a2348..0398d5083ac776af5717ae4eab2a5481c2f93be8 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -15,6 +15,8 @@ import java.util.function.Consumer; @@ -1345,7 +1311,7 @@ index 6048e9ed03b633eb545a82a506e5033c61d8176f..114e6cc9d2245f7362aa0c63dba890f3 import net.minecraft.CrashReport; import net.minecraft.CrashReportCategory; import net.minecraft.ReportedException; -@@ -827,7 +829,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -830,7 +832,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public final LevelChunk getChunk(int chunkX, int chunkZ) { // Paper - final to help inline // Paper start - make sure loaded chunks get the inlined variant of this function net.minecraft.server.level.ServerChunkCache cps = ((ServerLevel)this).getChunkSource(); @@ -1354,7 +1320,7 @@ index 6048e9ed03b633eb545a82a506e5033c61d8176f..114e6cc9d2245f7362aa0c63dba890f3 LevelChunk ifLoaded = cps.getChunkAtIfLoadedMainThread(chunkX, chunkZ); if (ifLoaded != null) { return ifLoaded; -@@ -911,6 +913,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -914,6 +916,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @Override public boolean setBlock(BlockPos pos, BlockState state, int flags, int maxUpdateDepth) { @@ -1362,7 +1328,7 @@ index 6048e9ed03b633eb545a82a506e5033c61d8176f..114e6cc9d2245f7362aa0c63dba890f3 // CraftBukkit start - tree generation if (this.captureTreeGeneration) { // Paper start -@@ -1306,7 +1309,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1317,7 +1320,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { tickingblockentity.tick(); // Paper start - execute chunk tasks during tick if ((this.tileTickPosition & 7) == 0) { @@ -1371,7 +1337,7 @@ index 6048e9ed03b633eb545a82a506e5033c61d8176f..114e6cc9d2245f7362aa0c63dba890f3 } // Paper end - execute chunk tasks during tick } // SparklyPaper end -@@ -1323,7 +1326,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1334,7 +1337,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public void guardEntityTick(Consumer tickConsumer, T entity) { try { tickConsumer.accept(entity); @@ -1380,7 +1346,7 @@ index 6048e9ed03b633eb545a82a506e5033c61d8176f..114e6cc9d2245f7362aa0c63dba890f3 } catch (Throwable throwable) { if (throwable instanceof ThreadDeath) throw throwable; // Paper // Paper start - Prevent tile entity and entity crashes -@@ -1423,6 +1426,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1441,6 +1444,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @Nullable public BlockEntity getBlockEntity(BlockPos blockposition, boolean validate) { @@ -1388,7 +1354,7 @@ index 6048e9ed03b633eb545a82a506e5033c61d8176f..114e6cc9d2245f7362aa0c63dba890f3 // Paper start - Optimize capturedTileEntities lookup net.minecraft.world.level.block.entity.BlockEntity blockEntity; if (!this.capturedTileEntities.isEmpty() && (blockEntity = this.capturedTileEntities.get(blockposition)) != null) { -@@ -1430,10 +1434,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1448,10 +1452,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } // Paper end // CraftBukkit end @@ -1401,7 +1367,7 @@ index 6048e9ed03b633eb545a82a506e5033c61d8176f..114e6cc9d2245f7362aa0c63dba890f3 BlockPos blockposition = blockEntity.getBlockPos(); if (!this.isOutsideBuildHeight(blockposition)) { -@@ -1519,6 +1524,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1537,6 +1542,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @Override public List getEntities(@Nullable Entity except, AABB box, Predicate predicate) { @@ -1409,7 +1375,7 @@ index 6048e9ed03b633eb545a82a506e5033c61d8176f..114e6cc9d2245f7362aa0c63dba890f3 this.getProfiler().incrementCounter("getEntities"); List list = Lists.newArrayList(); ((ServerLevel)this).getEntityLookup().getEntities(except, box, list, predicate); // Paper - optimise this call -@@ -1783,8 +1789,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1803,8 +1809,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 @@ -1420,10 +1386,10 @@ index 6048e9ed03b633eb545a82a506e5033c61d8176f..114e6cc9d2245f7362aa0c63dba890f3 out.set(x + (i1 & 15), y + (i1 >> 16 & l), z + (i1 >> 8 & 15)); // Paper - change to setValues call return out; // Paper diff --git a/src/main/java/net/minecraft/world/level/block/CactusBlock.java b/src/main/java/net/minecraft/world/level/block/CactusBlock.java -index 0003fb51ae3a6575575e10b4c86719f3061e2577..0c5e0634852fd929f7f1c4373b0c7baebb07bc96 100644 +index a9629a102c4fa4e5720e63fcf4590e9231426c62..c86f4eaf1d130a2eee820e4831f0b2dd23dd2ac3 100644 --- a/src/main/java/net/minecraft/world/level/block/CactusBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CactusBlock.java -@@ -115,9 +115,9 @@ public class CactusBlock extends Block { +@@ -122,9 +122,9 @@ public class CactusBlock extends Block { @Override public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper @@ -1436,10 +1402,10 @@ index 0003fb51ae3a6575575e10b4c86719f3061e2577..0c5e0634852fd929f7f1c4373b0c7bae @Override diff --git a/src/main/java/net/minecraft/world/level/block/CampfireBlock.java b/src/main/java/net/minecraft/world/level/block/CampfireBlock.java -index 7700461b8cd0bde1bf6c0d5e4b73184bed1adc4e..e55dd626d3ead2655894ddb9a25a31b661810533 100644 +index 7302d07c6ff69608e75ac52fdb19f2ec1d105129..64890b15dcec19732c45e1f3f485ccd67cb00142 100644 --- a/src/main/java/net/minecraft/world/level/block/CampfireBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CampfireBlock.java -@@ -95,9 +95,9 @@ public class CampfireBlock extends BaseEntityBlock implements SimpleWaterloggedB +@@ -110,9 +110,9 @@ public class CampfireBlock extends BaseEntityBlock implements SimpleWaterloggedB public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper if ((Boolean) state.getValue(CampfireBlock.LIT) && entity instanceof LivingEntity && !EnchantmentHelper.hasFrostWalker((LivingEntity) entity)) { @@ -1452,10 +1418,10 @@ index 7700461b8cd0bde1bf6c0d5e4b73184bed1adc4e..e55dd626d3ead2655894ddb9a25a31b6 super.entityInside(state, world, pos, entity); 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 9b1e51c1d95da885c80c6d05000d83436b7bcfb4..720b86021fd94cb68440eafebab4ea5d6e380c5f 100644 +index 52e92ffd6bf5d3d721807a0b3a8e2d301951f934..2b86f1ef01e5119ccf951c22f9b2da137d3f6735 100644 --- a/src/main/java/net/minecraft/world/level/block/DispenserBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DispenserBlock.java -@@ -48,7 +48,8 @@ public class DispenserBlock extends BaseEntityBlock { +@@ -49,7 +49,8 @@ public class DispenserBlock extends BaseEntityBlock { object2objectopenhashmap.defaultReturnValue(new DefaultDispenseItemBehavior()); }); private static final int TRIGGER_DURATION = 4; @@ -1463,9 +1429,9 @@ index 9b1e51c1d95da885c80c6d05000d83436b7bcfb4..720b86021fd94cb68440eafebab4ea5d + // public static boolean eventFired = false; // CraftBukkit // SparklyPaper - parallel world ticking + public static ThreadLocal eventFired = ThreadLocal.withInitial(() -> Boolean.FALSE); // SparklyPaper - parallel world ticking - public static void registerBehavior(ItemLike provider, DispenseItemBehavior behavior) { - DispenserBlock.DISPENSER_REGISTRY.put(provider.asItem(), behavior); -@@ -99,7 +100,7 @@ public class DispenserBlock extends BaseEntityBlock { + @Override + public MapCodec codec() { +@@ -105,7 +106,7 @@ public class DispenserBlock extends BaseEntityBlock { if (idispensebehavior != DispenseItemBehavior.NOOP) { if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockPreDispenseEvent(world, pos, itemstack, i)) return; // Paper - BlockPreDispenseEvent is called here @@ -1475,10 +1441,10 @@ index 9b1e51c1d95da885c80c6d05000d83436b7bcfb4..720b86021fd94cb68440eafebab4ea5d } diff --git a/src/main/java/net/minecraft/world/level/block/FungusBlock.java b/src/main/java/net/minecraft/world/level/block/FungusBlock.java -index 17e9e2efc78cfe8577dbf4e1d6096543ad8b8ac4..0d56dff0ccb86bc62b7752489f4b5d3fa4f1b913 100644 +index 50d7235cf2ef036451db708c45a063d037051ae9..ff9b3d7cbf4ffcc81b4837da0c4eb0d54a52508b 100644 --- a/src/main/java/net/minecraft/world/level/block/FungusBlock.java +++ b/src/main/java/net/minecraft/world/level/block/FungusBlock.java -@@ -61,9 +61,9 @@ public class FungusBlock extends BushBlock implements BonemealableBlock { +@@ -76,9 +76,9 @@ public class FungusBlock extends BushBlock implements BonemealableBlock { this.getFeature(world).ifPresent((holder) -> { // CraftBukkit start if (this == Blocks.WARPED_FUNGUS) { @@ -1491,10 +1457,10 @@ index 17e9e2efc78cfe8577dbf4e1d6096543ad8b8ac4..0d56dff0ccb86bc62b7752489f4b5d3f // CraftBukkit end ((ConfiguredFeature) holder.value()).place(world, world.getChunkSource().getGenerator(), random, pos); diff --git a/src/main/java/net/minecraft/world/level/block/MagmaBlock.java b/src/main/java/net/minecraft/world/level/block/MagmaBlock.java -index 1b766045687e4dcded5cbcc50b746c55b9a34e22..50e3ee93ed989a9a16f6d652a825abad488bb0b0 100644 +index 10f5ffacc72a5e0116e2599ca83ee57a5b1ce0eb..9e52c7e4459318171163ffae5d1a6c3e66ed84b0 100644 --- a/src/main/java/net/minecraft/world/level/block/MagmaBlock.java +++ b/src/main/java/net/minecraft/world/level/block/MagmaBlock.java -@@ -23,9 +23,9 @@ public class MagmaBlock extends Block { +@@ -30,9 +30,9 @@ public class MagmaBlock extends Block { @Override public void stepOn(Level world, BlockPos pos, BlockState state, Entity entity) { if (!entity.isSteppingCarefully() && entity instanceof LivingEntity && !EnchantmentHelper.hasFrostWalker((LivingEntity) entity)) { @@ -1507,10 +1473,10 @@ index 1b766045687e4dcded5cbcc50b746c55b9a34e22..50e3ee93ed989a9a16f6d652a825abad super.stepOn(world, pos, state, entity); diff --git a/src/main/java/net/minecraft/world/level/block/MushroomBlock.java b/src/main/java/net/minecraft/world/level/block/MushroomBlock.java -index 302c5a6401facf192677b89cc0e9190bb35b1229..6d4f5383d30893803945803384d4fdd7e1d17a51 100644 +index 7368c76a01275223a7bd3df1d36e80a15f66edbb..46a266b5f0d347b095ea0d03b41c18ae25277b13 100644 --- a/src/main/java/net/minecraft/world/level/block/MushroomBlock.java +++ b/src/main/java/net/minecraft/world/level/block/MushroomBlock.java -@@ -93,7 +93,7 @@ public class MushroomBlock extends BushBlock implements BonemealableBlock { +@@ -105,7 +105,7 @@ public class MushroomBlock extends BushBlock implements BonemealableBlock { return false; } else { world.removeBlock(pos, false); @@ -1520,10 +1486,10 @@ index 302c5a6401facf192677b89cc0e9190bb35b1229..6d4f5383d30893803945803384d4fdd7 return true; } else { diff --git a/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java b/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java -index cd943997f11f5ea5c600fdc6db96043fb0fa713c..fdfdac600fab86822cb9d1196b43424ad3fcf92a 100644 +index bd22d3fdecbc992b11073a74d854b7d1b43c3f6a..f6a76279119847af45c517fe481782a79f51761e 100644 --- a/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java +++ b/src/main/java/net/minecraft/world/level/block/PointedDripstoneBlock.java -@@ -141,9 +141,9 @@ public class PointedDripstoneBlock extends Block implements Fallable, SimpleWate +@@ -150,9 +150,9 @@ public class PointedDripstoneBlock extends Block implements Fallable, SimpleWate @Override public void fallOn(Level world, BlockState state, BlockPos pos, Entity entity, float fallDistance) { if (state.getValue(PointedDripstoneBlock.TIP_DIRECTION) == Direction.UP && state.getValue(PointedDripstoneBlock.THICKNESS) == DripstoneThickness.TIP) { @@ -1536,19 +1502,19 @@ index cd943997f11f5ea5c600fdc6db96043fb0fa713c..fdfdac600fab86822cb9d1196b43424a super.fallOn(world, state, pos, entity, fallDistance); } diff --git a/src/main/java/net/minecraft/world/level/block/SaplingBlock.java b/src/main/java/net/minecraft/world/level/block/SaplingBlock.java -index 53ac4e618fec3fe384d8a106c521f3eace0b5b35..b29df252c1b039004f40a8cf9aefb8387f29d7e3 100644 +index 836c86104ed4f0d375330c9123af5d502efefa4d..8e88047053e18b2d1b56ae9e329659969b3dc08e 100644 --- a/src/main/java/net/minecraft/world/level/block/SaplingBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SaplingBlock.java -@@ -27,7 +27,7 @@ public class SaplingBlock extends BushBlock implements BonemealableBlock { +@@ -34,7 +34,7 @@ public class SaplingBlock extends BushBlock implements BonemealableBlock { protected static final float AABB_OFFSET = 6.0F; protected static final VoxelShape SHAPE = Block.box(2.0D, 0.0D, 2.0D, 14.0D, 12.0D, 14.0D); - private final AbstractTreeGrower treeGrower; + protected final TreeGrower treeGrower; - public static TreeType treeType; // CraftBukkit + public static final ThreadLocal treeTypeRT = new ThreadLocal<>(); // CraftBukkit // SparklyPaper - parallel world ticking (from Folia) - protected SaplingBlock(AbstractTreeGrower generator, BlockBehaviour.Properties settings) { - super(settings); -@@ -60,8 +60,8 @@ public class SaplingBlock extends BushBlock implements BonemealableBlock { + @Override + public MapCodec codec() { +@@ -72,8 +72,8 @@ public class SaplingBlock extends BushBlock implements BonemealableBlock { this.treeGrower.growTree(world, world.getChunkSource().getGenerator(), pos, state, random); world.captureTreeGeneration = false; if (world.capturedBlockStates.size() > 0) { @@ -1560,10 +1526,10 @@ index 53ac4e618fec3fe384d8a106c521f3eace0b5b35..b29df252c1b039004f40a8cf9aefb838 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/SweetBerryBushBlock.java b/src/main/java/net/minecraft/world/level/block/SweetBerryBushBlock.java -index 34eb7ba1adb51e394bf46a6f643db3529626d9ec..d48945137f717062e5233c10e978e5134edebf19 100644 +index f474ae7b3121de701f371b7d88e80086ec07d03d..3b7a14d76b0e24aa7747e3b37560db4c8a7370db 100644 --- a/src/main/java/net/minecraft/world/level/block/SweetBerryBushBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SweetBerryBushBlock.java -@@ -85,9 +85,9 @@ public class SweetBerryBushBlock extends BushBlock implements BonemealableBlock +@@ -92,9 +92,9 @@ public class SweetBerryBushBlock extends BushBlock implements BonemealableBlock double d1 = Math.abs(entity.getZ() - entity.zOld); if (d0 >= 0.003000000026077032D || d1 >= 0.003000000026077032D) { @@ -1626,13 +1592,13 @@ index 65112ec3a6ea1c27f032477720ae74395523012b..41ed21bbb7762e52cd800846f546277c } @Override -diff --git a/src/main/java/net/minecraft/world/level/block/grower/AbstractTreeGrower.java b/src/main/java/net/minecraft/world/level/block/grower/AbstractTreeGrower.java -index a743f36f2682a6b72ffa6644782fc081d1479eb7..85e7da9884f48989a62a789306b701a3dc1a3b0d 100644 ---- a/src/main/java/net/minecraft/world/level/block/grower/AbstractTreeGrower.java -+++ b/src/main/java/net/minecraft/world/level/block/grower/AbstractTreeGrower.java -@@ -75,51 +75,53 @@ public abstract class AbstractTreeGrower { +diff --git a/src/main/java/net/minecraft/world/level/block/grower/TreeGrower.java b/src/main/java/net/minecraft/world/level/block/grower/TreeGrower.java +index 8cb822fed0cda4268f288feae1079a3dc4dc103e..1bac955a0b734689cc66b1a61e58fcde4cc3f15b 100644 +--- a/src/main/java/net/minecraft/world/level/block/grower/TreeGrower.java ++++ b/src/main/java/net/minecraft/world/level/block/grower/TreeGrower.java +@@ -175,51 +175,53 @@ public final class TreeGrower { // CraftBukkit start - protected void setTreeType(Holder> holder) { + private void setTreeType(Holder> holder) { ResourceKey> worldgentreeabstract = holder.unwrapKey().get(); + TreeType treeType; // SparklyPaper - parallel world ticking if (worldgentreeabstract == TreeFeatures.OAK || worldgentreeabstract == TreeFeatures.OAK_BEES_005) { @@ -1704,7 +1670,7 @@ index a743f36f2682a6b72ffa6644782fc081d1479eb7..85e7da9884f48989a62a789306b701a3 + SaplingBlock.treeTypeRT.set(treeType); // SparklyPaper - parallel world ticking } // 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 1338f91a85f5db6ce78705a0c48bec8a449a6220..00af4b8db53a55d252a43a29c4939fea111d3f13 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -1761,10 +1727,10 @@ index 4cdfc433df67afcd455422e9baf56f167dd712ae..f52b3740bd48f8527a36d48a0454e7d6 // 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) diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index f19f2199cac5a7eb275f40cc23472416a40ec0da..08f481b413b426987444b8ed9ed89b7ccbb45751 100644 +index e1fad381b861471a17529c246bb8a4a9c7646420..7075cd07d93f0f70a96d0cc3d54bf5545666cf5e 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -428,7 +428,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -435,7 +435,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { } private boolean unloadChunk0(int x, int z, boolean save) { @@ -1773,7 +1739,7 @@ index f19f2199cac5a7eb275f40cc23472416a40ec0da..08f481b413b426987444b8ed9ed89b7c if (!this.isChunkLoaded(x, z)) { return true; } -@@ -443,7 +443,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -450,7 +450,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public boolean regenerateChunk(int x, int z) { @@ -1782,7 +1748,7 @@ index f19f2199cac5a7eb275f40cc23472416a40ec0da..08f481b413b426987444b8ed9ed89b7c warnUnsafeChunk("regenerating a faraway chunk", x, z); // Paper // Paper start - implement regenerateChunk method final ServerLevel serverLevel = this.world; -@@ -504,6 +504,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -511,6 +511,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public boolean refreshChunk(int x, int z) { @@ -1790,7 +1756,7 @@ index f19f2199cac5a7eb275f40cc23472416a40ec0da..08f481b413b426987444b8ed9ed89b7c ChunkHolder playerChunk = this.world.getChunkSource().chunkMap.getVisibleChunkIfPresent(ChunkPos.asLong(x, z)); if (playerChunk == null) return false; -@@ -539,7 +540,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -546,7 +547,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public boolean loadChunk(int x, int z, boolean generate) { @@ -1799,7 +1765,7 @@ index f19f2199cac5a7eb275f40cc23472416a40ec0da..08f481b413b426987444b8ed9ed89b7c warnUnsafeChunk("loading a faraway chunk", x, z); // Paper // Paper start - Optimize this method ChunkPos chunkPos = new ChunkPos(x, z); -@@ -802,6 +803,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -809,6 +810,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public boolean generateTree(Location loc, TreeType type, BlockChangeDelegate delegate) { @@ -1807,7 +1773,7 @@ index f19f2199cac5a7eb275f40cc23472416a40ec0da..08f481b413b426987444b8ed9ed89b7c this.world.captureTreeGeneration = true; this.world.captureBlockStates = true; boolean grownTree = this.generateTree(loc, type); -@@ -912,11 +914,13 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -919,11 +921,13 @@ 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) { @@ -1821,7 +1787,7 @@ index f19f2199cac5a7eb275f40cc23472416a40ec0da..08f481b413b426987444b8ed9ed89b7c 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 -@@ -986,6 +990,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -993,6 +997,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public int getHighestBlockYAt(int x, int z, org.bukkit.HeightMap heightMap) { @@ -1829,7 +1795,7 @@ index f19f2199cac5a7eb275f40cc23472416a40ec0da..08f481b413b426987444b8ed9ed89b7c 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); -@@ -1016,6 +1021,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1023,6 +1028,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); @@ -1837,7 +1803,7 @@ index f19f2199cac5a7eb275f40cc23472416a40ec0da..08f481b413b426987444b8ed9ed89b7c if (this.world.hasChunkAt(pos)) { net.minecraft.world.level.chunk.LevelChunk chunk = this.world.getChunkAt(pos); -@@ -2299,6 +2305,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2311,6 +2317,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void sendGameEvent(Entity sourceEntity, org.bukkit.GameEvent gameEvent, Vector position) { @@ -1845,7 +1811,7 @@ index f19f2199cac5a7eb275f40cc23472416a40ec0da..08f481b413b426987444b8ed9ed89b7c getHandle().gameEvent(sourceEntity != null ? ((CraftEntity) sourceEntity).getHandle(): null, net.minecraft.core.registries.BuiltInRegistries.GAME_EVENT.get(org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(gameEvent.getKey())), org.bukkit.craftbukkit.util.CraftVector.toBlockPos(position)); } // Paper end -@@ -2453,7 +2460,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2465,7 +2472,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 @@ -1855,10 +1821,10 @@ index f19f2199cac5a7eb275f40cc23472416a40ec0da..08f481b413b426987444b8ed9ed89b7c 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 bec8e6b62dba2bd0e4e85a7d1fb51287384f1290..f650163cab8c54b97a7dac7c79320dae733e3411 100644 +index e5506a7d074a9f89d41f4d5d7549a458779bef20..8481a7dfc04b9d663fec909207b744a647067d84 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -@@ -74,6 +74,11 @@ public class CraftBlock implements Block { +@@ -75,6 +75,11 @@ public class CraftBlock implements Block { } public net.minecraft.world.level.block.state.BlockState getNMS() { @@ -1870,7 +1836,7 @@ index bec8e6b62dba2bd0e4e85a7d1fb51287384f1290..f650163cab8c54b97a7dac7c79320dae return this.world.getBlockState(this.position); } -@@ -150,6 +155,11 @@ public class CraftBlock implements Block { +@@ -151,6 +156,11 @@ public class CraftBlock implements Block { } private void setData(final byte data, int flag) { @@ -1882,7 +1848,7 @@ index bec8e6b62dba2bd0e4e85a7d1fb51287384f1290..f650163cab8c54b97a7dac7c79320dae this.world.setBlock(this.position, CraftMagicNumbers.getBlock(this.getType(), data), flag); } -@@ -191,6 +201,12 @@ public class CraftBlock implements Block { +@@ -192,6 +202,12 @@ public class CraftBlock implements Block { } 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) { @@ -1895,7 +1861,7 @@ index bec8e6b62dba2bd0e4e85a7d1fb51287384f1290..f650163cab8c54b97a7dac7c79320dae // SPIGOT-611: need to do this to prevent glitchiness. Easier to handle this here (like /setblock) than to fix weirdness in tile entity cleanup if (old.hasBlockEntity() && blockData.getBlock() != old.getBlock()) { // SPIGOT-3725 remove old tile entity if block changes // SPIGOT-4612: faster - just clear tile -@@ -336,18 +352,33 @@ public class CraftBlock implements Block { +@@ -337,18 +353,33 @@ public class CraftBlock implements Block { @Override public Biome getBiome() { @@ -1929,7 +1895,7 @@ index bec8e6b62dba2bd0e4e85a7d1fb51287384f1290..f650163cab8c54b97a7dac7c79320dae this.getWorld().setBiome(this.getX(), this.getY(), this.getZ(), bio); } -@@ -395,6 +426,11 @@ public class CraftBlock implements Block { +@@ -396,6 +427,11 @@ public class CraftBlock implements Block { @Override public boolean isBlockFaceIndirectlyPowered(BlockFace face) { @@ -1941,7 +1907,7 @@ index bec8e6b62dba2bd0e4e85a7d1fb51287384f1290..f650163cab8c54b97a7dac7c79320dae int power = this.world.getMinecraftWorld().getSignal(this.position, CraftBlock.blockFaceToNotch(face)); Block relative = this.getRelative(face); -@@ -407,6 +443,11 @@ public class CraftBlock implements Block { +@@ -408,6 +444,11 @@ public class CraftBlock implements Block { @Override public int getBlockPower(BlockFace face) { @@ -1953,7 +1919,7 @@ index bec8e6b62dba2bd0e4e85a7d1fb51287384f1290..f650163cab8c54b97a7dac7c79320dae int power = 0; net.minecraft.world.level.Level world = this.world.getMinecraftWorld(); int x = this.getX(); -@@ -477,6 +518,11 @@ public class CraftBlock implements Block { +@@ -478,6 +519,11 @@ public class CraftBlock implements Block { @Override public boolean breakNaturally() { @@ -1965,7 +1931,7 @@ index bec8e6b62dba2bd0e4e85a7d1fb51287384f1290..f650163cab8c54b97a7dac7c79320dae return this.breakNaturally(null); } -@@ -536,6 +582,11 @@ public class CraftBlock implements Block { +@@ -537,6 +583,11 @@ public class CraftBlock implements Block { @Override public boolean applyBoneMeal(BlockFace face) { @@ -1977,7 +1943,7 @@ index bec8e6b62dba2bd0e4e85a7d1fb51287384f1290..f650163cab8c54b97a7dac7c79320dae Direction direction = CraftBlock.blockFaceToNotch(face); BlockFertilizeEvent event = null; ServerLevel world = this.getCraftWorld().getHandle(); -@@ -547,8 +598,8 @@ public class CraftBlock implements Block { +@@ -548,8 +599,8 @@ public class CraftBlock implements Block { world.captureTreeGeneration = false; if (world.capturedBlockStates.size() > 0) { @@ -1988,7 +1954,7 @@ index bec8e6b62dba2bd0e4e85a7d1fb51287384f1290..f650163cab8c54b97a7dac7c79320dae List blocks = new ArrayList<>(world.capturedBlockStates.values()); world.capturedBlockStates.clear(); StructureGrowEvent structureEvent = null; -@@ -637,6 +688,11 @@ public class CraftBlock implements Block { +@@ -638,6 +689,11 @@ public class CraftBlock implements Block { @Override public RayTraceResult rayTrace(Location start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode) { @@ -2000,7 +1966,7 @@ index bec8e6b62dba2bd0e4e85a7d1fb51287384f1290..f650163cab8c54b97a7dac7c79320dae Preconditions.checkArgument(start != null, "Location start cannot be null"); Preconditions.checkArgument(this.getWorld().equals(start.getWorld()), "Location start cannot be a different world"); start.checkFinite(); -@@ -678,6 +734,11 @@ public class CraftBlock implements Block { +@@ -679,6 +735,11 @@ public class CraftBlock implements Block { @Override public boolean canPlace(BlockData data) { @@ -2012,7 +1978,7 @@ index bec8e6b62dba2bd0e4e85a7d1fb51287384f1290..f650163cab8c54b97a7dac7c79320dae Preconditions.checkArgument(data != null, "BlockData cannot be null"); net.minecraft.world.level.block.state.BlockState iblockdata = ((CraftBlockData) data).getState(); net.minecraft.world.level.Level world = this.world.getMinecraftWorld(); -@@ -712,6 +773,11 @@ public class CraftBlock implements Block { +@@ -713,6 +774,11 @@ public class CraftBlock implements Block { @Override public void tick() { @@ -2074,10 +2040,10 @@ index 390e1b7fd2721b99cb3ce268c6bc1bf0a38e08a3..9255e51954bd9a43afc366d8c414dd8a // Modelled off EntityHuman#hasBlock diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java -index e3b07d623cd64de9645f2372f1e08757edc1a9ed..72e72d4c1e77d2940d65bc65253b3a84c47c38a7 100644 +index 9271ff2a9ea05569e3c81886399aa7ab47efb05d..e5891ed14f688413dfe9ebd2b5af6d4b82f43f68 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java -@@ -239,8 +239,8 @@ public final class CraftBlockStates { +@@ -243,8 +243,8 @@ public final class CraftBlockStates { net.minecraft.world.level.block.state.BlockState blockData = craftBlock.getNMS(); BlockEntity tileEntity = craftBlock.getHandle().getBlockEntity(blockPosition); // Paper start - block state snapshots @@ -2088,7 +2054,7 @@ index e3b07d623cd64de9645f2372f1e08757edc1a9ed..72e72d4c1e77d2940d65bc65253b3a84 try { // Paper end CraftBlockState blockState = CraftBlockStates.getBlockState(world, blockPosition, blockData, tileEntity); -@@ -248,7 +248,7 @@ public final class CraftBlockStates { +@@ -252,7 +252,7 @@ public final class CraftBlockStates { return blockState; // Paper start } finally { @@ -2098,7 +2064,7 @@ index e3b07d623cd64de9645f2372f1e08757edc1a9ed..72e72d4c1e77d2940d65bc65253b3a84 // 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 5dc160b743534665c6b3efb10b10f7c36e2da5ab..8942bb585e1f4a0b747194ef2ad91acc5de82d8b 100644 +index e0f80414e01852b6f48c173dc2343ec928147e2f..7a2151cd5ae0848009e0ea19cf00a518032f3d7f 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -246,8 +246,8 @@ import org.bukkit.potion.PotionEffect; @@ -2130,7 +2096,7 @@ index 5dc160b743534665c6b3efb10b10f7c36e2da5ab..8942bb585e1f4a0b747194ef2ad91acc Bukkit.getPluginManager().callEvent(event); if (!event.isCancelled()) { -@@ -1047,8 +1047,8 @@ public class CraftEventFactory { +@@ -1057,8 +1057,8 @@ public class CraftEventFactory { private static EntityDamageEvent handleEntityDamageEvent(Entity entity, DamageSource source, Map modifiers, Map> modifierFunctions, boolean cancelled) { if (source.is(DamageTypeTags.IS_EXPLOSION)) { DamageCause damageCause; @@ -2141,7 +2107,7 @@ index 5dc160b743534665c6b3efb10b10f7c36e2da5ab..8942bb585e1f4a0b747194ef2ad91acc EntityDamageEvent event; if (damager == null) { event = new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.BLOCK_EXPLOSION, modifiers, modifierFunctions, source.explodedBlockState); // Paper - handle block state in damage -@@ -1109,13 +1109,13 @@ public class CraftEventFactory { +@@ -1119,13 +1119,13 @@ public class CraftEventFactory { } return event; } else if (source.is(DamageTypes.LAVA)) { @@ -2159,7 +2125,7 @@ index 5dc160b743534665c6b3efb10b10f7c36e2da5ab..8942bb585e1f4a0b747194ef2ad91acc if (!event.isCancelled()) { event.getEntity().setLastDamageCause(event); -@@ -1123,9 +1123,9 @@ public class CraftEventFactory { +@@ -1133,9 +1133,9 @@ public class CraftEventFactory { entity.lastDamageCancelled = true; // SPIGOT-5339, SPIGOT-6252, SPIGOT-6777: Keep track if the event was canceled } return event; @@ -2171,7 +2137,7 @@ index 5dc160b743534665c6b3efb10b10f7c36e2da5ab..8942bb585e1f4a0b747194ef2ad91acc if (source.is(DamageTypes.CACTUS) || source.is(DamageTypes.SWEET_BERRY_BUSH) || source.is(DamageTypes.STALAGMITE) || source.is(DamageTypes.FALLING_STALACTITE) || source.is(DamageTypes.FALLING_ANVIL)) { cause = DamageCause.CONTACT; } else if (source.is(DamageTypes.HOT_FLOOR)) { -@@ -1140,9 +1140,9 @@ public class CraftEventFactory { +@@ -1150,9 +1150,9 @@ public class CraftEventFactory { EntityDamageEvent event = new EntityDamageByBlockEvent(damager, entity.getBukkitEntity(), cause, modifiers, modifierFunctions); event.setCancelled(cancelled); @@ -2183,7 +2149,7 @@ index 5dc160b743534665c6b3efb10b10f7c36e2da5ab..8942bb585e1f4a0b747194ef2ad91acc if (!event.isCancelled()) { event.getEntity().setLastDamageCause(event); -@@ -1150,10 +1150,10 @@ public class CraftEventFactory { +@@ -1160,10 +1160,10 @@ public class CraftEventFactory { entity.lastDamageCancelled = true; // SPIGOT-5339, SPIGOT-6252, SPIGOT-6777: Keep track if the event was canceled } return event; @@ -2197,7 +2163,7 @@ index 5dc160b743534665c6b3efb10b10f7c36e2da5ab..8942bb585e1f4a0b747194ef2ad91acc if (source.is(DamageTypes.FALLING_STALACTITE) || source.is(DamageTypes.FALLING_BLOCK) || source.is(DamageTypes.FALLING_ANVIL)) { cause = DamageCause.FALLING_BLOCK; } else if (damager instanceof LightningStrike) { -@@ -2123,7 +2123,7 @@ public class CraftEventFactory { +@@ -2132,7 +2132,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(), new org.bukkit.util.Vector(to.getX(), to.getY(), to.getZ()));