From 27a8d6da9a74a6b6b26568ba768538f16fa5f584 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Sun, 13 Jun 2021 12:29:58 -0700 Subject: [PATCH] more patches --- ...184-Expose-the-internal-current-tick.patch | 4 +- ...layerDeathEvent-shouldDropExperience.patch | 2 +- ...-Add-effect-to-block-break-naturally.patch | 2 +- .../0187-World-view-distance-api.patch} | 2 +- ...ce-improvement-for-Chunk.getEntities.patch | 2 + .../0378-Generator-Settings.patch | 89 --- ...nk-loads-when-villagers-try-to-find-.patch | 20 - ...rializing-mismatching-chunk-coordina.patch | 62 --- patches/server/0338-Generator-Settings.patch | 165 ++++++ .../0339-Fix-MC-161754.patch} | 10 +- ...anging-entities-that-are-not-ItemFr.patch} | 6 +- ...41-Expose-the-internal-current-tick.patch} | 4 +- ...sneak-when-changing-worlds-MC-10657.patch} | 10 +- ...-option-to-disable-pillager-patrols.patch} | 7 +- ...r-when-player-hand-set-to-empty-typ.patch} | 16 +- ...nk-loads-when-villagers-try-to-find-.patch | 20 + ...656-Fix-Follow-Range-Initial-Target.patch} | 38 +- .../0347-Optimize-Hoppers.patch} | 373 +++++-------- ...ayerDeathEvent-shouldDropExperience.patch} | 6 +- ...ading-chunks-checking-hive-position.patch} | 4 +- ...hunks-from-Hoppers-and-other-things.patch} | 22 +- ...rializing-mismatching-chunk-coordina.patch | 54 ++ ...imise-IEntityAccess-getPlayerByUUID.patch} | 28 +- ...353-Fix-items-not-falling-correctly.patch} | 8 +- .../0354-Lag-compensate-eating.patch} | 46 +- ...ize-call-to-getFluid-for-explosions.patch} | 8 +- ...-in-stack-not-having-effects-when-d.patch} | 4 +- ...Add-effect-to-block-break-naturally.patch} | 8 +- .../0358-Entity-Activation-Range-2.0.patch} | 514 +++++++----------- .../0359-Increase-Light-Queue-Size.patch} | 13 +- .../0360-Fix-Light-Command.patch} | 97 ++-- ...o-Tick-view-distance-implementation.patch} | 349 ++++-------- 32 files changed, 825 insertions(+), 1168 deletions(-) rename patches/{api-unmapped => api}/0184-Expose-the-internal-current-tick.patch (87%) rename patches/{api-unmapped => api}/0185-PlayerDeathEvent-shouldDropExperience.patch (97%) rename patches/{api-unmapped => api}/0186-Add-effect-to-block-break-naturally.patch (91%) rename patches/{api-unmapped/0201-World-view-distance-api.patch => api/0187-World-view-distance-api.patch} (94%) rename patches/{server-remapped => removed/1.17}/0380-Performance-improvement-for-Chunk.getEntities.patch (96%) delete mode 100644 patches/server-remapped/0378-Generator-Settings.patch delete mode 100644 patches/server-remapped/0388-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch delete mode 100644 patches/server-remapped/0394-Guard-against-serializing-mismatching-chunk-coordina.patch create mode 100644 patches/server/0338-Generator-Settings.patch rename patches/{server-remapped/0379-Fix-MC-161754.patch => server/0339-Fix-MC-161754.patch} (54%) rename patches/{server-remapped/0381-Fix-spawning-of-hanging-entities-that-are-not-ItemFr.patch => server/0340-Fix-spawning-of-hanging-entities-that-are-not-ItemFr.patch} (85%) rename patches/{server-remapped/0382-Expose-the-internal-current-tick.patch => server/0341-Expose-the-internal-current-tick.patch} (81%) rename patches/{server-remapped/0383-Fix-stuck-in-sneak-when-changing-worlds-MC-10657.patch => server/0342-Fix-stuck-in-sneak-when-changing-worlds-MC-10657.patch} (78%) rename patches/{server-remapped/0384-Add-option-to-disable-pillager-patrols.patch => server/0343-Add-option-to-disable-pillager-patrols.patch} (86%) rename patches/{server-remapped/0385-Fix-AssertionError-when-player-hand-set-to-empty-typ.patch => server/0344-Fix-AssertionError-when-player-hand-set-to-empty-typ.patch} (52%) create mode 100644 patches/server/0345-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch rename patches/{server-remapped/0389-MC-145656-Fix-Follow-Range-Initial-Target.patch => server/0346-MC-145656-Fix-Follow-Range-Initial-Target.patch} (62%) rename patches/{server-remapped/0390-Optimize-Hoppers.patch => server/0347-Optimize-Hoppers.patch} (51%) rename patches/{server-remapped/0391-PlayerDeathEvent-shouldDropExperience.patch => server/0348-PlayerDeathEvent-shouldDropExperience.patch} (79%) rename patches/{server-remapped/0392-Prevent-bees-loading-chunks-checking-hive-position.patch => server/0349-Prevent-bees-loading-chunks-checking-hive-position.patch} (85%) rename patches/{server-remapped/0393-Don-t-load-Chunks-from-Hoppers-and-other-things.patch => server/0350-Don-t-load-Chunks-from-Hoppers-and-other-things.patch} (58%) create mode 100644 patches/server/0351-Guard-against-serializing-mismatching-chunk-coordina.patch rename patches/{server-remapped/0395-Optimise-IEntityAccess-getPlayerByUUID.patch => server/0352-Optimise-IEntityAccess-getPlayerByUUID.patch} (51%) rename patches/{server-remapped/0396-Fix-items-not-falling-correctly.patch => server/0353-Fix-items-not-falling-correctly.patch} (66%) rename patches/{server-remapped/0397-Lag-compensate-eating.patch => server/0354-Lag-compensate-eating.patch} (57%) rename patches/{server-remapped/0398-Optimize-call-to-getFluid-for-explosions.patch => server/0355-Optimize-call-to-getFluid-for-explosions.patch} (72%) rename patches/{server-remapped/0399-Fix-last-firework-in-stack-not-having-effects-when-d.patch => server/0356-Fix-last-firework-in-stack-not-having-effects-when-d.patch} (90%) rename patches/{server-remapped/0400-Add-effect-to-block-break-naturally.patch => server/0357-Add-effect-to-block-break-naturally.patch} (81%) rename patches/{server-remapped/0402-Entity-Activation-Range-2.0.patch => server/0358-Entity-Activation-Range-2.0.patch} (58%) rename patches/{server-remapped/0429-Increase-Light-Queue-Size.patch => server/0359-Increase-Light-Queue-Size.patch} (78%) rename patches/{server-remapped/0472-Fix-Light-Command.patch => server/0360-Fix-Light-Command.patch} (68%) rename patches/{server-remapped/0470-No-Tick-view-distance-implementation.patch => server/0361-No-Tick-view-distance-implementation.patch} (68%) diff --git a/patches/api-unmapped/0184-Expose-the-internal-current-tick.patch b/patches/api/0184-Expose-the-internal-current-tick.patch similarity index 87% rename from patches/api-unmapped/0184-Expose-the-internal-current-tick.patch rename to patches/api/0184-Expose-the-internal-current-tick.patch index b127872bf..b83fdf74f 100644 --- a/patches/api-unmapped/0184-Expose-the-internal-current-tick.patch +++ b/patches/api/0184-Expose-the-internal-current-tick.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Expose the internal current tick diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index e3304fcc8c4fd176abd3fb7d4b47e5ccb7bdd37f..49bf621a2c0e5e9641b334a42b2769944c991d5d 100644 +index 7dd3fc9301de9a88313179088f6b5ce4c1362f06..02f91b446697b1c637fda3b65b48ec8cf38de66d 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java @@ -1835,6 +1835,10 @@ public final class Bukkit { @@ -20,7 +20,7 @@ index e3304fcc8c4fd176abd3fb7d4b47e5ccb7bdd37f..49bf621a2c0e5e9641b334a42b276994 @NotNull diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index 989a732e5ef2053deede245d65fbf99cdf117c5e..e448ae78304974f7664b7ef18568a547833ece9f 100644 +index 139a96d01e3a7e2e298592ce5d485dfc21c9c6c7..b038a82ffc298abb5129b6ec20538df5d0b6f595 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java @@ -1609,5 +1609,12 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi diff --git a/patches/api-unmapped/0185-PlayerDeathEvent-shouldDropExperience.patch b/patches/api/0185-PlayerDeathEvent-shouldDropExperience.patch similarity index 97% rename from patches/api-unmapped/0185-PlayerDeathEvent-shouldDropExperience.patch rename to patches/api/0185-PlayerDeathEvent-shouldDropExperience.patch index f19bdcd56..cc31e6747 100644 --- a/patches/api-unmapped/0185-PlayerDeathEvent-shouldDropExperience.patch +++ b/patches/api/0185-PlayerDeathEvent-shouldDropExperience.patch @@ -5,7 +5,7 @@ Subject: [PATCH] PlayerDeathEvent#shouldDropExperience diff --git a/src/main/java/org/bukkit/event/entity/PlayerDeathEvent.java b/src/main/java/org/bukkit/event/entity/PlayerDeathEvent.java -index 7b78afe9281681cb9262fa044c1069a6121358eb..46917615ac4734bf5fa4ddea497132466eb5cc35 100644 +index 8c46eaebf004823c1c31eb2c7304181487cb1332..3d45d2e41aad6992b40a22030f2a63baeec78757 100644 --- a/src/main/java/org/bukkit/event/entity/PlayerDeathEvent.java +++ b/src/main/java/org/bukkit/event/entity/PlayerDeathEvent.java @@ -1,6 +1,8 @@ diff --git a/patches/api-unmapped/0186-Add-effect-to-block-break-naturally.patch b/patches/api/0186-Add-effect-to-block-break-naturally.patch similarity index 91% rename from patches/api-unmapped/0186-Add-effect-to-block-break-naturally.patch rename to patches/api/0186-Add-effect-to-block-break-naturally.patch index 7c52aaa44..5ccd8c254 100644 --- a/patches/api-unmapped/0186-Add-effect-to-block-break-naturally.patch +++ b/patches/api/0186-Add-effect-to-block-break-naturally.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add effect to block break naturally diff --git a/src/main/java/org/bukkit/block/Block.java b/src/main/java/org/bukkit/block/Block.java -index d4ba9c2b858204825d47fd6e91dab8c003df085a..f8c599718143fe638de422fd4625f353ee6c54ae 100644 +index 5e2aa4fb8cf8130df21d3172dd94e857317f7653..e1cc36fbe808973227c0e8ca7166453235c90279 100644 --- a/src/main/java/org/bukkit/block/Block.java +++ b/src/main/java/org/bukkit/block/Block.java @@ -469,6 +469,18 @@ public interface Block extends Metadatable { diff --git a/patches/api-unmapped/0201-World-view-distance-api.patch b/patches/api/0187-World-view-distance-api.patch similarity index 94% rename from patches/api-unmapped/0201-World-view-distance-api.patch rename to patches/api/0187-World-view-distance-api.patch index 17a9a94f1..64845bcaf 100644 --- a/patches/api-unmapped/0201-World-view-distance-api.patch +++ b/patches/api/0187-World-view-distance-api.patch @@ -5,7 +5,7 @@ Subject: [PATCH] World view distance api diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java -index 7bf85151efddcbd561afb0fb2d423aa97ac176c1..61dfb057d94d89477d11b9e8d4be7c16032e25a9 100644 +index 6fe2875f95bb600606d66e2f7113d325d10a9b9c..cd96c851d00185e7ee3ec6682b166fc1d06b6a73 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java @@ -3447,6 +3447,34 @@ public interface World extends PluginMessageRecipient, Metadatable, net.kyori.ad diff --git a/patches/server-remapped/0380-Performance-improvement-for-Chunk.getEntities.patch b/patches/removed/1.17/0380-Performance-improvement-for-Chunk.getEntities.patch similarity index 96% rename from patches/server-remapped/0380-Performance-improvement-for-Chunk.getEntities.patch rename to patches/removed/1.17/0380-Performance-improvement-for-Chunk.getEntities.patch index 439bca032..508f96a2b 100644 --- a/patches/server-remapped/0380-Performance-improvement-for-Chunk.getEntities.patch +++ b/patches/removed/1.17/0380-Performance-improvement-for-Chunk.getEntities.patch @@ -9,6 +9,8 @@ extra array with List.toArray() with is a costly and unneccessary operation. This patch will reduce the load of plugins which for example implement custom moblimits and depend on Chunk.getEntities(). +1.17: needs to be reworked, entities not in chunk anymore? + diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java index 74bad15034d9d55fb70931f38868f812160c6305..0f45f4b2486e910d11fd94b260bcd68e49eae31e 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java diff --git a/patches/server-remapped/0378-Generator-Settings.patch b/patches/server-remapped/0378-Generator-Settings.patch deleted file mode 100644 index fe0b780b5..000000000 --- a/patches/server-remapped/0378-Generator-Settings.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Byteflux -Date: Wed, 2 Mar 2016 02:17:54 -0600 -Subject: [PATCH] Generator Settings - - -diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index 6aec502eb529d4090306e12e837117cde7e114eb..290e49cf0077909ad7ab8127c01ef93cf7b70b51 100644 ---- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -@@ -570,4 +570,9 @@ public class PaperWorldConfig { - private void perPlayerMobSpawns() { - perPlayerMobSpawns = getBoolean("per-player-mob-spawns", false); - } -+ -+ public boolean generateFlatBedrock; -+ private void generatorSettings() { -+ generateFlatBedrock = getBoolean("generator-settings.flat-bedrock", false); -+ } - } -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 e6303cdb433ee2b6782e2a0bd6b03e4f6ecb18ba..36c7ab3919d8818af96d50170aeb431051c5aabf 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java -+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java -@@ -25,6 +25,18 @@ import org.apache.logging.log4j.LogManager; - - public interface ChunkAccess extends BlockGetter, FeatureAccess { - -+ // Paper start -+ default boolean generateFlatBedrock() { -+ if (this instanceof ProtoChunk) { -+ return ((ProtoChunk)this).world.paperConfig.generateFlatBedrock; -+ } else if (this instanceof LevelChunk) { -+ return ((LevelChunk)this).world.paperConfig.generateFlatBedrock; -+ } else { -+ return false; -+ } -+ } -+ // Paper end -+ - BlockState getType(final int x, final int y, final int z); // Paper - @Nullable - BlockState setBlockState(BlockPos pos, BlockState state, boolean moved); -diff --git a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java -index 87fd585141ad9818fca0b697cb4c87248fe7ce11..5a94464b9628b74eefa1c1d8514cf267f4c8a11d 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java -+++ b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java -@@ -64,7 +64,7 @@ public class ProtoChunk implements ChunkAccess { - private long inhabitedTime; - private final Map carvingMasks; - private volatile boolean isLightCorrect; -- private final Level world; // Paper - Anti-Xray - Add world -+ final Level world; // Paper - Anti-Xray - Add world // Paper - private -> default - - // Paper start - Anti-Xray - Add world - @Deprecated public ProtoChunk(ChunkPos pos, UpgradeData upgradeData) { this(pos, upgradeData, null); } // Notice for updates: Please make sure this constructor isn't used anywhere -diff --git a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java -index b38a9c87fc996bd3107c38f6446a687fd093c617..04adec255e4650ead8d80bee32a681c98686fb95 100644 ---- a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java -+++ b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java -@@ -408,8 +408,8 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { - int i = chunk.getPos().getMinBlockX(); - int j = chunk.getPos().getMinBlockZ(); - NoiseGeneratorSettings generatorsettingbase = (NoiseGeneratorSettings) this.settings.get(); -- int k = generatorsettingbase.getBedrockFloorPosition(); -- int l = this.height - 1 - generatorsettingbase.getBedrockRoofPosition(); -+ int k = generatorsettingbase.getBedrockFloorPosition(); final int floorHeight = k; // Paper -+ int l = this.height - 1 - generatorsettingbase.getBedrockRoofPosition(); final int roofHeight = l; // Paper - boolean flag = true; - boolean flag1 = l + 4 >= 0 && l < this.height; - boolean flag2 = k + 4 >= 0 && k < this.height; -@@ -423,7 +423,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { - - if (flag1) { - for (i1 = 0; i1 < 5; ++i1) { -- if (i1 <= random.nextInt(5)) { -+ if (i1 <= (chunk.generateFlatBedrock() ? roofHeight : random.nextInt(5))) { // Paper - Configurable flat bedrock roof - chunk.setBlockState(blockposition_mutableblockposition.set(blockposition.getX(), l - i1, blockposition.getZ()), Blocks.BEDROCK.defaultBlockState(), false); - } - } -@@ -431,7 +431,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { - - if (flag2) { - for (i1 = 4; i1 >= 0; --i1) { -- if (i1 <= random.nextInt(5)) { -+ if (i1 <= (chunk.generateFlatBedrock() ? floorHeight : random.nextInt(5))) { // Paper - Configurable flat bedrock floor - chunk.setBlockState(blockposition_mutableblockposition.set(blockposition.getX(), k + i1, blockposition.getZ()), Blocks.BEDROCK.defaultBlockState(), false); - } - } diff --git a/patches/server-remapped/0388-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch b/patches/server-remapped/0388-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch deleted file mode 100644 index 32b045db4..000000000 --- a/patches/server-remapped/0388-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch +++ /dev/null @@ -1,20 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Callahan -Date: Mon, 13 Jan 2020 23:47:28 -0600 -Subject: [PATCH] Prevent sync chunk loads when villagers try to find beds - - -diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/SleepInBed.java b/src/main/java/net/minecraft/world/entity/ai/behavior/SleepInBed.java -index 5151c794985a135d3bd794bbafdf524ab9f670de..9a582fb4b96b2d0406cc86e473e8bf8c4e488e37 100644 ---- a/src/main/java/net/minecraft/world/entity/ai/behavior/SleepInBed.java -+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/SleepInBed.java -@@ -46,7 +46,8 @@ public class SleepInBed extends Behavior { - } - } - -- BlockState iblockdata = world.getBlockState(globalpos.getBlockPosition()); -+ BlockState iblockdata = world.getTypeIfLoaded(globalpos.getBlockPosition()); // Paper -+ if (iblockdata == null) { return false; } // Paper - - return globalpos.getBlockPosition().a((Position) entity.position(), 2.0D) && iblockdata.getBlock().is((Tag) BlockTags.BEDS) && !(Boolean) iblockdata.getValue(BedBlock.OCCUPIED); - } diff --git a/patches/server-remapped/0394-Guard-against-serializing-mismatching-chunk-coordina.patch b/patches/server-remapped/0394-Guard-against-serializing-mismatching-chunk-coordina.patch deleted file mode 100644 index 37dc33fc4..000000000 --- a/patches/server-remapped/0394-Guard-against-serializing-mismatching-chunk-coordina.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Fri, 27 Dec 2019 09:42:26 -0800 -Subject: [PATCH] Guard against serializing mismatching chunk coordinate - -Should help if something dumb happens - -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -index be67dc16bf70e4517efd213ca9002f116f60b57c..6c28a611b9b79c3322ab07883972c07b3bfc3073 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -@@ -67,6 +67,13 @@ public class ChunkSerializer { - - private static final Logger LOGGER = LogManager.getLogger(); - -+ // Paper start - guard against serializing mismatching coordinates -+ // TODO Note: This needs to be re-checked each update -+ public static ChunkPos getChunkCoordinate(CompoundTag chunkData) { -+ CompoundTag levelData = chunkData.getCompound("Level"); -+ return new ChunkPos(levelData.getInt("xPos"), levelData.getInt("zPos")); -+ } -+ // Paper end - // Paper start - public static final class InProgressChunkHolder { - -@@ -92,8 +99,8 @@ public class ChunkSerializer { - // Paper end - ChunkGenerator chunkgenerator = worldserver.getChunkSource().getGenerator(); - BiomeSource worldchunkmanager = chunkgenerator.getBiomeSource(); -- CompoundTag nbttagcompound1 = nbttagcompound.getCompound("Level"); -- ChunkPos chunkcoordintpair1 = new ChunkPos(nbttagcompound1.getInt("xPos"), nbttagcompound1.getInt("zPos")); -+ CompoundTag nbttagcompound1 = nbttagcompound.getCompound("Level"); // Paper - diff on change, see ChunkRegionLoader#getChunkCoordinate -+ ChunkPos chunkcoordintpair1 = new ChunkPos(nbttagcompound1.getInt("xPos"), nbttagcompound1.getInt("zPos")); // Paper - diff on change, see ChunkRegionLoader#getChunkCoordinate - - if (!Objects.equals(chunkcoordintpair, chunkcoordintpair1)) { - ChunkSerializer.LOGGER.error("Chunk file at {} is in the wrong location; relocating. (Expected {}, got {})", chunkcoordintpair, chunkcoordintpair, chunkcoordintpair1); -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java -index 684442b7175e30b6d4cafb2f7d2d4c10517cc33d..1af804c5c6fb2b20ea3f020610763c1d7dcee110 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java -@@ -13,6 +13,7 @@ import net.minecraft.SharedConstants; - import net.minecraft.nbt.CompoundTag; - import net.minecraft.nbt.NbtUtils; - import net.minecraft.resources.ResourceKey; -+import net.minecraft.server.level.ChunkMap; - import net.minecraft.server.level.ServerChunkCache; - import net.minecraft.server.level.ServerLevel; - import net.minecraft.util.datafix.DataFixTypes; -@@ -119,6 +120,13 @@ public class ChunkStorage implements AutoCloseable { - - public void write(ChunkPos chunkcoordintpair, CompoundTag nbttagcompound) throws IOException { write(chunkcoordintpair, nbttagcompound); } // Paper OBFHELPER - public void write(ChunkPos chunkcoordintpair, CompoundTag nbttagcompound) throws IOException { // Paper - OBFHELPER - (Switched around for safety) -+ // Paper start -+ if (!chunkcoordintpair.equals(ChunkSerializer.getChunkCoordinate(nbttagcompound))) { -+ String world = (this instanceof ChunkMap) ? ((ChunkMap)this).level.getWorld().getName() : null; -+ throw new IllegalArgumentException("Chunk coordinate and serialized data do not have matching coordinates, trying to serialize coordinate " + chunkcoordintpair.toString() -+ + " but compound says coordinate is " + ChunkSerializer.getChunkCoordinate(nbttagcompound).toString() + (world == null ? " for an unknown world" : (" for world: " + world))); -+ } -+ // Paper end - this.regionFileCache.write(chunkcoordintpair, nbttagcompound); - if (this.legacyStructureHandler != null) { - synchronized (this.persistentDataLock) { // Paper - Async chunk loading diff --git a/patches/server/0338-Generator-Settings.patch b/patches/server/0338-Generator-Settings.patch new file mode 100644 index 000000000..590c2cd9f --- /dev/null +++ b/patches/server/0338-Generator-Settings.patch @@ -0,0 +1,165 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Byteflux +Date: Wed, 2 Mar 2016 02:17:54 -0600 +Subject: [PATCH] Generator Settings + + +diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +index 4c177a383b277debe8a7c02a70d029d862e6b048..0c336a794d21d5084b9ea39308379b2ffb4a4330 100644 +--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java ++++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +@@ -416,5 +416,10 @@ public class PaperWorldConfig { + private void disableRelativeProjectileVelocity() { + disableRelativeProjectileVelocity = getBoolean("game-mechanics.disable-relative-projectile-velocity", false); + } ++ ++ public boolean generateFlatBedrock; ++ private void generatorSettings() { ++ generateFlatBedrock = getBoolean("generator-settings.flat-bedrock", false); ++ } + } + +diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java +index dd7de2c3db10d9d606d47c52eba40e71034fc11a..5473b22d21ea981f245f4826c4d47295890f88ef 100644 +--- a/src/main/java/net/minecraft/server/level/ChunkMap.java ++++ b/src/main/java/net/minecraft/server/level/ChunkMap.java +@@ -678,7 +678,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + } + + this.markPositionReplaceable(pos); +- return Either.left(new ProtoChunk(pos, UpgradeData.EMPTY, this.level)); ++ return Either.left(new ProtoChunk(pos, UpgradeData.EMPTY, this.level, this.level)); // Paper - add level + // Paper start - Async chunk io + }; + CompletableFuture> ret = new CompletableFuture<>(); +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 974ab04b08bbd3c27a394b37c1af112be5f28f43..c0075d226331f32e470dae5bf1ce8d79e8b263dc 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java ++++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java +@@ -29,6 +29,18 @@ public interface ChunkAccess extends BlockGetter, FeatureAccess { + return GameEventDispatcher.NOOP; + } + ++ // Paper start ++ default boolean generateFlatBedrock() { ++ if (this instanceof ProtoChunk) { ++ return ((ProtoChunk)this).level.paperConfig.generateFlatBedrock; ++ } else if (this instanceof LevelChunk) { ++ return ((LevelChunk)this).level.paperConfig.generateFlatBedrock; ++ } else { ++ return false; ++ } ++ } ++ // Paper end ++ + BlockState getType(final int x, final int y, final int z); // Paper + @Nullable + BlockState setBlockState(BlockPos pos, BlockState state, boolean moved); +diff --git a/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java b/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java +index 452b513e8b89d865a396066adaf4feb1140e1c62..8245c5834ec69beb8e3b95fb3900601009a9273f 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java ++++ b/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java +@@ -25,7 +25,7 @@ public class ImposterProtoChunk extends ProtoChunk { + private final LevelChunk wrapped; + + public ImposterProtoChunk(LevelChunk wrapped) { +- super(wrapped.getPos(), UpgradeData.EMPTY, wrapped); ++ super(wrapped.getPos(), UpgradeData.EMPTY, wrapped, wrapped.level); // Paper - add level + this.wrapped = wrapped; + } + +diff --git a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java +index da36e6d40ad3e8b7cdbe09ef911d1e5b8c28670f..245998e2cea32cf15ee2659639c647f449704ec0 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java ++++ b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java +@@ -63,16 +63,24 @@ public class ProtoChunk implements ChunkAccess { + private long inhabitedTime; + private final Map carvingMasks = new Object2ObjectArrayMap<>(); + private volatile boolean isLightCorrect; ++ final net.minecraft.world.level.Level level; // Paper - Add level + +- public ProtoChunk(ChunkPos pos, UpgradeData upgradeData, LevelHeightAccessor world) { ++ // Paper start - add level ++ @Deprecated public ProtoChunk(ChunkPos pos, UpgradeData upgradeData, LevelHeightAccessor world) { this(pos, upgradeData, world, null); } ++ public ProtoChunk(ChunkPos pos, UpgradeData upgradeData, LevelHeightAccessor world, net.minecraft.server.level.ServerLevel level) { ++ // Paper end + this(pos, upgradeData, (LevelChunkSection[])null, new ProtoTickList<>((block) -> { + return block == null || block.defaultBlockState().isAir(); + }, pos, world), new ProtoTickList<>((fluid) -> { + return fluid == null || fluid == Fluids.EMPTY; +- }, pos, world), world); ++ }, pos, world), world, level); // Paper - add level + } + +- public ProtoChunk(ChunkPos pos, UpgradeData upgradeData, @Nullable LevelChunkSection[] levelChunkSections, ProtoTickList blockTickScheduler, ProtoTickList fluidTickScheduler, LevelHeightAccessor world) { ++ // Paper start - add level ++ @Deprecated public ProtoChunk(ChunkPos pos, UpgradeData upgradeData, @Nullable LevelChunkSection[] levelChunkSections, ProtoTickList blockTickScheduler, ProtoTickList fluidTickScheduler, LevelHeightAccessor world) { this(pos, upgradeData, levelChunkSections, blockTickScheduler, fluidTickScheduler, world, null); } ++ public ProtoChunk(ChunkPos pos, UpgradeData upgradeData, @Nullable LevelChunkSection[] levelChunkSections, ProtoTickList blockTickScheduler, ProtoTickList fluidTickScheduler, LevelHeightAccessor world, net.minecraft.server.level.ServerLevel level) { ++ this.level = level; ++ // Paper end + this.chunkPos = pos; + this.upgradeData = upgradeData; + this.blockTicks = blockTickScheduler; +diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java +index fc320450878279a6aa48019fbde35bb183f5f06e..3cb35f2f47ba841915ac2825d30cc4c3274ce3c4 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java ++++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java +@@ -210,7 +210,7 @@ public class ChunkSerializer { + // CraftBukkit end + }); + } else { +- ProtoChunk protochunk = new ProtoChunk(pos, chunkconverter, achunksection, protochunkticklist, protochunkticklist1, world); ++ ProtoChunk protochunk = new ProtoChunk(pos, chunkconverter, achunksection, protochunkticklist, protochunkticklist1, world, world); // Paper - add level + + protochunk.setBiomes(biomestorage); + object = protochunk; +diff --git a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java +index a0a3cf7655eca5c2b181476b0842d9e8c19dbffd..db0abd275be2df7a4fdeb1d7179bff4d61bab052 100644 +--- a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java ++++ b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java +@@ -270,8 +270,8 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { + int j = chunk.getPos().getMinBlockZ(); + NoiseGeneratorSettings noiseGeneratorSettings = this.settings.get(); + int k = noiseGeneratorSettings.noiseSettings().minY(); +- int l = k + noiseGeneratorSettings.getBedrockFloorPosition(); +- int m = this.height - 1 + k - noiseGeneratorSettings.getBedrockRoofPosition(); ++ int l = k + noiseGeneratorSettings.getBedrockFloorPosition(); final int floorHeight = k; // Paper ++ int m = this.height - 1 + k - noiseGeneratorSettings.getBedrockRoofPosition(); final int roofHeight = l; // Paper + int n = 5; + int o = chunk.getMinBuildHeight(); + int p = chunk.getMaxBuildHeight(); +@@ -281,7 +281,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { + for(BlockPos blockPos : BlockPos.betweenClosed(i, 0, j, i + 15, 0, j + 15)) { + if (bl) { + for(int q = 0; q < 5; ++q) { +- if (q <= random.nextInt(5)) { ++ if (q <= (chunk.generateFlatBedrock() ? roofHeight : random.nextInt(5))) { // Paper - Configurable flat bedrock roof + chunk.setBlockState(mutableBlockPos.set(blockPos.getX(), m - q, blockPos.getZ()), Blocks.BEDROCK.defaultBlockState(), false); + } + } +@@ -289,7 +289,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { + + if (bl2) { + for(int r = 4; r >= 0; --r) { +- if (r <= random.nextInt(5)) { ++ if (r <= (chunk.generateFlatBedrock() ? roofHeight : random.nextInt(5))) { // Paper - Configurable flat bedrock floor + chunk.setBlockState(mutableBlockPos.set(blockPos.getX(), l + r, blockPos.getZ()), Blocks.BEDROCK.defaultBlockState(), false); + } + } +@@ -309,14 +309,14 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { + if (l <= 0) { + return CompletableFuture.completedFuture(chunk); + } else { +- int m = chunk.getSectionIndex(l * this.cellHeight - 1 + i); ++ int mStart = chunk.getSectionIndex(l * this.cellHeight - 1 + i); // Paper - decompile fix + int n = chunk.getSectionIndex(i); + return CompletableFuture.supplyAsync(() -> { + Set set = Sets.newHashSet(); + + ChunkAccess var16; + try { +- for(int m = m; m >= n; --m) { ++ for(int m = mStart; m >= n; --m) { // Paper - decompile fix + LevelChunkSection levelChunkSection = chunk.getOrCreateSection(m); + levelChunkSection.acquire(); + set.add(levelChunkSection); diff --git a/patches/server-remapped/0379-Fix-MC-161754.patch b/patches/server/0339-Fix-MC-161754.patch similarity index 54% rename from patches/server-remapped/0379-Fix-MC-161754.patch rename to patches/server/0339-Fix-MC-161754.patch index c50817dd4..5dcb7f8ca 100644 --- a/patches/server-remapped/0379-Fix-MC-161754.patch +++ b/patches/server/0339-Fix-MC-161754.patch @@ -9,15 +9,15 @@ We can use an entity valid check since this method is invoked for each inventory iteraction (thanks to CB) and on player tick (vanilla). diff --git a/src/main/java/net/minecraft/world/inventory/HorseInventoryMenu.java b/src/main/java/net/minecraft/world/inventory/HorseInventoryMenu.java -index 7246b3a84415e303591adb08d81362201deebfce..e0237e821b2c31ba68168fddf1c1a4ebfcf10ca7 100644 +index 9da2f9334ea98ecba328c7b0d022321d6194529b..0d145f075798dde27beef80022cd7c0f582f8253 100644 --- a/src/main/java/net/minecraft/world/inventory/HorseInventoryMenu.java +++ b/src/main/java/net/minecraft/world/inventory/HorseInventoryMenu.java -@@ -85,7 +85,7 @@ public class HorseInventoryMenu extends AbstractContainerMenu { +@@ -95,7 +95,7 @@ public class HorseInventoryMenu extends AbstractContainerMenu { @Override public boolean stillValid(Player player) { -- return this.horseContainer.stillValid(player) && this.horse.isAlive() && this.horse.distanceTo((Entity) player) < 8.0F; -+ return this.horseContainer.stillValid(player) && (this.horse.isAlive() && this.horse.valid) && this.horse.distanceTo((Entity) player) < 8.0F; // Paper - Fix MC-161754 +- return !this.horse.hasInventoryChanged(this.horseContainer) && this.horseContainer.stillValid(player) && this.horse.isAlive() && this.horse.distanceTo((Entity) player) < 8.0F; ++ return !this.horse.hasInventoryChanged(this.horseContainer) && this.horseContainer.stillValid(player) && (this.horse.isAlive() && this.horse.valid) && this.horse.distanceTo((Entity) player) < 8.0F; // Paper - Fix MC-161754 } - @Override + private boolean hasChest(AbstractHorse entityhorseabstract) { diff --git a/patches/server-remapped/0381-Fix-spawning-of-hanging-entities-that-are-not-ItemFr.patch b/patches/server/0340-Fix-spawning-of-hanging-entities-that-are-not-ItemFr.patch similarity index 85% rename from patches/server-remapped/0381-Fix-spawning-of-hanging-entities-that-are-not-ItemFr.patch rename to patches/server/0340-Fix-spawning-of-hanging-entities-that-are-not-ItemFr.patch index 548deb2cd..8a4a109b1 100644 --- a/patches/server-remapped/0381-Fix-spawning-of-hanging-entities-that-are-not-ItemFr.patch +++ b/patches/server/0340-Fix-spawning-of-hanging-entities-that-are-not-ItemFr.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Fix spawning of hanging entities that are not ItemFrames and diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 52444619a4bae80a12bf296fbe07fa811adf806e..fb74bdcf4c2935b56e92717cc5a1504fbc853d0a 100644 +index 4841591539fdd5a01f9ded0ee510991602c266a4..f1cbcdb1e409f8544125dde5f24bff5b07cb5082 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -1868,7 +1868,12 @@ public class CraftWorld implements World { +@@ -1881,7 +1881,12 @@ public class CraftWorld implements World { height = 9; } @@ -22,4 +22,4 @@ index 52444619a4bae80a12bf296fbe07fa811adf806e..fb74bdcf4c2935b56e92717cc5a1504f + // Paper end final BlockPos pos = new BlockPos(x, y, z); for (BlockFace dir : faces) { - net.minecraft.world.level.block.state.BlockState nmsBlock = world.getBlockState(pos.relative(CraftBlock.blockFaceToNotch(dir))); + net.minecraft.world.level.block.state.BlockState nmsBlock = this.world.getBlockState(pos.relative(CraftBlock.blockFaceToNotch(dir))); diff --git a/patches/server-remapped/0382-Expose-the-internal-current-tick.patch b/patches/server/0341-Expose-the-internal-current-tick.patch similarity index 81% rename from patches/server-remapped/0382-Expose-the-internal-current-tick.patch rename to patches/server/0341-Expose-the-internal-current-tick.patch index 9cf110529..038231105 100644 --- a/patches/server-remapped/0382-Expose-the-internal-current-tick.patch +++ b/patches/server/0341-Expose-the-internal-current-tick.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Expose the internal current tick diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 96a3a4d89df858d4e46a36f110dd9ad3a2061433..3c0ba80bbba19f3725013e118cecdbac5612deec 100644 +index 58d7fec472dd8c8d7775eb6d931be29871102054..9730c701b734eb3491bc1fa5d9bb81ddfefc910a 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2363,5 +2363,10 @@ public final class CraftServer implements Server { +@@ -2364,5 +2364,10 @@ public final class CraftServer implements Server { } return new com.destroystokyo.paper.profile.CraftPlayerProfile(uuid, name); } diff --git a/patches/server-remapped/0383-Fix-stuck-in-sneak-when-changing-worlds-MC-10657.patch b/patches/server/0342-Fix-stuck-in-sneak-when-changing-worlds-MC-10657.patch similarity index 78% rename from patches/server-remapped/0383-Fix-stuck-in-sneak-when-changing-worlds-MC-10657.patch rename to patches/server/0342-Fix-stuck-in-sneak-when-changing-worlds-MC-10657.patch index 169ff964a..559cc6317 100644 --- a/patches/server-remapped/0383-Fix-stuck-in-sneak-when-changing-worlds-MC-10657.patch +++ b/patches/server/0342-Fix-stuck-in-sneak-when-changing-worlds-MC-10657.patch @@ -5,23 +5,23 @@ Subject: [PATCH] Fix stuck in sneak when changing worlds (MC-10657) diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index b0eed4e18fc183856613c05f378576eb19985c46..2ef273e3b917803f3e2ac3c6a22d92a15b9eb71a 100644 +index 679f1e3ef4c19ab466cf2d06c47b1018aabaa7bf..8da35a7dde494b059e542d049d7ee039deb5833d 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -1070,6 +1070,8 @@ public class ServerPlayer extends Player implements ContainerListener { +@@ -1101,6 +1101,8 @@ public class ServerPlayer extends Player { this.lastSentHealth = -1.0F; this.lastSentFood = -1; -+ setShiftKeyDown(false); // Paper - fix MC-10657 ++ setShiftKeyDown(false); // Paper - fix MC-10657 + // CraftBukkit start PlayerChangedWorldEvent changeEvent = new PlayerChangedWorldEvent(this.getBukkitEntity(), worldserver1.getWorld()); this.level.getCraftServer().getPluginManager().callEvent(changeEvent); diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index e6eebb8f6f48cc55fc8fb114c959b8fbec4b8472..dfdde9722bc0d83916779014b7718eef2c01b3db 100644 +index 6f9bd5da1504af296e7ee2a69d8afdd3bc4cfd5e..bcc946d2747443c34ee8ac2485a5ab41773c93af 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -842,6 +842,8 @@ public abstract class PlayerList { +@@ -820,6 +820,8 @@ public abstract class PlayerList { entityplayer.connection.send(new ClientboundUpdateMobEffectPacket(entityplayer.getId(), mobEffect)); } diff --git a/patches/server-remapped/0384-Add-option-to-disable-pillager-patrols.patch b/patches/server/0343-Add-option-to-disable-pillager-patrols.patch similarity index 86% rename from patches/server-remapped/0384-Add-option-to-disable-pillager-patrols.patch rename to patches/server/0343-Add-option-to-disable-pillager-patrols.patch index 2e772d88a..12f2a0608 100644 --- a/patches/server-remapped/0384-Add-option-to-disable-pillager-patrols.patch +++ b/patches/server/0343-Add-option-to-disable-pillager-patrols.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add option to disable pillager patrols diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index 290e49cf0077909ad7ab8127c01ef93cf7b70b51..e726b6213cf2e8f5b326f05c0438b8f1ee2b73c5 100644 +index 0c336a794d21d5084b9ea39308379b2ffb4a4330..f46731897f4234b27dafa49a5f652535a99d2992 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -@@ -575,4 +575,9 @@ public class PaperWorldConfig { +@@ -421,5 +421,10 @@ public class PaperWorldConfig { private void generatorSettings() { generateFlatBedrock = getBoolean("generator-settings.flat-bedrock", false); } @@ -18,8 +18,9 @@ index 290e49cf0077909ad7ab8127c01ef93cf7b70b51..e726b6213cf2e8f5b326f05c0438b8f1 + disablePillagerPatrols = getBoolean("game-mechanics.disable-pillager-patrols", disablePillagerPatrols); + } } + diff --git a/src/main/java/net/minecraft/world/level/levelgen/PatrolSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PatrolSpawner.java -index caadd1a0fa6c4c446f84629088890a09e29622d9..48efe133d294bb1b17e8ac8b44eea8a29f15845f 100644 +index e0a376617f6b6232591942da0bc9d7b1ee58c2e7..744b58d59a5f34ed3bd6f2d4a0f876acfa6a7135 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/PatrolSpawner.java +++ b/src/main/java/net/minecraft/world/level/levelgen/PatrolSpawner.java @@ -26,6 +26,7 @@ public class PatrolSpawner implements CustomSpawner { diff --git a/patches/server-remapped/0385-Fix-AssertionError-when-player-hand-set-to-empty-typ.patch b/patches/server/0344-Fix-AssertionError-when-player-hand-set-to-empty-typ.patch similarity index 52% rename from patches/server-remapped/0385-Fix-AssertionError-when-player-hand-set-to-empty-typ.patch rename to patches/server/0344-Fix-AssertionError-when-player-hand-set-to-empty-typ.patch index 3d4d87429..fcb643423 100644 --- a/patches/server-remapped/0385-Fix-AssertionError-when-player-hand-set-to-empty-typ.patch +++ b/patches/server/0344-Fix-AssertionError-when-player-hand-set-to-empty-typ.patch @@ -7,10 +7,10 @@ Fixes an AssertionError when setting the player's item in hand to null or a new Fixes GH-2718 diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index e45690b6197335ed1c07fa04c39b311b401724d7..2b79413bb8a592a7b7093e11d3a0cce895286c8f 100644 +index 377e224acb06bfd5f769b5f75b7f52129394b494..9240064a17e7ac2492fe157b759d1f724105cd0e 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1706,6 +1706,10 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener { +@@ -1741,6 +1741,10 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser this.player.getBukkitEntity().updateInventory(); // SPIGOT-2524 return; } @@ -21,15 +21,3 @@ index e45690b6197335ed1c07fa04c39b311b401724d7..2b79413bb8a592a7b7093e11d3a0cce8 InteractionResult enuminteractionresult = this.player.gameMode.useItem(this.player, worldserver, itemstack, enumhand); if (enuminteractionresult.shouldSwing()) { -diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index f8917123547615dd624e3e428ec1bf6450c7b7d8..b49d4772932a58852b3195f5f56ff93dbcabf766 100644 ---- a/src/main/java/net/minecraft/world/entity/LivingEntity.java -+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -2153,6 +2153,7 @@ public abstract class LivingEntity extends Entity { - return predicate.test(this.getMainHandItem().getItem()) || predicate.test(this.getOffhandItem().getItem()); - } - -+ public final ItemStack getItemInHand(InteractionHand enumhand) { return this.getItemInHand(enumhand); } // Paper - OBFHELPER - public ItemStack getItemInHand(InteractionHand hand) { - if (hand == InteractionHand.MAIN_HAND) { - return this.getItemBySlot(EquipmentSlot.MAINHAND); diff --git a/patches/server/0345-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch b/patches/server/0345-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch new file mode 100644 index 000000000..740993993 --- /dev/null +++ b/patches/server/0345-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch @@ -0,0 +1,20 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Callahan +Date: Mon, 13 Jan 2020 23:47:28 -0600 +Subject: [PATCH] Prevent sync chunk loads when villagers try to find beds + + +diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/SleepInBed.java b/src/main/java/net/minecraft/world/entity/ai/behavior/SleepInBed.java +index 455774a211c679367c6e7845a11159ad84ca07e2..673b6e60731d440cc02b1e86bfba50e6ebeb0da9 100644 +--- a/src/main/java/net/minecraft/world/entity/ai/behavior/SleepInBed.java ++++ b/src/main/java/net/minecraft/world/entity/ai/behavior/SleepInBed.java +@@ -41,7 +41,8 @@ public class SleepInBed extends Behavior { + } + } + +- BlockState blockState = world.getBlockState(globalPos.pos()); ++ BlockState blockState = world.getTypeIfLoaded(globalPos.pos()); // Paper ++ if (blockState == null) { return false; } // Paper + return globalPos.pos().closerThan(entity.position(), 2.0D) && blockState.is(BlockTags.BEDS) && !blockState.getValue(BedBlock.OCCUPIED); + } + } diff --git a/patches/server-remapped/0389-MC-145656-Fix-Follow-Range-Initial-Target.patch b/patches/server/0346-MC-145656-Fix-Follow-Range-Initial-Target.patch similarity index 62% rename from patches/server-remapped/0389-MC-145656-Fix-Follow-Range-Initial-Target.patch rename to patches/server/0346-MC-145656-Fix-Follow-Range-Initial-Target.patch index 27d343fa1..e7218a0ce 100644 --- a/patches/server-remapped/0389-MC-145656-Fix-Follow-Range-Initial-Target.patch +++ b/patches/server/0346-MC-145656-Fix-Follow-Range-Initial-Target.patch @@ -5,10 +5,10 @@ Subject: [PATCH] MC-145656 Fix Follow Range Initial Target diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index e726b6213cf2e8f5b326f05c0438b8f1ee2b73c5..edda2121f8c1046478beaa77030ebb36d403b334 100644 +index f46731897f4234b27dafa49a5f652535a99d2992..8190c30346c0fd2d86fb7cbcfc7ce17333e05146 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -@@ -580,4 +580,9 @@ public class PaperWorldConfig { +@@ -426,5 +426,10 @@ public class PaperWorldConfig { private void pillagerSettings() { disablePillagerPatrols = getBoolean("game-mechanics.disable-pillager-patrols", disablePillagerPatrols); } @@ -18,41 +18,33 @@ index e726b6213cf2e8f5b326f05c0438b8f1ee2b73c5..edda2121f8c1046478beaa77030ebb36 + entitiesTargetWithFollowRange = getBoolean("entities-target-with-follow-range", entitiesTargetWithFollowRange); + } } + diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/target/NearestAttackableTargetGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/target/NearestAttackableTargetGoal.java -index 7bba2ac71a3cd34a06ec865a3c1828b10decd644..93845edab0e1b0e2ad300cad051b0182cadd46e5 100644 +index 6cbd2fc4a7041f957966e5b09616e70aae63c0d4..b5bbcb9fa6de4c919e4d4fabbab483054d81574e 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/target/NearestAttackableTargetGoal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/target/NearestAttackableTargetGoal.java @@ -32,6 +32,7 @@ public class NearestAttackableTargetGoal extends TargetG this.randomInterval = reciprocalChance; this.setFlags(EnumSet.of(Goal.Flag.TARGET)); - this.targetConditions = (new TargetingConditions()).range(this.getFollowDistance()).selector(targetPredicate); + this.targetConditions = TargetingConditions.forCombat().range(this.getFollowDistance()).selector(targetPredicate); + if (mob.level.paperConfig.entitiesTargetWithFollowRange) this.targetConditions.useFollowRange(); // Paper } @Override diff --git a/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java b/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java -index 1714507fa744b2767e8a66cdb5db7f43c21f5c56..e1a0104a3b52990a83e7732491029d8a20976dc3 100644 +index e45434b844c98c322e1432c2382c1ccb8c3e57a7..3ee691d4caccbc1b3e0f52decb41d436ac0d08ec 100644 --- a/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java +++ b/src/main/java/net/minecraft/world/entity/ai/targeting/TargetingConditions.java -@@ -4,6 +4,8 @@ import java.util.function.Predicate; - import javax.annotation.Nullable; - import net.minecraft.world.entity.LivingEntity; - import net.minecraft.world.entity.Mob; -+import net.minecraft.world.entity.ai.attributes.AttributeInstance; -+import net.minecraft.world.entity.ai.attributes.Attributes; - - public class TargetingConditions { - -@@ -82,7 +84,7 @@ public class TargetingConditions { +@@ -75,7 +75,7 @@ public class TargetingConditions { if (this.range > 0.0D) { - double d0 = this.testInvisible ? targetEntity.getVisibilityPercent(baseEntity) : 1.0D; -- double d1 = Math.max(this.range * d0, 2.0D); -+ double d1 = Math.max((useFollowRange ? getFollowRange(baseEntity) : this.range) * d0, 2.0D); // Paper - double d2 = baseEntity.distanceToSqr(targetEntity.getX(), targetEntity.getY(), targetEntity.getZ()); - - if (d2 > d1 * d1) { -@@ -98,4 +100,18 @@ public class TargetingConditions { + double d = this.testInvisible ? targetEntity.getVisibilityPercent(baseEntity) : 1.0D; +- double e = Math.max(this.range * d, 2.0D); ++ double e = Math.max((this.useFollowRange ? this.getFollowRange(baseEntity) : this.range) * d, 2.0D); // Paper + double f = baseEntity.distanceToSqr(targetEntity.getX(), targetEntity.getY(), targetEntity.getZ()); + if (f > e * e) { + return false; +@@ -90,4 +90,18 @@ public class TargetingConditions { return true; } } @@ -66,7 +58,7 @@ index 1714507fa744b2767e8a66cdb5db7f43c21f5c56..e1a0104a3b52990a83e7732491029d8a + } + + private double getFollowRange(LivingEntity entityliving) { -+ AttributeInstance attributeinstance = entityliving.getAttribute(Attributes.FOLLOW_RANGE); ++ net.minecraft.world.entity.ai.attributes.AttributeInstance attributeinstance = entityliving.getAttribute(net.minecraft.world.entity.ai.attributes.Attributes.FOLLOW_RANGE); + return attributeinstance == null ? 16.0D : attributeinstance.getValue(); + } + // Paper end diff --git a/patches/server-remapped/0390-Optimize-Hoppers.patch b/patches/server/0347-Optimize-Hoppers.patch similarity index 51% rename from patches/server-remapped/0390-Optimize-Hoppers.patch rename to patches/server/0347-Optimize-Hoppers.patch index 5d342ad55..d68d9a035 100644 --- a/patches/server-remapped/0390-Optimize-Hoppers.patch +++ b/patches/server/0347-Optimize-Hoppers.patch @@ -13,10 +13,10 @@ Subject: [PATCH] Optimize Hoppers * Remove Streams from Item Suck In and restore restore 1.12 AABB checks which is simpler and no voxel allocations (was doing TWO Item Suck ins) diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index edda2121f8c1046478beaa77030ebb36d403b334..7fbd501d70dccf869a4454e2789a5d68f2e15754 100644 +index 8190c30346c0fd2d86fb7cbcfc7ce17333e05146..041efecbfcd54384d15ebf771cdfa0e711483997 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -@@ -585,4 +585,13 @@ public class PaperWorldConfig { +@@ -431,5 +431,14 @@ public class PaperWorldConfig { private void entitiesTargetWithFollowRange() { entitiesTargetWithFollowRange = getBoolean("entities-target-with-follow-range", entitiesTargetWithFollowRange); } @@ -30,31 +30,24 @@ index edda2121f8c1046478beaa77030ebb36d403b334..7fbd501d70dccf869a4454e2789a5d68 + log("Hopper Move Item Events: " + (disableHopperMoveEvents ? "disabled" : "enabled")); + } } + diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 753e6f609189c589514739bea80007bace3c89d2..7038897b8fb4c18ca97b95a3b24c30b40b62b005 100644 +index f00839eab02277bf10b742c88fadc4aa9e89e7e0..312be2221e1acc44aaf6936533b0eb968f796dc6 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -131,6 +131,7 @@ import net.minecraft.world.level.LevelSettings; - import net.minecraft.world.level.biome.BiomeManager; - import net.minecraft.world.level.biome.BiomeSource; - import net.minecraft.world.level.block.Block; -+import net.minecraft.world.level.block.entity.HopperBlockEntity; - import net.minecraft.world.level.border.WorldBorder; - import net.minecraft.world.level.chunk.ChunkGenerator; - import net.minecraft.world.level.dimension.DimensionType; -@@ -1360,6 +1361,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper -+ HopperBlockEntity.skipHopperEvents = worldserver.paperConfig.disableHopperMoveEvents || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper ++ net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = worldserver.paperConfig.disableHopperMoveEvents || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper this.profiler.push(() -> { return worldserver + " " + worldserver.dimension().location(); diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index 02bfa4fb8055e60a84e878ffbf18303c0ee25b1d..ac996d581925c8f92832009945c766962e5b51c5 100644 +index dd4deb08eb3ed15a156269a11d3d43abfd61fe5b..10f55ba189d12c46e0ef38b0b96a29894b4fba93 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -538,11 +538,12 @@ public final class ItemStack { +@@ -601,11 +601,12 @@ public final class ItemStack { return this.getItem().interactLivingEntity(this, user, entity, hand); } @@ -70,89 +63,75 @@ index 02bfa4fb8055e60a84e878ffbf18303c0ee25b1d..ac996d581925c8f92832009945c76696 itemstack.setPopTime(this.getPopTime()); if (this.tag != null) { -diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 3e2cd6c7a34c1a792d7346019a8b039d1f4a7c04..6b79f8cd9258af47afa6efa7b1f97c3780be58b0 100644 ---- a/src/main/java/net/minecraft/world/level/Level.java -+++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -1162,8 +1162,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - return list; - } - -- @Override -- public List getEntitiesOfClass(Class entityClass, AABB box, @Nullable Predicate predicate) { -+ public List getEntities(Class oclass, AABB axisalignedbb, @Nullable Predicate predicate) { return getEntitiesOfClass(oclass, axisalignedbb, predicate); } // Paper - OBFHELPER -+ @Override public List getEntitiesOfClass(Class entityClass, AABB box, @Nullable Predicate predicate) { - this.getProfiler().incrementCounter("getEntities"); - int i = Mth.floor((box.minX - 2.0D) / 16.0D); - int j = Mth.ceil((box.maxX + 2.0D) / 16.0D); diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -index 84012c2d12817e657b046bc168cc8eddebcd3831..05fa76c02ce61e26891ad995fe89e925ea086557 100644 +index 8a079ee3ed243fd19b1dd7eed2de1dd33785faa1..c3a07ccccd5cc38552363c82398f432c8d624288 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java -@@ -77,6 +77,7 @@ public abstract class BlockEntity implements net.minecraft.server.KeyedObject { - public void setCurrentChunk(LevelChunk chunk) { - this.currentChunk = chunk != null ? new java.lang.ref.WeakReference<>(chunk) : null; +@@ -63,6 +63,7 @@ public abstract class BlockEntity implements net.minecraft.server.KeyedObject { + getMinecraftKey(); // Try to load if it doesn't exists. + return tileEntityKeyString; } + static boolean IGNORE_TILE_UPDATES = false; // Paper end @Nullable -@@ -155,6 +156,7 @@ public abstract class BlockEntity implements net.minecraft.server.KeyedObject { +@@ -145,6 +146,7 @@ public abstract class BlockEntity implements net.minecraft.server.KeyedObject { public void setChanged() { if (this.level != null) { + if (IGNORE_TILE_UPDATES) return; // Paper - this.blockState = this.level.getBlockState(this.worldPosition); - this.level.blockEntityChanged(this.worldPosition, this); - if (!this.blockState.isAir()) { + BlockEntity.setChanged(this.level, this.worldPosition, this.blockState); + } + diff --git a/src/main/java/net/minecraft/world/level/block/entity/Hopper.java b/src/main/java/net/minecraft/world/level/block/entity/Hopper.java -index f8e4a42bed265822666141683e36e6696694925b..fc8bb72f7d677f65db505016ad6a4cd6146de29f 100644 +index a05acf709735b40ca86f978508c63a86065fd405..c1754df6a60ff93d75a28145b9dc4e9174241a21 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/Hopper.java +++ b/src/main/java/net/minecraft/world/level/block/entity/Hopper.java -@@ -1,6 +1,7 @@ - package net.minecraft.world.level.block.entity; - - import javax.annotation.Nullable; -+import net.minecraft.core.BlockPos; - import net.minecraft.world.Container; - import net.minecraft.world.level.Level; - import net.minecraft.world.level.block.Block; -@@ -17,12 +18,13 @@ public interface Hopper extends Container { - return Hopper.SUCK; +@@ -14,6 +14,10 @@ public interface Hopper extends Container { + return SUCK; } -- @Nullable -+ //@Nullable // Paper - it's annoying - Level getLevel(); -+ default BlockPos getBlockPosition() { return new BlockPos(getX(), getY(), getZ()); } // Paper ++ net.minecraft.world.level.Level getLevel(); ++ ++ default net.minecraft.core.BlockPos getBlockPosition() { return new net.minecraft.core.BlockPos(getLevelX(), getLevelY(), getLevelZ()); } // Paper ++ + double getLevelX(); -- double getLevelX(); -+ double getLevelX(); default double getX() { return this.getLevelX(); } // Paper - OBFHELPER - -- double getLevelY(); -+ double getLevelY(); default double getY() { return this.getLevelY(); } // Paper - OBFHELPER - -- double getLevelZ(); -+ double getLevelZ(); default double getZ() { return this.getLevelZ(); } // Paper - OBFHELPER - } + double getLevelY(); diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java -index 04b0f0de43dfd95e82d402068da8a97bdb86f758..70718fcbaa6f671061479957b7608f7639dab54b 100644 +index 0ec16d554c2b51a64614c73783505c7b06ff02c7..86c0a477883102e4aebdab7ac28bf9f2ab2f7c48 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java -@@ -193,6 +193,160 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen +@@ -3,7 +3,6 @@ package net.minecraft.world.level.block.entity; + import java.util.Iterator; + import java.util.List; + import java.util.function.BooleanSupplier; +-import java.util.stream.Collectors; + import java.util.stream.IntStream; + import javax.annotation.Nullable; + import net.minecraft.core.BlockPos; +@@ -33,7 +32,6 @@ import net.minecraft.world.level.block.state.BlockState; + import net.minecraft.world.phys.AABB; + import net.minecraft.world.phys.shapes.BooleanOp; + import net.minecraft.world.phys.shapes.Shapes; +-import org.bukkit.Bukkit; + import org.bukkit.craftbukkit.entity.CraftHumanEntity; + import org.bukkit.craftbukkit.inventory.CraftItemStack; + import org.bukkit.entity.HumanEntity; +@@ -192,6 +190,159 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen + return false; } - + // Paper start - Optimize Hoppers + private static boolean skipPullModeEventFire = false; + private static boolean skipPushModeEventFire = false; + public static boolean skipHopperEvents = false; + -+ private boolean hopperPush(Container iinventory, Direction enumdirection) { ++ private static boolean hopperPush(Level level, BlockPos pos, Container iinventory, Direction enumdirection, HopperBlockEntity hopper) { + skipPushModeEventFire = skipHopperEvents; + boolean foundItem = false; -+ for (int i = 0; i < this.getContainerSize(); ++i) { -+ ItemStack item = this.getItem(i); ++ for (int i = 0; i < iinventory.getContainerSize(); ++i) { ++ ItemStack item = iinventory.getItem(i); + if (!item.isEmpty()) { + foundItem = true; + ItemStack origItemStack = item; @@ -165,13 +144,13 @@ index 04b0f0de43dfd95e82d402068da8a97bdb86f758..70718fcbaa6f671061479957b7608f76 + // We only need to fire the event once to give protection plugins a chance to cancel this event + // Because nothing uses getItem, every event call should end up the same result. + if (!skipPushModeEventFire) { -+ itemstack = callPushMoveEvent(iinventory, itemstack); ++ itemstack = callPushMoveEvent(iinventory, itemstack, hopper); + if (itemstack == null) { // cancelled + origItemStack.setCount(origCount); + return false; + } + } -+ final ItemStack itemstack2 = addItem(this, iinventory, itemstack, enumdirection); ++ final ItemStack itemstack2 = addItem(hopper, iinventory, itemstack, enumdirection); + final int remaining = itemstack2.getCount(); + if (remaining != moved) { + origItemStack = origItemStack.cloneItemStack(true); @@ -179,7 +158,7 @@ index 04b0f0de43dfd95e82d402068da8a97bdb86f758..70718fcbaa6f671061479957b7608f76 + if (!origItemStack.isEmpty()) { + origItemStack.setCount(origCount - moved + remaining); + } -+ this.setItem(i, origItemStack); ++ hopper.setItem(i, origItemStack); + iinventory.setChanged(); + return true; + } @@ -187,7 +166,7 @@ index 04b0f0de43dfd95e82d402068da8a97bdb86f758..70718fcbaa6f671061479957b7608f76 + } + } + if (foundItem && level.paperConfig.cooldownHopperWhenFull) { // Inventory was full - cooldown -+ this.setCooldown(level.spigotConfig.hopperTransfer); ++ hopper.setCooldown(level.spigotConfig.hopperTransfer); + } + return false; + } @@ -233,16 +212,16 @@ index 04b0f0de43dfd95e82d402068da8a97bdb86f758..70718fcbaa6f671061479957b7608f76 + return false; + } + -+ private ItemStack callPushMoveEvent(Container iinventory, ItemStack itemstack) { ++ private static ItemStack callPushMoveEvent(Container iinventory, ItemStack itemstack, HopperBlockEntity hopper) { + Inventory destinationInventory = getInventory(iinventory); -+ InventoryMoveItemEvent event = new InventoryMoveItemEvent(this.getOwner(false).getInventory(), ++ InventoryMoveItemEvent event = new InventoryMoveItemEvent(hopper.getOwner(false).getInventory(), + CraftItemStack.asCraftMirror(itemstack), destinationInventory, true); + boolean result = event.callEvent(); + if (!event.calledGetItem && !event.calledSetItem) { + skipPushModeEventFire = true; + } + if (!result) { -+ cooldownHopper(this); ++ cooldownHopper(hopper); + return null; + } + @@ -296,58 +275,18 @@ index 04b0f0de43dfd95e82d402068da8a97bdb86f758..70718fcbaa6f671061479957b7608f76 + } + } + // Paper end -+ - private boolean ejectItems() { - Container iinventory = this.getAttachedContainer(); -@@ -204,27 +358,28 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen - if (this.isFullContainer(iinventory, enumdirection)) { + private static boolean a(Level world, BlockPos blockposition, BlockState iblockdata, Container iinventory, HopperBlockEntity hopper) { // CraftBukkit + Container iinventory1 = HopperBlockEntity.getAttachedContainer(world, blockposition, iblockdata); +@@ -204,6 +355,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen + if (HopperBlockEntity.isFullContainer(iinventory1, enumdirection)) { return false; } else { -- for (int i = 0; i < this.getContainerSize(); ++i) { -+ return hopperPush(iinventory, enumdirection); /* // Paper - disable rest -+ for (int i = 0; i < this.getSize(); ++i) { - if (!this.getItem(i).isEmpty()) { -- ItemStack itemstack = this.getItem(i).copy(); -+ ItemStack itemstack = this.getItem(i).cloneItemStack(); - // ItemStack itemstack1 = addItem(this, iinventory, this.splitStack(i, 1), enumdirection); - - // CraftBukkit start - Call event when pushing items into other inventories -- CraftItemStack oitemstack = CraftItemStack.asCraftMirror(this.removeItem(i, level.spigotConfig.hopperAmount)); // Spigot -+ CraftItemStack oitemstack = CraftItemStack.asCraftMirror(this.splitStack(i, world.spigotConfig.hopperAmount)); // Spigot - - Inventory destinationInventory; - // Have to special case large chests as they work oddly -- if (iinventory instanceof CompoundContainer) { -- destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) iinventory); -+ if (iinventory instanceof InventoryLargeChest) { -+ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) iinventory); - } else { - destinationInventory = iinventory.getOwner().getInventory(); - } - - InventoryMoveItemEvent event = new InventoryMoveItemEvent(this.getOwner().getInventory(), oitemstack.clone(), destinationInventory, true); -- this.getLevel().getCraftServer().getPluginManager().callEvent(event); -+ this.getWorld().getServer().getPluginManager().callEvent(event); - if (event.isCancelled()) { - this.setItem(i, itemstack); -- this.setCooldown(level.spigotConfig.hopperTransfer); // Spigot -+ this.setCooldown(world.spigotConfig.hopperTransfer); // Spigot - return false; - } - int origCount = event.getItem().getAmount(); // Spigot -@@ -232,16 +387,16 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen - // CraftBukkit end - - if (itemstack1.isEmpty()) { -- iinventory.setChanged(); -+ iinventory.update(); - return true; - } - -- itemstack.shrink(origCount - itemstack1.getCount()); // Spigot -+ itemstack.subtract(origCount - itemstack1.getCount()); // Spigot - this.setItem(i, itemstack); ++ return hopperPush(world, blockposition, iinventory, enumdirection, hopper); /* // Paper - disable rest + for (int i = 0; i < iinventory.getContainerSize(); ++i) { + if (!iinventory.getItem(i).isEmpty()) { + ItemStack itemstack = iinventory.getItem(i).copy(); +@@ -241,7 +393,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen } } @@ -356,13 +295,25 @@ index 04b0f0de43dfd95e82d402068da8a97bdb86f758..70718fcbaa6f671061479957b7608f76 } } } -@@ -250,18 +405,54 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen - return inventory instanceof WorldlyContainer ? IntStream.of(((WorldlyContainer) inventory).getSlotsForFace(side)) : IntStream.range(0, inventory.getContainerSize()); +@@ -251,27 +403,68 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen } -- private boolean isFullContainer(Container inv, Direction enumdirection) { -- return getSlots(inv, enumdirection).allMatch((i) -> { -- ItemStack itemstack = inv.getItem(i); + private static boolean isFullContainer(Container inventory, Direction direction) { +- return HopperBlockEntity.getSlots(inventory, direction).allMatch((i) -> { +- ItemStack itemstack = inventory.getItem(i); +- +- return itemstack.getCount() >= itemstack.getMaxStackSize(); +- }); ++ return allMatch(inventory, direction, STACK_SIZE_TEST); // Paper - no streams + } + + private static boolean isEmptyContainer(Container inv, Direction facing) { +- return HopperBlockEntity.getSlots(inv, facing).allMatch((i) -> { +- return inv.getItem(i).isEmpty(); +- }); ++ // Paper start ++ return allMatch(inv, facing, IS_EMPTY_TEST); ++ } + private static boolean allMatch(Container iinventory, Direction enumdirection, java.util.function.BiPredicate test) { + if (iinventory instanceof WorldlyContainer) { + for (int i : ((WorldlyContainer) iinventory).getSlotsForFace(enumdirection)) { @@ -379,10 +330,8 @@ index 04b0f0de43dfd95e82d402068da8a97bdb86f758..70718fcbaa6f671061479957b7608f76 + } + } + return true; -+ } + } -- return itemstack.getCount() >= itemstack.getMaxStackSize(); -- }); + private static boolean anyMatch(Container iinventory, Direction enumdirection, java.util.function.BiPredicate test) { + if (iinventory instanceof WorldlyContainer) { + for (int i : ((WorldlyContainer) iinventory).getSlotsForFace(enumdirection)) { @@ -402,111 +351,53 @@ index 04b0f0de43dfd95e82d402068da8a97bdb86f758..70718fcbaa6f671061479957b7608f76 + } + private static final java.util.function.BiPredicate STACK_SIZE_TEST = (itemstack, i) -> itemstack.getCount() >= itemstack.getMaxStackSize(); + private static final java.util.function.BiPredicate IS_EMPTY_TEST = (itemstack, i) -> itemstack.isEmpty(); -+ + // Paper end + -+ private boolean isFullContainer(Container inv, Direction enumdirection) { -+ // Paper start - no streams -+ return allMatch(inv, enumdirection, STACK_SIZE_TEST); -+ // Paper end - } + public static boolean suckInItems(Level world, Hopper hopper) { + Container iinventory = HopperBlockEntity.getSourceContainer(world, hopper); - private static boolean isEmptyContainer(Container inv, Direction facing) { -- return getSlots(inv, facing).allMatch((i) -> { -- return inv.getItem(i).isEmpty(); -- }); -+ return allMatch(inv, facing, IS_EMPTY_TEST); - } - - public static boolean suckInItems(Hopper hopper) { -@@ -270,9 +461,17 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen if (iinventory != null) { Direction enumdirection = Direction.DOWN; -- return isEmptyContainer(iinventory, enumdirection) ? false : getSlots(iinventory, enumdirection).anyMatch((i) -> { -- return tryTakeInItemFromSlot(hopper, iinventory, i, enumdirection); +- return HopperBlockEntity.isEmptyContainer(iinventory, enumdirection) ? false : HopperBlockEntity.getSlots(iinventory, enumdirection).anyMatch((i) -> { +- return HopperBlockEntity.a(hopper, iinventory, i, enumdirection, world); // Spigot + // Paper start - optimize hoppers and remove streams + skipPullModeEventFire = skipHopperEvents; -+ return !isEmptyContainer(iinventory, enumdirection) && anyMatch(iinventory, enumdirection, (item, i) -> { ++ return !HopperBlockEntity.isEmptyContainer(iinventory, enumdirection) && anyMatch(iinventory, enumdirection, (item, i) -> { + // Logic copied from below to avoid extra getItem calls -+ if (!item.isEmpty() && canTakeItem(iinventory, item, i, enumdirection)) { ++ if (!item.isEmpty() && canTakeItemFromContainer(iinventory, item, i, enumdirection)) { + return hopperPull(hopper, iinventory, item, i); + } else { + return false; + } ++ // Paper end }); -+ // Paper end } else { - Iterator iterator = getItemsAtAndAbove(hopper).iterator(); - -@@ -290,47 +489,48 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen + Iterator iterator = HopperBlockEntity.getItemsAtAndAbove(world, hopper).iterator(); +@@ -290,10 +483,12 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen } } -- private static boolean tryTakeInItemFromSlot(Hopper hopper, Container inventory, int slot, Direction side) { -+ private static boolean tryTakeInItemFromSlot(Hopper hopper, Container inventory, int slot, Direction side) {// Paper - method unused as logic is inlined above - ItemStack itemstack = inventory.getItem(slot); ++ // Paper - method unused as logic is inlined above + private static boolean a(Hopper ihopper, Container iinventory, int i, Direction enumdirection, Level world) { // Spigot + ItemStack itemstack = iinventory.getItem(i); -- if (!itemstack.isEmpty() && canTakeItemFromContainer(inventory, itemstack, slot, side)) { -- ItemStack itemstack1 = itemstack.copy(); -+ if (!itemstack.isEmpty() && canTakeItemFromContainer(inventory, itemstack, slot, side)) { // If this logic changes, update above. this is left inused incase reflective plugins -+ return hopperPull(hopper, inventory, itemstack, slot); /* // Paper - disable rest -+ ItemStack itemstack1 = itemstack.cloneItemStack(); +- if (!itemstack.isEmpty() && HopperBlockEntity.canTakeItemFromContainer(iinventory, itemstack, i, enumdirection)) { ++ if (!itemstack.isEmpty() && HopperBlockEntity.canTakeItemFromContainer(iinventory, itemstack, i, enumdirection)) { // If this logic changes, update above. this is left inused incase reflective plugins ++ return hopperPull(ihopper, iinventory, itemstack, i); /* // Paper - disable rest + ItemStack itemstack1 = itemstack.copy(); // ItemStack itemstack2 = addItem(iinventory, ihopper, iinventory.splitStack(i, 1), (EnumDirection) null); // CraftBukkit start - Call event on collection of items from inventories into the hopper -- CraftItemStack oitemstack = CraftItemStack.asCraftMirror(inventory.removeItem(slot, hopper.getLevel().spigotConfig.hopperAmount)); // Spigot -+ CraftItemStack oitemstack = CraftItemStack.asCraftMirror(iinventory.splitStack(i, ihopper.getWorld().spigotConfig.hopperAmount)); // Spigot - - Inventory sourceInventory; - // Have to special case large chests as they work oddly -- if (inventory instanceof CompoundContainer) { -- sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) inventory); -+ if (iinventory instanceof InventoryLargeChest) { -+ sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) iinventory); - } else { -- sourceInventory = inventory.getOwner().getInventory(); -+ sourceInventory = iinventory.getOwner().getInventory(); +@@ -330,7 +525,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen } -- InventoryMoveItemEvent event = new InventoryMoveItemEvent(sourceInventory, oitemstack.clone(), hopper.getOwner().getInventory(), false); -+ InventoryMoveItemEvent event = new InventoryMoveItemEvent(sourceInventory, oitemstack.clone(), ihopper.getOwner().getInventory(), false); - -- hopper.getLevel().getCraftServer().getPluginManager().callEvent(event); -+ ihopper.getWorld().getServer().getPluginManager().callEvent(event); - if (event.isCancelled()) { -- inventory.setItem(slot, itemstack1); -+ iinventory.setItem(i, itemstack1); - -- if (hopper instanceof HopperBlockEntity) { -- ((HopperBlockEntity) hopper).setCooldown(hopper.getLevel().spigotConfig.hopperTransfer); // Spigot -- } else if (hopper instanceof MinecartHopper) { -- ((MinecartHopper) hopper).setCooldown(hopper.getLevel().spigotConfig.hopperTransfer / 2); // Spigot -+ if (ihopper instanceof TileEntityHopper) { -+ ((TileEntityHopper) ihopper).setCooldown(ihopper.getWorld().spigotConfig.hopperTransfer); // Spigot -+ } else if (ihopper instanceof EntityMinecartHopper) { -+ ((EntityMinecartHopper) ihopper).setCooldown(ihopper.getWorld().spigotConfig.hopperTransfer / 2); // Spigot - } - return false; - } - int origCount = event.getItem().getAmount(); // Spigot -- ItemStack itemstack2 = addItem(inventory, hopper, CraftItemStack.asNMSCopy(event.getItem()), null); -+ ItemStack itemstack2 = addItem(iinventory, ihopper, CraftItemStack.asNMSCopy(event.getItem()), null); - // CraftBukkit end - - if (itemstack2.isEmpty()) { -- inventory.setChanged(); -+ iinventory.update(); - return true; - } - -- itemstack1.shrink(origCount - itemstack2.getCount()); // Spigot -- inventory.setItem(slot, itemstack1); -+ itemstack1.subtract(origCount - itemstack2.getCount()); // Spigot + itemstack1.shrink(origCount - itemstack2.getCount()); // Spigot +- iinventory.setItem(i, itemstack1); + iinventory.setItem(i, itemstack1);*/ // Paper - end commenting out replaced block for Hopper Optimizations } return false; -@@ -339,7 +539,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen +@@ -339,7 +534,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen public static boolean addItem(Container inventory, ItemEntity itemEntity) { boolean flag = false; // CraftBukkit start @@ -515,15 +406,7 @@ index 04b0f0de43dfd95e82d402068da8a97bdb86f758..70718fcbaa6f671061479957b7608f76 itemEntity.level.getCraftServer().getPluginManager().callEvent(event); if (event.isCancelled()) { return false; -@@ -381,6 +581,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen - return !inventory.canPlaceItem(slot, stack) ? false : !(inventory instanceof WorldlyContainer) || ((WorldlyContainer) inventory).canPlaceItemThroughFace(slot, stack, side); - } - -+ private static boolean canTakeItem(Container iinventory, ItemStack itemstack, int i, Direction enumdirection) { return canTakeItemFromContainer(iinventory, itemstack, i, enumdirection); } // Paper - OBFHELPER - private static boolean canTakeItemFromContainer(Container inv, ItemStack stack, int slot, Direction facing) { - return !(inv instanceof WorldlyContainer) || ((WorldlyContainer) inv).canTakeItemThroughFace(slot, stack, facing); - } -@@ -393,7 +594,9 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen +@@ -393,7 +588,9 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen boolean flag1 = to.isEmpty(); if (itemstack1.isEmpty()) { @@ -532,59 +415,53 @@ index 04b0f0de43dfd95e82d402068da8a97bdb86f758..70718fcbaa6f671061479957b7608f76 + IGNORE_TILE_UPDATES = false; // Paper stack = ItemStack.EMPTY; flag = true; - } else if (canMergeItems(itemstack1, stack)) { -@@ -444,20 +647,26 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen + } else if (HopperBlockEntity.canMergeItems(itemstack1, stack)) { +@@ -444,18 +641,23 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen } - public static List getItemsAtAndAbove(Hopper ihopper) { -- return (List) ihopper.getSuckShape().toAabbs().stream().flatMap((axisalignedbb) -> { -- return ihopper.getLevel().getEntitiesOfClass(ItemEntity.class, axisalignedbb.move(ihopper.getLevelX() - 0.5D, ihopper.getLevelY() - 0.5D, ihopper.getLevelZ() - 0.5D), EntitySelector.ENTITY_STILL_ALIVE).stream(); + public static List getItemsAtAndAbove(Level world, Hopper hopper) { +- return (List) hopper.getSuckShape().toAabbs().stream().flatMap((axisalignedbb) -> { +- return world.getEntitiesOfClass(ItemEntity.class, axisalignedbb.move(hopper.getLevelX() - 0.5D, hopper.getLevelY() - 0.5D, hopper.getLevelZ() - 0.5D), EntitySelector.ENTITY_STILL_ALIVE).stream(); - }).collect(Collectors.toList()); + // Paper start - Optimize item suck in. remove streams, restore 1.12 checks. Seriously checking the bowl?! -+ Level world = ihopper.getLevel(); -+ double d0 = ihopper.getX(); -+ double d1 = ihopper.getY(); -+ double d2 = ihopper.getZ(); ++ double d0 = hopper.getLevelX(); ++ double d1 = hopper.getLevelY(); ++ double d2 = hopper.getLevelZ(); + AABB bb = new AABB(d0 - 0.5D, d1, d2 - 0.5D, d0 + 0.5D, d1 + 1.5D, d2 + 0.5D); -+ return world.getEntities(ItemEntity.class, bb, Entity::isAlive); ++ return world.getEntitiesOfClass(ItemEntity.class, bb, Entity::isAlive); + // Paper end } @Nullable - public static Container getContainerAt(Level world, BlockPos blockposition) { -- return getContainerAt(world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D); -+ return a(world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, true); // Paper + public static Container getContainerAt(Level world, BlockPos pos) { +- return HopperBlockEntity.getContainerAt(world, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D); ++ return HopperBlockEntity.getContainerAt(world, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, true); // Paper } ++ public static Container getContainerAt(Level world, double x, double y, double z) { return getContainerAt(world, x, y, z, false); } // Paper - overload to default false @Nullable -- public static Container getContainerAt(Level world, double x, double y, double z) { -+ public static Container getContainerAt(Level world, double x, double y, double z) { return a(world, x, y, z, false); } // Paper - overload to default false -+ public static Container a(Level world, double d0, double d1, double d2, boolean optimizeEntities) { // Paper +- private static Container getContainerAt(Level world, double x, double y, double z) { ++ private static Container getContainerAt(Level world, double x, double y, double z, boolean optimizeEntities) { Object object = null; -- BlockPos blockposition = new BlockPos(x, y, z); -+ BlockPos blockposition = new BlockPos(d0, d1, d2); + BlockPos blockposition = new BlockPos(x, y, z); if ( !world.hasChunkAt( blockposition ) ) return null; // Spigot - BlockState iblockdata = world.getBlockState(blockposition); - Block block = iblockdata.getBlock(); -@@ -475,8 +684,8 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen +@@ -475,7 +677,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen } } - if (object == null) { -- List list = world.getEntities((Entity) null, new AABB(x - 0.5D, y - 0.5D, z - 0.5D, x + 0.5D, y + 0.5D, z + 0.5D), EntitySelector.CONTAINER_ENTITY_SELECTOR); + if (object == null && (!optimizeEntities || !org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(block).isOccluding())) { // Paper -+ List list = world.getEntities((Entity) null, new AABB(d0 - 0.5D, d1 - 0.5D, d2 - 0.5D, d0 + 0.5D, d1 + 0.5D, d2 + 0.5D), EntitySelector.CONTAINER_ENTITY_SELECTOR); + List list = world.getEntities((Entity) null, new AABB(x - 0.5D, y - 0.5D, z - 0.5D, x + 0.5D, y + 0.5D, z + 0.5D), EntitySelector.CONTAINER_ENTITY_SELECTOR); if (!list.isEmpty()) { - object = (Container) list.get(world.random.nextInt(list.size())); diff --git a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java -index 5ad419941ff1113ef29b9a4593f44d8f35ba8424..4525032232b5a89de13c6a46dc489a07428e3f21 100644 +index f23fff80d07ac7d06715efe67cb49ebbe704967b..ed3518fe7c841d9e1a9c97626acaa3d765a6d76f 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java -@@ -97,12 +97,19 @@ public abstract class RandomizableContainerBlockEntity extends BaseContainerBloc +@@ -95,12 +95,19 @@ public abstract class RandomizableContainerBlockEntity extends BaseContainerBloc @Override public boolean isEmpty() { - this.unpackLootTable((Player) null); + this.unpackLootTable((Player)null); - return this.getItems().stream().allMatch(ItemStack::isEmpty); + // Paper start + for (ItemStack itemStack : this.getItems()) { @@ -598,8 +475,8 @@ index 5ad419941ff1113ef29b9a4593f44d8f35ba8424..4525032232b5a89de13c6a46dc489a07 @Override public ItemStack getItem(int slot) { -- this.unpackLootTable((Player) null); +- this.unpackLootTable((Player)null); + if (slot == 0) this.unpackLootTable((Player) null); // Paper - return (ItemStack) this.getItems().get(slot); + return this.getItems().get(slot); } diff --git a/patches/server-remapped/0391-PlayerDeathEvent-shouldDropExperience.patch b/patches/server/0348-PlayerDeathEvent-shouldDropExperience.patch similarity index 79% rename from patches/server-remapped/0391-PlayerDeathEvent-shouldDropExperience.patch rename to patches/server/0348-PlayerDeathEvent-shouldDropExperience.patch index 4f453dc68..40e04c2c4 100644 --- a/patches/server-remapped/0391-PlayerDeathEvent-shouldDropExperience.patch +++ b/patches/server/0348-PlayerDeathEvent-shouldDropExperience.patch @@ -5,10 +5,10 @@ Subject: [PATCH] PlayerDeathEvent#shouldDropExperience diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 2ef273e3b917803f3e2ac3c6a22d92a15b9eb71a..7f4e81ee3339e90b8525541dccf6dea187853cf7 100644 +index 8da35a7dde494b059e542d049d7ee039deb5833d..4fef4c0240be90ddcb9640f5719e292d2d5dbdf8 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -819,7 +819,7 @@ public class ServerPlayer extends Player implements ContainerListener { +@@ -849,7 +849,7 @@ public class ServerPlayer extends Player { this.tellNeutralMobsThatIDied(); } // SPIGOT-5478 must be called manually now @@ -16,4 +16,4 @@ index 2ef273e3b917803f3e2ac3c6a22d92a15b9eb71a..7f4e81ee3339e90b8525541dccf6dea1 + if (event.shouldDropExperience()) this.dropExperience(); // Paper - tie to event // we clean the player's inventory after the EntityDeathEvent is called so plugins can get the exact state of the inventory. if (!event.getKeepInventory()) { - // Paper start - replace logic + this.getInventory().clearContent(); diff --git a/patches/server-remapped/0392-Prevent-bees-loading-chunks-checking-hive-position.patch b/patches/server/0349-Prevent-bees-loading-chunks-checking-hive-position.patch similarity index 85% rename from patches/server-remapped/0392-Prevent-bees-loading-chunks-checking-hive-position.patch rename to patches/server/0349-Prevent-bees-loading-chunks-checking-hive-position.patch index 9a427d5aa..6c74d7945 100644 --- a/patches/server-remapped/0392-Prevent-bees-loading-chunks-checking-hive-position.patch +++ b/patches/server/0349-Prevent-bees-loading-chunks-checking-hive-position.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Prevent bees loading chunks checking hive position diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java -index 32ee38142a3053091ab7b3fb3d608d268b07d4e3..edd6d63f715acef1a77eba0cf46ff8267228f4c6 100644 +index 488dd4693dbbc303f0fc6d98667b822304b06c9f..f3ba4b26553915917c79f013ed9dd7c87d9f65a4 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Bee.java +++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java -@@ -442,6 +442,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -495,6 +495,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { if (!this.hasHive()) { return false; } else { diff --git a/patches/server-remapped/0393-Don-t-load-Chunks-from-Hoppers-and-other-things.patch b/patches/server/0350-Don-t-load-Chunks-from-Hoppers-and-other-things.patch similarity index 58% rename from patches/server-remapped/0393-Don-t-load-Chunks-from-Hoppers-and-other-things.patch rename to patches/server/0350-Don-t-load-Chunks-from-Hoppers-and-other-things.patch index f6952f625..d646992d7 100644 --- a/patches/server-remapped/0393-Don-t-load-Chunks-from-Hoppers-and-other-things.patch +++ b/patches/server/0350-Don-t-load-Chunks-from-Hoppers-and-other-things.patch @@ -13,20 +13,20 @@ This of course is undesirable, so just return the loaded side as "primary" and treat it as a single chest if the other sides are unloaded diff --git a/src/main/java/net/minecraft/world/level/block/DoubleBlockCombiner.java b/src/main/java/net/minecraft/world/level/block/DoubleBlockCombiner.java -index a4f16b2093c867e9fd1c2e07b67c49c3c5ec7506..df20b3616929657d2e8061159ed97f500b33d192 100644 +index ff2a7b08fe70adaecdaa508baadcfe40416519e0..7082bb0b28b6a046e3925f69e18b7c319871128f 100644 --- a/src/main/java/net/minecraft/world/level/block/DoubleBlockCombiner.java +++ b/src/main/java/net/minecraft/world/level/block/DoubleBlockCombiner.java -@@ -29,7 +29,12 @@ public class DoubleBlockCombiner { - return new DoubleBlockCombiner.NeighborCombineResult.Single<>(s0); +@@ -25,7 +25,12 @@ public class DoubleBlockCombiner { + return new DoubleBlockCombiner.NeighborCombineResult.Single<>(blockEntity); } else { - BlockPos blockposition1 = pos.relative((Direction) function1.apply(state)); -- BlockState iblockdata1 = world.getBlockState(blockposition1); + BlockPos blockPos = pos.relative(function.apply(state)); +- BlockState blockState = world.getBlockState(blockPos); + // Paper start -+ BlockState iblockdata1 = world.getTypeIfLoaded(blockposition1); -+ if (iblockdata1 == null) { -+ return new DoubleBlockCombiner.NeighborCombineResult.Single<>(s0); ++ BlockState blockState = world.getTypeIfLoaded(blockPos); ++ if (blockState == null) { ++ return new DoubleBlockCombiner.NeighborCombineResult.Single<>(blockEntity); + } + // Paper end - - if (iblockdata1.is(state.getBlock())) { - DoubleBlockCombiner.BlockType doubleblockfinder_blocktype1 = (DoubleBlockCombiner.BlockType) typeMapper.apply(iblockdata1); + if (blockState.is(state.getBlock())) { + DoubleBlockCombiner.BlockType blockType2 = typeMapper.apply(blockState); + if (blockType2 != DoubleBlockCombiner.BlockType.SINGLE && blockType != blockType2 && blockState.getValue(directionProperty) == state.getValue(directionProperty)) { diff --git a/patches/server/0351-Guard-against-serializing-mismatching-chunk-coordina.patch b/patches/server/0351-Guard-against-serializing-mismatching-chunk-coordina.patch new file mode 100644 index 000000000..5d846e842 --- /dev/null +++ b/patches/server/0351-Guard-against-serializing-mismatching-chunk-coordina.patch @@ -0,0 +1,54 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Fri, 27 Dec 2019 09:42:26 -0800 +Subject: [PATCH] Guard against serializing mismatching chunk coordinate + +Should help if something dumb happens + +diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java +index 3cb35f2f47ba841915ac2825d30cc4c3274ce3c4..7c04aef3eac54981ca1e34cb87d97104c3c9685b 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java ++++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java +@@ -69,6 +69,13 @@ public class ChunkSerializer { + + public ChunkSerializer() {} + ++ // Paper start - guard against serializing mismatching coordinates ++ // TODO Note: This needs to be re-checked each update ++ public static ChunkPos getChunkCoordinate(CompoundTag chunkData) { ++ CompoundTag levelData = chunkData.getCompound("Level"); ++ return new ChunkPos(levelData.getInt("xPos"), levelData.getInt("zPos")); ++ } ++ // Paper end + // Paper start + public static final class InProgressChunkHolder { + +@@ -95,8 +102,8 @@ public class ChunkSerializer { + // Paper end + ChunkGenerator chunkgenerator = world.getChunkSource().getGenerator(); + BiomeSource worldchunkmanager = chunkgenerator.getBiomeSource(); +- CompoundTag nbttagcompound1 = nbt.getCompound("Level"); +- ChunkPos chunkcoordintpair1 = new ChunkPos(nbttagcompound1.getInt("xPos"), nbttagcompound1.getInt("zPos")); ++ CompoundTag nbttagcompound1 = nbt.getCompound("Level"); // Paper - diff on change, see ChunkSerializer#getChunkCoordinate ++ ChunkPos chunkcoordintpair1 = new ChunkPos(nbttagcompound1.getInt("xPos"), nbttagcompound1.getInt("zPos")); // Paper - diff on change, see ChunkSerializer#getChunkCoordinate + + if (!Objects.equals(pos, chunkcoordintpair1)) { + ChunkSerializer.LOGGER.error("Chunk file at {} is in the wrong location; relocating. (Expected {}, got {})", pos, pos, chunkcoordintpair1); +diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java +index 6f13c7adce7d4b3d170045ea5ef2a841d34ae7b0..176610b31f66b890afe61f4de46c412382bb8d22 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java ++++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java +@@ -117,6 +117,13 @@ public class ChunkStorage implements AutoCloseable { + + // Paper start - async chunk io + public void write(ChunkPos chunkPos, CompoundTag nbt) throws IOException { ++ // Paper start ++ if (!chunkPos.equals(ChunkSerializer.getChunkCoordinate(nbt))) { ++ String world = (this instanceof net.minecraft.server.level.ChunkMap) ? ((net.minecraft.server.level.ChunkMap)this).level.getWorld().getName() : null; ++ throw new IllegalArgumentException("Chunk coordinate and serialized data do not have matching coordinates, trying to serialize coordinate " + chunkPos.toString() ++ + " but compound says coordinate is " + ChunkSerializer.getChunkCoordinate(nbt).toString() + (world == null ? " for an unknown world" : (" for world: " + world))); ++ } ++ // Paper end + this.regionFileCache.write(chunkPos, nbt); + // Paper end - Async chunk loading + if (this.legacyStructureHandler != null) { diff --git a/patches/server-remapped/0395-Optimise-IEntityAccess-getPlayerByUUID.patch b/patches/server/0352-Optimise-IEntityAccess-getPlayerByUUID.patch similarity index 51% rename from patches/server-remapped/0395-Optimise-IEntityAccess-getPlayerByUUID.patch rename to patches/server/0352-Optimise-IEntityAccess-getPlayerByUUID.patch index e478c7d03..7ec891558 100644 --- a/patches/server-remapped/0395-Optimise-IEntityAccess-getPlayerByUUID.patch +++ b/patches/server/0352-Optimise-IEntityAccess-getPlayerByUUID.patch @@ -6,39 +6,21 @@ Subject: [PATCH] Optimise IEntityAccess#getPlayerByUUID Use the world entity map instead of iterating over all players diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 01f879a8dd0e1ffec380e02072567330152eaceb..40d7dbc4f1deda88d4a539b89d84b595217051b6 100644 +index 736521c0925339dc74c2648641932104a947708e..eabf8fa6e8802ebea8dbe124363bb085849af5d9 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -283,6 +283,15 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl - } +@@ -281,6 +281,14 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl + public final com.destroystokyo.paper.io.chunk.ChunkTaskManager asyncChunkTaskManager; // Paper end + // Paper start - optimise getPlayerByUUID + @Nullable + @Override + public Player getPlayerByUUID(UUID uuid) { -+ Entity player = this.entitiesByUuid.get(uuid); -+ return (player instanceof Player) ? (Player)player : null; ++ return this.getServer().getPlayerList().getPlayer(uuid); + } + // Paper end + // Add env and gen to constructor, WorldData -> WorldDataServer public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, ServerLevelData iworlddataserver, ResourceKey resourcekey, DimensionType dimensionmanager, ChunkProgressListener worldloadlistener, ChunkGenerator chunkgenerator, boolean flag, long i, List list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) { - super(iworlddataserver, resourcekey, dimensionmanager, minecraftserver::getProfiler, false, flag, i, gen, env, executor); // Paper pass executor -diff --git a/src/main/java/net/minecraft/world/level/EntityGetter.java b/src/main/java/net/minecraft/world/level/EntityGetter.java -index 6a5430fe54a5c8ad119a0f3842961825a54d8d7a..b9606465ace8b320eafbbad3d60c01b87a859c44 100644 ---- a/src/main/java/net/minecraft/world/level/EntityGetter.java -+++ b/src/main/java/net/minecraft/world/level/EntityGetter.java -@@ -277,6 +277,12 @@ public interface EntityGetter { - - @Nullable - default Player getPlayerByUUID(UUID uuid) { -+ // Paper start - allow WorldServer to override -+ return this.getPlayerByUUID(uuid); -+ } -+ @Nullable -+ default Player getPlayerByUUID(UUID uuid) { -+ // Paper end - for (int i = 0; i < this.players().size(); ++i) { - Player entityhuman = (Player) this.players().get(i); - + // Objects.requireNonNull(minecraftserver); // CraftBukkit - decompile error diff --git a/patches/server-remapped/0396-Fix-items-not-falling-correctly.patch b/patches/server/0353-Fix-items-not-falling-correctly.patch similarity index 66% rename from patches/server-remapped/0396-Fix-items-not-falling-correctly.patch rename to patches/server/0353-Fix-items-not-falling-correctly.patch index f1ecdfe62..8eba5c8d5 100644 --- a/patches/server-remapped/0396-Fix-items-not-falling-correctly.patch +++ b/patches/server/0353-Fix-items-not-falling-correctly.patch @@ -15,15 +15,15 @@ This patch resolves the conflict by offsetting checking an item's move method from Spigot's entity activation range check. diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index 96b8102773cbee2c3fe2711008ba1487084d67b0..9311f9f411d09d4460f0be8235957fab9e195b7a 100644 +index 82ffe3624943d2e931e2cc2f85ede94f369bd06b..9ee1dc89dd4c6b9453e1f6f92208d454877d23c9 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -@@ -115,7 +115,7 @@ public class ItemEntity extends Entity { +@@ -135,7 +135,7 @@ public class ItemEntity extends Entity { } } -- if (!this.onGround || getHorizontalDistanceSqr(this.getDeltaMovement()) > 9.999999747378752E-6D || (this.tickCount + this.getId()) % 4 == 0) { -+ if (!this.onGround || getHorizontalDistanceSqr(this.getDeltaMovement()) > 9.999999747378752E-6D || this.tickCount % 4 == 0) { // Paper - Ensure checking item movement is always offset from Spigot's entity activation range check +- if (!this.onGround || this.getDeltaMovement().horizontalDistanceSqr() > 9.999999747378752E-6D || (this.tickCount + this.getId()) % 4 == 0) { ++ if (!this.onGround || this.getDeltaMovement().horizontalDistanceSqr() > 9.999999747378752E-6D || this.tickCount % 4 == 0) { // Paper - Ensure checking item movement is always offset from Spigot's entity activation range check this.move(MoverType.SELF, this.getDeltaMovement()); float f1 = 0.98F; diff --git a/patches/server-remapped/0397-Lag-compensate-eating.patch b/patches/server/0354-Lag-compensate-eating.patch similarity index 57% rename from patches/server-remapped/0397-Lag-compensate-eating.patch rename to patches/server/0354-Lag-compensate-eating.patch index cc90ba965..9941db915 100644 --- a/patches/server-remapped/0397-Lag-compensate-eating.patch +++ b/patches/server/0354-Lag-compensate-eating.patch @@ -7,19 +7,10 @@ When the server is lagging, players will wait longer when eating. Change to also use a time check instead if it passes. diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index b49d4772932a58852b3195f5f56ff93dbcabf766..016fcc4ae20e1e48728a848be28633e624ae49a7 100644 +index 5def2e0379373b126a1b2281b0859b39443fc4ac..f48435dc344fb48feb48e2a141b394829058c5c4 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -211,7 +211,7 @@ public abstract class LivingEntity extends Entity { - private int noJumpDelay; - private float absorptionAmount; - public ItemStack useItem; // Paper - public -- protected int useItemRemaining; -+ protected int useItemRemaining; protected final int getEatTimeTicks() { return this.useItemRemaining; } protected final void setEatTimeTicks(int value) { this.useItemRemaining = value; } // Paper - OBFHELPER - protected int fallFlyTicks; - private BlockPos lastPos; - private Optional lastClimbablePos; -@@ -3148,6 +3148,11 @@ public abstract class LivingEntity extends Entity { +@@ -3492,6 +3492,11 @@ public abstract class LivingEntity extends Entity { return ((Byte) this.entityData.get(LivingEntity.DATA_LIVING_ENTITY_FLAGS) & 2) > 0 ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND; } @@ -31,21 +22,22 @@ index b49d4772932a58852b3195f5f56ff93dbcabf766..016fcc4ae20e1e48728a848be28633e6 private void updatingUsingItem() { if (this.isUsingItem()) { if (ItemStack.isSameIgnoreDurability(this.getItemInHand(this.getUsedItemHand()), this.useItem)) { -@@ -3157,7 +3162,12 @@ public abstract class LivingEntity extends Entity { - this.triggerItemUseEffects(this.useItem, 5); - } +@@ -3509,8 +3514,12 @@ public abstract class LivingEntity extends Entity { + if (this.shouldTriggerItemUseEffects()) { + this.triggerItemUseEffects(stack, 5); + } +- +- if (--this.useItemRemaining == 0 && !this.level.isClientSide && !stack.useOnRelease()) { ++ // Paper start - lag compensate eating ++ // we add 1 to the expected time to avoid lag compensating when we should not ++ boolean shouldLagCompensate = this.useItem.getItem().isEdible() && this.eatStartTime != -1 && (System.nanoTime() - this.eatStartTime) > ((1 + this.totalEatTimeTicks) * 50 * (1000 * 1000)); ++ if ((--this.useItemRemaining == 0 || shouldLagCompensate) && !this.level.isClientSide && !this.useItem.useOnRelease()) { ++ this.useItemRemaining = 0; ++ // Paper end + this.completeUsingItem(); + } -- if (--this.useItemRemaining == 0 && !this.level.isClientSide && !this.useItem.useOnRelease()) { -+ // Paper start - lag compensate eating -+ // we add 1 to the expected time to avoid lag compensating when we should not -+ boolean shouldLagCompensate = this.useItem.getItem().isEdible() && this.eatStartTime != -1 && (System.nanoTime() - this.eatStartTime) > ((1 + this.totalEatTimeTicks) * 50 * (1000 * 1000)); -+ if ((--this.useItemRemaining == 0 || shouldLagCompensate) && !this.level.isClientSide && !this.useItem.useOnRelease()) { -+ this.setEatTimeTicks(0); -+ // Paper end - this.completeUsingItem(); - } - } else { -@@ -3207,7 +3217,10 @@ public abstract class LivingEntity extends Entity { +@@ -3556,7 +3565,10 @@ public abstract class LivingEntity extends Entity { if (!itemstack.isEmpty() && !this.isUsingItem() || forceUpdate) { // Paper use override flag this.useItem = itemstack; @@ -57,7 +49,7 @@ index b49d4772932a58852b3195f5f56ff93dbcabf766..016fcc4ae20e1e48728a848be28633e6 if (!this.level.isClientSide) { this.setLivingEntityFlag(1, true); this.setLivingEntityFlag(2, enumhand == InteractionHand.OFF_HAND); -@@ -3231,7 +3244,10 @@ public abstract class LivingEntity extends Entity { +@@ -3580,7 +3592,10 @@ public abstract class LivingEntity extends Entity { } } else if (!this.isUsingItem() && !this.useItem.isEmpty()) { this.useItem = ItemStack.EMPTY; @@ -69,7 +61,7 @@ index b49d4772932a58852b3195f5f56ff93dbcabf766..016fcc4ae20e1e48728a848be28633e6 } } -@@ -3359,7 +3375,10 @@ public abstract class LivingEntity extends Entity { +@@ -3706,7 +3721,10 @@ public abstract class LivingEntity extends Entity { } this.useItem = ItemStack.EMPTY; diff --git a/patches/server-remapped/0398-Optimize-call-to-getFluid-for-explosions.patch b/patches/server/0355-Optimize-call-to-getFluid-for-explosions.patch similarity index 72% rename from patches/server-remapped/0398-Optimize-call-to-getFluid-for-explosions.patch rename to patches/server/0355-Optimize-call-to-getFluid-for-explosions.patch index 9e3f2b347..43ce56104 100644 --- a/patches/server-remapped/0398-Optimize-call-to-getFluid-for-explosions.patch +++ b/patches/server/0355-Optimize-call-to-getFluid-for-explosions.patch @@ -5,15 +5,15 @@ Subject: [PATCH] Optimize call to getFluid for explosions diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java -index 45a75f7be308678336e192828becf6cf5c9047bc..667a6d645034c67639c01b8221591877bcb87b35 100644 +index edc0845ae735a9cf3e0f1a3a2b7eabf726d62744..cdf214fca3b0055efa56702470d9d2f890a8aead 100644 --- a/src/main/java/net/minecraft/world/level/Explosion.java +++ b/src/main/java/net/minecraft/world/level/Explosion.java -@@ -151,7 +151,7 @@ public class Explosion { +@@ -174,7 +174,7 @@ public class Explosion { for (float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) { BlockPos blockposition = new BlockPos(d4, d5, d6); BlockState iblockdata = this.level.getBlockState(blockposition); - FluidState fluid = this.level.getFluidState(blockposition); + FluidState fluid = iblockdata.getFluidState(); // Paper - Optional optional = this.damageCalculator.a(this, this.level, blockposition, iblockdata, fluid); - if (optional.isPresent()) { + if (!this.level.isInWorldBounds(blockposition)) { + break; diff --git a/patches/server-remapped/0399-Fix-last-firework-in-stack-not-having-effects-when-d.patch b/patches/server/0356-Fix-last-firework-in-stack-not-having-effects-when-d.patch similarity index 90% rename from patches/server-remapped/0399-Fix-last-firework-in-stack-not-having-effects-when-d.patch rename to patches/server/0356-Fix-last-firework-in-stack-not-having-effects-when-d.patch index 63271d423..fbe63db8c 100644 --- a/patches/server-remapped/0399-Fix-last-firework-in-stack-not-having-effects-when-d.patch +++ b/patches/server/0356-Fix-last-firework-in-stack-not-having-effects-when-d.patch @@ -9,10 +9,10 @@ dispensed. The resulting item would have size == 0 and therefore be convertered to air, hence why the effects disappeared. diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -index 67a894a185a3d4a53b3c7f90174b2604dff18257..67d140dff483bfc654a0390e0cdcd13aa658a62d 100644 +index b665d4293b746b221d469a7b029c1c7f17df6188..92623ae25249d63efb92be8bd6c95228f9155ad2 100644 --- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -@@ -425,7 +425,7 @@ public interface DispenseItemBehavior { +@@ -431,7 +431,7 @@ public interface DispenseItemBehavior { } itemstack1 = CraftItemStack.asNMSCopy(event.getItem()); diff --git a/patches/server-remapped/0400-Add-effect-to-block-break-naturally.patch b/patches/server/0357-Add-effect-to-block-break-naturally.patch similarity index 81% rename from patches/server-remapped/0400-Add-effect-to-block-break-naturally.patch rename to patches/server/0357-Add-effect-to-block-break-naturally.patch index e51ec69f4..f0c758d80 100644 --- a/patches/server-remapped/0400-Add-effect-to-block-break-naturally.patch +++ b/patches/server/0357-Add-effect-to-block-break-naturally.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add effect to block break naturally diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -index 5bff313dbbb3049105874846d995883e827fbc00..05f0833f762436bf8f5f5875c7e3cfed1da11e1c 100644 +index 0a9ed9992a2fc97472a06591a5d129a767ce21af..ca95a6b1b156b37f839c6479733e5184691af66c 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -@@ -630,6 +630,13 @@ public class CraftBlock implements Block { +@@ -632,6 +632,13 @@ public class CraftBlock implements Block { @Override public boolean breakNaturally(ItemStack item) { @@ -22,10 +22,10 @@ index 5bff313dbbb3049105874846d995883e827fbc00..05f0833f762436bf8f5f5875c7e3cfed // Order matters here, need to drop before setting to air so skulls can get their data net.minecraft.world.level.block.state.BlockState iblockdata = this.getNMS(); net.minecraft.world.level.block.Block block = iblockdata.getBlock(); -@@ -639,6 +646,7 @@ public class CraftBlock implements Block { +@@ -641,6 +648,7 @@ public class CraftBlock implements Block { // Modelled off EntityHuman#hasBlock if (block != Blocks.AIR && (item == null || !iblockdata.requiresCorrectToolForDrops() || nmsItem.isCorrectToolForDrops(iblockdata))) { - net.minecraft.world.level.block.Block.dropResources(iblockdata, world.getLevel(), position, world.getBlockEntity(position), null, nmsItem); + net.minecraft.world.level.block.Block.dropResources(iblockdata, this.world.getMinecraftWorld(), position, this.world.getBlockEntity(position), null, nmsItem); + if (triggerEffect) world.levelEvent(org.bukkit.Effect.STEP_SOUND.getId(), position, net.minecraft.world.level.block.Block.getId(block.defaultBlockState())); // Paper result = true; } diff --git a/patches/server-remapped/0402-Entity-Activation-Range-2.0.patch b/patches/server/0358-Entity-Activation-Range-2.0.patch similarity index 58% rename from patches/server-remapped/0402-Entity-Activation-Range-2.0.patch rename to patches/server/0358-Entity-Activation-Range-2.0.patch index ad4d82992..35cc61b42 100644 --- a/patches/server-remapped/0402-Entity-Activation-Range-2.0.patch +++ b/patches/server/0358-Entity-Activation-Range-2.0.patch @@ -14,111 +14,120 @@ Adds flying monsters to control ghast and phantoms Adds villagers as separate config diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 40d7dbc4f1deda88d4a539b89d84b595217051b6..bf1bb1530037ebcacc8d5a491789909bddb8b697 100644 +index eabf8fa6e8802ebea8dbe124363bb085849af5d9..67b9daee8d7e55fdf2015e6616f393f176b1ca96 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -855,17 +855,17 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl - ++TimingHistory.entityTicks; // Paper - timings - // Spigot start - co.aikar.timings.Timing timer; // Paper -- if (!org.spigotmc.ActivationRange.checkIfActive(entity)) { -- entity.tickCount++; -- timer = entity.getType().inactiveTickTimer.startTiming(); try { // Paper - timings -+ /*if (!org.spigotmc.ActivationRange.checkIfActive(entity)) { // Paper - comment out - EAR 2, reimplement below -+ entity.ticksLived++; -+ timer = entity.getEntityType().inactiveTickTimer.startTiming(); try { // Paper - timings - entity.inactiveTick(); - } finally { timer.stopTiming(); } // Paper - return; -- } -+ }*/ // Paper - comment out EAR 2 - // Spigot end - // Paper start- timings -- TimingHistory.activatedEntityTicks++; -- timer = entity.getVehicle() != null ? entity.getType().passengerTickTimer.startTiming() : entity.getType().tickTimer.startTiming(); -+ final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(entity); -+ timer = isActive ? entity.getType().tickTimer.startTiming() : entity.getType().inactiveTickTimer.startTiming(); // Paper - try { - // Paper end - timings - entity.setPosAndOldPos(entity.getX(), entity.getY(), entity.getZ()); -@@ -879,12 +879,16 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl - return Registry.ENTITY_TYPE.getKey(entity.getType()).toString(); - }); - gameprofilerfiller.incrementCounter("tickNonPassenger"); -+ if (isActive) { // Paper - EAR 2 -+ TimingHistory.activatedEntityTicks++; // Paper - entity.tick(); - entity.postTick(); // CraftBukkit -+ } else { entity.inactiveTick(); } // Paper - EAR 2 - gameprofilerfiller.pop(); - } +@@ -2,7 +2,6 @@ package net.minecraft.server.level; - this.updateChunkPos(entity); -+ } finally { timer.stopTiming(); } // Paper - timings - if (entity.inChunk) { - Iterator iterator = entity.getPassengers().iterator(); - -@@ -894,7 +898,7 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl - this.tickPassenger(entity, entity1); - } - } -- } finally { timer.stopTiming(); } // Paper - timings -+ //} finally { timer.stopTiming(); } // Paper - timings - move up + import com.google.common.annotations.VisibleForTesting; + import co.aikar.timings.TimingHistory; // Paper +-import co.aikar.timings.Timings; // Paper + import com.google.common.collect.Lists; + import com.mojang.datafixers.DataFixer; + import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +@@ -11,7 +10,6 @@ import it.unimi.dsi.fastutil.longs.LongSet; + import it.unimi.dsi.fastutil.longs.LongSets; + import it.unimi.dsi.fastutil.objects.Object2IntMap.Entry; + import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +-import it.unimi.dsi.fastutil.objects.Object2IntMap; + import it.unimi.dsi.fastutil.objects.ObjectIterator; + import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet; + import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +@@ -123,7 +121,6 @@ import net.minecraft.world.level.chunk.LevelChunkSection; + import net.minecraft.world.level.chunk.storage.EntityStorage; + import net.minecraft.world.level.dimension.DimensionType; + import net.minecraft.world.level.dimension.end.EndDragonFight; +-import net.minecraft.world.level.entity.EntityAccess; + import net.minecraft.world.level.entity.EntityPersistentStorage; + import net.minecraft.world.level.entity.EntityTickList; + import net.minecraft.world.level.entity.EntityTypeTest; +@@ -888,17 +885,17 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl + ++TimingHistory.entityTicks; // Paper - timings + // Spigot start + co.aikar.timings.Timing timer; // Paper +- if (!org.spigotmc.ActivationRange.checkIfActive(entity)) { ++ /*if (!org.spigotmc.ActivationRange.checkIfActive(entity)) { // Paper - comment out - EAR 2, reimplement below + entity.tickCount++; + timer = entity.getType().inactiveTickTimer.startTiming(); try { // Paper - timings + entity.inactiveTick(); + } finally { timer.stopTiming(); } // Paper + return; +- } ++ }*/ // Paper - comment out EAR 2 + // Spigot end + // Paper start- timings +- TimingHistory.activatedEntityTicks++; +- timer = entity.getVehicle() != null ? entity.getType().passengerTickTimer.startTiming() : entity.getType().tickTimer.startTiming(); ++ final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(entity); ++ timer = isActive ? entity.getType().tickTimer.startTiming() : entity.getType().inactiveTickTimer.startTiming(); // Paper + try { + // Paper end - timings + entity.isInLava(); +@@ -909,9 +906,13 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl + return Registry.ENTITY_TYPE.getKey(entity.getType()).toString(); + }); + gameprofilerfiller.incrementCounter("tickNonPassenger"); ++ if (isActive) { // Paper - EAR 2 ++ TimingHistory.activatedEntityTicks++; + entity.tick(); + entity.postTick(); // CraftBukkit ++ } else { entity.inactiveTick(); } // Paper - EAR 2 + this.getProfiler().pop(); ++ } finally { timer.stopTiming(); } // Paper - timings + Iterator iterator = entity.getPassengers().iterator(); + while (iterator.hasNext()) { +@@ -920,13 +921,18 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl + this.tickPassenger(entity, entity1); } + +- } finally { timer.stopTiming(); } // Paper - timings ++ // } finally { timer.stopTiming(); } // Paper - timings - move up + } -@@ -902,6 +906,11 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl - public void tickPassenger(Entity vehicle, Entity passenger) { - if (!passenger.removed && passenger.getVehicle() == vehicle) { - if (passenger instanceof Player || this.getChunkSource().isEntityTickingChunk(passenger)) { + + private void tickPassenger(Entity vehicle, Entity passenger) { + if (!passenger.isRemoved() && passenger.getVehicle() == vehicle) { + if (passenger instanceof Player || this.entityTickList.contains(passenger)) { + // Paper - EAR 2 + final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(passenger); + co.aikar.timings.Timing timer = isActive ? passenger.getType().passengerTickTimer.startTiming() : passenger.getType().passengerInactiveTickTimer.startTiming(); // Paper + try { + // Paper end - passenger.setPosAndOldPos(passenger.getX(), passenger.getY(), passenger.getZ()); - passenger.yRotO = passenger.yRot; - passenger.xRotO = passenger.xRot; -@@ -913,8 +922,17 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl - return Registry.ENTITY_TYPE.getKey(passenger.getType()).toString(); - }); - gameprofilerfiller.incrementCounter("tickPassenger"); -+ // Paper start - EAR 2 -+ if (isActive) { - passenger.rideTick(); - passenger.postTick(); // CraftBukkit -+ } else { -+ passenger.setDeltaMovement(Vec3.ZERO); -+ passenger.inactiveTick(); -+ // copied from inside of if (isPassenger()) of passengerTick, but that ifPassenger is unnecessary -+ vehicle.syncPositionOf(passenger); -+ } -+ // Paper end - EAR 2 - gameprofilerfiller.pop(); + passenger.setOldPosAndRot(); + ++passenger.tickCount; + ProfilerFiller gameprofilerfiller = this.getProfiler(); +@@ -935,8 +941,17 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl + return Registry.ENTITY_TYPE.getKey(passenger.getType()).toString(); + }); + gameprofilerfiller.incrementCounter("tickPassenger"); ++ // Paper start - EAR 2 ++ if (isActive) { + passenger.rideTick(); + passenger.postTick(); // CraftBukkit ++ } else { ++ passenger.setDeltaMovement(Vec3.ZERO); ++ passenger.inactiveTick(); ++ // copied from inside of if (isPassenger()) of passengerTick, but that ifPassenger is unnecessary ++ vehicle.positionRider(passenger); ++ } ++ // Paper end - EAR 2 + gameprofilerfiller.pop(); + Iterator iterator = passenger.getPassengers().iterator(); + +@@ -946,6 +961,7 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl + this.tickPassenger(passenger, entity2); } -@@ -927,7 +945,7 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl - - this.tickPassenger(passenger, entity2); - } -- } -+ } } finally { timer.stopTiming(); } // Paper - EAR2 timings - ++ } finally { timer.stopTiming(); }// Paper - EAR2 timings } } else { + passenger.stopRiding(); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index af86c370c6f834514115a8e40659f5e1aaabec75..c6881a9a5da2caed77dea30e4906d2dd99a624c1 100644 +index a5159198003e43ce272ae73941d2be47d50eedc9..fffeba61e9af5c69876921b48241edb881af2a64 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -67,6 +67,7 @@ import net.minecraft.world.entity.animal.AbstractFish; - import net.minecraft.world.entity.animal.Animal; - import net.minecraft.world.entity.item.ItemEntity; - import net.minecraft.world.entity.player.Player; -+import net.minecraft.world.entity.vehicle.AbstractMinecart; - import net.minecraft.world.entity.vehicle.Boat; - import net.minecraft.world.item.ItemStack; - import net.minecraft.world.item.enchantment.EnchantmentHelper; -@@ -250,7 +251,7 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s +@@ -275,7 +275,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n public boolean noCulling; public boolean hasImpulse; public int portalCooldown; @@ -127,7 +136,7 @@ index af86c370c6f834514115a8e40659f5e1aaabec75..c6881a9a5da2caed77dea30e4906d2dd protected int portalTime; protected BlockPos portalEntrancePos; private boolean invulnerable; -@@ -274,6 +275,7 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s +@@ -305,6 +305,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n public final org.spigotmc.ActivationRange.ActivationType activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this); public final boolean defaultActivationState; public long activatedTick = Integer.MIN_VALUE; @@ -135,51 +144,35 @@ index af86c370c6f834514115a8e40659f5e1aaabec75..c6881a9a5da2caed77dea30e4906d2dd public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one protected int numCollisions = 0; // Paper public void inactiveTick() { } -@@ -664,6 +666,7 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s - this.setLocationFromBoundingbox(); +@@ -746,6 +747,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n } else { - if (type == MoverType.PISTON) { + this.wasOnFire = this.isOnFire(); + if (movementType == MoverType.PISTON) { + this.activatedTick = MinecraftServer.currentTick + 20; // Paper movement = this.limitPistonMovement(movement); if (movement.equals(Vec3.ZERO)) { return; -@@ -676,6 +679,13 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s +@@ -758,6 +760,13 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n this.stuckSpeedMultiplier = Vec3.ZERO; this.setDeltaMovement(Vec3.ZERO); } + // Paper start - ignore movement changes while inactive. -+ if (isTemporarilyActive && !(this instanceof ItemEntity || this instanceof AbstractMinecart) && movement == getDeltaMovement() && type == MoverType.SELF) { ++ if (isTemporarilyActive && !(this instanceof ItemEntity || this instanceof net.minecraft.world.entity.vehicle.AbstractMinecart) && movement == getDeltaMovement() && movementType == MoverType.SELF) { + setDeltaMovement(Vec3.ZERO); + this.level.getProfiler().pop(); + return; + } + // Paper end - movement = this.maybeBackOffFromEdge(movement, type); + movement = this.maybeBackOffFromEdge(movement, movementType); Vec3 vec3d1 = this.collide(movement); -@@ -2011,6 +2021,7 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s - } - } - -+ public void syncPositionOf(Entity entity) { positionRider(entity); } // Paper - OBFHELPER - public void positionRider(Entity passenger) { - this.positionRider(passenger, Entity::setPos); - } -@@ -2821,6 +2832,7 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s - return this.stringUUID; - } - -+ public final boolean isPushedByWater() { return this.isPushedByFluid(); } // Paper - OBFHELPER - the below is not an obfhelper, don't use it! - public boolean isPushedByFluid() { - // Paper start - return this.pushedByWater(); diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 016fcc4ae20e1e48728a848be28633e624ae49a7..b84dab1043c56e2deb58aec8639226f98db165d1 100644 +index f48435dc344fb48feb48e2a141b394829058c5c4..bd1cc5e6fea4b9a171718c1249f652782b7ce13e 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -189,7 +189,7 @@ public abstract class LivingEntity extends Entity { +@@ -219,7 +219,7 @@ public abstract class LivingEntity extends Entity { protected float rotOffs; - protected int deathScore;protected int getKillCount() { return this.deathScore; } // Paper - OBFHELPER + protected int deathScore; public float lastHurt; - protected boolean jumping; + public boolean jumping; // Paper protected -> public @@ -187,10 +180,10 @@ index 016fcc4ae20e1e48728a848be28633e624ae49a7..b84dab1043c56e2deb58aec8639226f9 public float yya; public float zza; diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index 29a2eeee9f2011ed6fcc44f19041f616decfdb38..40ab66f888f30a5506e3aa96a4b32485452e8978 100644 +index 32e8ae0d2a0f78af671a632c4d1be58a0b38a392..79e10f41b2993a02c4218551b06673f1848325a3 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -113,7 +113,7 @@ public abstract class Mob extends LivingEntity { +@@ -117,7 +117,7 @@ public abstract class Mob extends LivingEntity { public ResourceLocation lootTable; public long lootTableSeed; @Nullable @@ -199,7 +192,7 @@ index 29a2eeee9f2011ed6fcc44f19041f616decfdb38..40ab66f888f30a5506e3aa96a4b32485 private int delayedLeashHolderId; @Nullable private CompoundTag leashInfoTag; -@@ -194,6 +194,19 @@ public abstract class Mob extends LivingEntity { +@@ -198,6 +198,19 @@ public abstract class Mob extends LivingEntity { return this.lookControl; } @@ -231,51 +224,29 @@ index 920ae9af8985705a0ada7da5b7085a1ed8ca7f27..7c82d453388a27b69207d051dec316fc protected PathfinderMob(EntityType type, Level world) { super(type, world); -diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java b/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java -index d44a5b7f6cf62d5e9acacad25d47cb0d44761cfa..558dd72c47930f6993952467f83b5a54ead95d92 100644 ---- a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java -+++ b/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java -@@ -20,7 +20,10 @@ public abstract class Goal { - - public void start() {} - -- public void stop() {} -+ public void stop() { -+ onTaskReset(); // Paper -+ } -+ public void onTaskReset() {} // Paper - - public void tick() {} - diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java -index 9066db5c9a76cfb9665bef77b36172f1ea6ba931..9bd2ee05a0de6678ad8933a8ffbe0ae66bd073b4 100644 +index 70e5b4446a8485b5995a0ba26af3a86d9b79bcc7..f29ace7b6a27a602102d37d43a6dd0571f218dfe 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java -@@ -26,10 +26,11 @@ public class GoalSelector { - } - }; - private final Map lockedFlags = new EnumMap(Goal.Flag.class); -- private final Set availableGoals = Sets.newLinkedHashSet(); -+ private final Set availableGoals = Sets.newLinkedHashSet(); private Set getTasks() { return availableGoals; }// Paper - OBFHELPER - private final Supplier profiler; +@@ -31,6 +31,7 @@ public class GoalSelector { private final EnumSet disabledFlags = EnumSet.noneOf(Goal.Flag.class); -- private int newGoalRate = 3; -+ private int newGoalRate = 3;private int getTickRate() { return newGoalRate; } // Paper - OBFHELPER -+ private int curRate;private int getCurRate() { return curRate; } private void incRate() { this.curRate++; } // Paper TODO + private int tickCount; + private int newGoalRate = 3; ++ private int curRate; public GoalSelector(Supplier profiler) { this.profiler = profiler; -@@ -39,6 +40,21 @@ public class GoalSelector { - this.availableGoals.add(new WrappedGoal(priority, goal)); +@@ -45,6 +46,20 @@ public class GoalSelector { + this.availableGoals.clear(); } + // Paper start + public boolean inactiveTick() { -+ incRate(); -+ return getCurRate() % getTickRate() == 0; ++ this.curRate++; ++ return this.curRate % this.newGoalRate == 0; + } + public boolean hasTasks() { -+ for (WrappedGoal task : getTasks()) { ++ for (WrappedGoal task : this.availableGoals) { + if (task.isRunning()) { + return true; + } @@ -283,26 +254,19 @@ index 9066db5c9a76cfb9665bef77b36172f1ea6ba931..9bd2ee05a0de6678ad8933a8ffbe0ae6 + return false; + } + // Paper end -+ public void removeGoal(Goal goal) { - this.availableGoals.stream().filter((pathfindergoalwrapped) -> { - return pathfindergoalwrapped.getGoal() == goal; + this.availableGoals.stream().filter((wrappedGoal) -> { + return wrappedGoal.getGoal() == goal; diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java -index c8680e795deeb68e0662eac7c760a103d1c767b4..e83cb412d8549b86d0348a2aa37c79201a5930be 100644 +index 065d0752db0e3ae2a89d707aaa2145807f50ecad..c93805ae832d049ea13ca495b778ed52381b1f78 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java -@@ -9,12 +9,12 @@ import net.minecraft.world.level.LevelReader; - - public abstract class MoveToBlockGoal extends Goal { - -- protected final PathfinderMob mob; -+ protected final PathfinderMob mob;public PathfinderMob getEntity() { return mob; } // Paper - OBFHELPER - public final double speedModifier; +@@ -14,7 +14,7 @@ public abstract class MoveToBlockGoal extends Goal { protected int nextStartTick; protected int tryTicks; private int maxStayTicks; -- protected BlockPos blockPos;public final BlockPos getTargetPosition() { return this.blockPos; } // Paper - OBFHELPER -+ protected BlockPos blockPos; public final BlockPos getTargetPosition() { return this.blockPos; } public void setTargetPosition(BlockPos pos) { this.blockPos = pos; getEntity().movingTarget = pos != BlockPos.ZERO ? pos : null; } // Paper - OBFHELPER +- protected BlockPos blockPos = BlockPos.ZERO; public final BlockPos getTargetPosition() { return this.blockPos; } // Paper - OBFHELPER ++ protected BlockPos blockPos = BlockPos.ZERO; public final BlockPos getTargetPosition() { return this.blockPos; } public void setTargetPosition(BlockPos pos) { this.blockPos = pos; mob.movingTarget = pos != BlockPos.ZERO ? pos : null; } // Paper - OBFHELPER private boolean reachedTarget; private final int searchRange; private final int verticalSearchRange; @@ -312,85 +276,44 @@ index c8680e795deeb68e0662eac7c760a103d1c767b4..e83cb412d8549b86d0348a2aa37c7920 } + // Paper start - activation range improvements + @Override -+ public void onTaskReset() { -+ super.onTaskReset(); ++ public void stop() { ++ super.stop(); + setTargetPosition(BlockPos.ZERO); + } + // Paper end public MoveToBlockGoal(PathfinderMob mob, double speed, int range, int maxYDifference) { - this.blockPos = BlockPos.ZERO; -@@ -111,6 +118,7 @@ public abstract class MoveToBlockGoal extends Goal { - blockposition_mutableblockposition.setWithOffset((Vec3i) blockposition, i1, k - 1, j1); - if (this.mob.isWithinRestriction((BlockPos) blockposition_mutableblockposition) && this.isValidTarget(this.mob.level, blockposition_mutableblockposition)) { - this.blockPos = blockposition_mutableblockposition; -+ setTargetPosition(blockposition_mutableblockposition.immutable()); // Paper + this.mob = mob; +@@ -109,6 +116,7 @@ public abstract class MoveToBlockGoal extends Goal { + mutableBlockPos.setWithOffset(blockPos, m, k - 1, n); + if (this.mob.isWithinRestriction(mutableBlockPos) && this.isValidTarget(this.mob.level, mutableBlockPos)) { + this.blockPos = mutableBlockPos; ++ setTargetPosition(mutableBlockPos.immutable()); // Paper return true; } } -diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/WrappedGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/WrappedGoal.java -index 9921adf9292e0eff77515841d1b109a07b489367..81b4618a7979ee8dd25e1749c084de9262318ef4 100644 ---- a/src/main/java/net/minecraft/world/entity/ai/goal/WrappedGoal.java -+++ b/src/main/java/net/minecraft/world/entity/ai/goal/WrappedGoal.java -@@ -64,6 +64,7 @@ public class WrappedGoal extends Goal { - return this.goal.getFlags(); - } - -+ public boolean isRunning() { return this.isRunning(); } // Paper - OBFHELPER - public boolean isRunning() { - return this.isRunning; - } -diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java b/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java -index 5a7310bb48c1b8a72ad3c5d82c44fff8800995a2..a24af0600ad3e7d189581aa06a8e998f6a12e0fc 100644 ---- a/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java -+++ b/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java -@@ -454,6 +454,7 @@ public class Llama extends AbstractChestedHorse implements RangedAttackMob { - return this.caravanTail != null; - } - -+ public final boolean inCaravan() { return this.inCaravan(); } // Paper - OBFHELPER - public boolean inCaravan() { - return this.caravanHead != null; - } -diff --git a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java -index ae8f850baa14a4f4277da5b6fdb1e5ccb44c4f35..9eee68a5a84e121698d26bd54212a72c75e16251 100644 ---- a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java -+++ b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java -@@ -70,10 +70,12 @@ public abstract class AbstractVillager extends AgableMob implements Npc, Merchan - return super.finalizeSpawn(world, difficulty, spawnReason, (SpawnGroupData) entityData, entityTag); - } - -+ public final int getUnhappy() { return getUnhappyCounter(); } // Paper - OBFHELPER - public int getUnhappyCounter() { - return (Integer) this.entityData.get(AbstractVillager.DATA_UNHAPPY_COUNTER); - } - -+ public final void setUnhappy(int i) { setUnhappyCounter(i); } // Paper - OBFHELPER - public void setUnhappyCounter(int ticks) { - this.entityData.set(AbstractVillager.DATA_UNHAPPY_COUNTER, ticks); - } diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java -index eed6265dc8275921a18fc5f4970ba131ba782132..4aa34320ef7d6c62ccb17734bfa61d406190b919 100644 +index 6a9e2105b2d9a4ee83c0a2516d5ef26dc3b99053..a35ce224b11b44567814207c3821d0cd4cdd9ec1 100644 --- a/src/main/java/net/minecraft/world/entity/npc/Villager.java +++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java -@@ -212,17 +212,29 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -227,17 +227,29 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @Override public void inactiveTick() { // SPIGOT-3874, SPIGOT-3894, SPIGOT-3846, SPIGOT-5286 :( - if (level.spigotConfig.tickInactiveVillagers && this.isEffectiveAi()) { - this.customServerAiStep(); + // Paper start -+ if (this.getUnhappy() > 0) { -+ this.setUnhappy(this.getUnhappy() - 1); - } ++ if (this.getUnhappyCounter() > 0) { ++ this.setUnhappyCounter(this.getUnhappyCounter() - 1); ++ } + if (this.isEffectiveAi()) { + if (level.spigotConfig.tickInactiveVillagers) { + this.customServerAiStep(); + } else { + this.mobTick(true); + } -+ } -+ doReputationTick(); + } ++ maybeDecayGossip(); + // Paper end + super.inactiveTick(); @@ -407,7 +330,7 @@ index eed6265dc8275921a18fc5f4970ba131ba782132..4aa34320ef7d6c62ccb17734bfa61d40 this.level.getProfiler().pop(); if (this.assignProfessionWhenSpawned) { this.assignProfessionWhenSpawned = false; -@@ -246,7 +258,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -261,7 +273,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler this.lastTradedPlayer = null; } @@ -416,7 +339,7 @@ index eed6265dc8275921a18fc5f4970ba131ba782132..4aa34320ef7d6c62ccb17734bfa61d40 Raid raid = ((ServerLevel) this.level).getRaidAt(this.blockPosition()); if (raid != null && raid.isActive() && !raid.isOver()) { -@@ -257,6 +269,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -272,6 +284,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler if (this.getVillagerData().getProfession() == VillagerProfession.NONE && this.isTrading()) { this.stopTrading(); } @@ -424,19 +347,11 @@ index eed6265dc8275921a18fc5f4970ba131ba782132..4aa34320ef7d6c62ccb17734bfa61d40 super.customServerAiStep(); } -@@ -900,6 +913,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler - } - } - -+ private void doReputationTick() { maybeDecayGossip(); } // Paper - OBFHELPER - private void maybeDecayGossip() { - long i = this.level.getGameTime(); - diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 6b79f8cd9258af47afa6efa7b1f97c3780be58b0..1d536d77518a70bdc1a23924aea99df1042b3cd5 100644 +index 9891e40972c1dc6bebe8ccec2bf82123dcdd7e94..ddcde88a8c8b748b4dc2583b4dfd0fb8ea9e201e 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -142,6 +142,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -153,6 +153,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public long ticksPerWaterSpawns; public long ticksPerWaterAmbientSpawns; public long ticksPerAmbientSpawns; @@ -450,17 +365,16 @@ index 6b79f8cd9258af47afa6efa7b1f97c3780be58b0..1d536d77518a70bdc1a23924aea99df1 public final org.spigotmc.SpigotWorldConfig spigotConfig; // Spigot diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index 61f180a7c95d83bb88c7df4910c498d9bdf6785a..8cbafad53d20366a36493f22160c4fa3e4ac3eaf 100644 +index 84ce3d38d5decb4a2f9fae78e0ef5d715860dc7d..2ab585a018290996e7fa9ca6f3ad7d734cd7beaa 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java -@@ -1,41 +1,55 @@ +@@ -1,39 +1,51 @@ package org.spigotmc; - import java.util.Collection; +-import java.util.Collection; +import net.minecraft.core.BlockPos; import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerChunkCache; - import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.FlyingMob; import net.minecraft.world.entity.LightningBolt; @@ -478,7 +392,6 @@ index 61f180a7c95d83bb88c7df4910c498d9bdf6785a..8cbafad53d20366a36493f22160c4fa3 import net.minecraft.world.entity.boss.enderdragon.EndCrystal; import net.minecraft.world.entity.boss.enderdragon.EnderDragon; import net.minecraft.world.entity.boss.wither.WitherBoss; -+import net.minecraft.world.entity.item.FallingBlockEntity; import net.minecraft.world.entity.item.PrimedTnt; import net.minecraft.world.entity.monster.Creeper; -import net.minecraft.world.entity.monster.Monster; @@ -497,7 +410,6 @@ index 61f180a7c95d83bb88c7df4910c498d9bdf6785a..8cbafad53d20366a36493f22160c4fa3 +import co.aikar.timings.MinecraftTimings; +import net.minecraft.world.entity.schedule.Activity; import net.minecraft.world.level.Level; - import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.phys.AABB; -import co.aikar.timings.MinecraftTimings; @@ -512,7 +424,7 @@ index 61f180a7c95d83bb88c7df4910c498d9bdf6785a..8cbafad53d20366a36493f22160c4fa3 MONSTER, ANIMAL, RAIDER, -@@ -43,6 +57,43 @@ public class ActivationRange +@@ -41,6 +53,43 @@ public class ActivationRange AABB boundingBox = new AABB( 0, 0, 0, 0, 0, 0 ); } @@ -556,7 +468,7 @@ index 61f180a7c95d83bb88c7df4910c498d9bdf6785a..8cbafad53d20366a36493f22160c4fa3 static AABB maxBB = new AABB( 0, 0, 0, 0, 0, 0 ); -@@ -55,10 +106,13 @@ public class ActivationRange +@@ -53,10 +102,13 @@ public class ActivationRange */ public static ActivationType initializeEntityActivationType(Entity entity) { @@ -571,7 +483,7 @@ index 61f180a7c95d83bb88c7df4910c498d9bdf6785a..8cbafad53d20366a36493f22160c4fa3 { return ActivationType.MONSTER; } else if ( entity instanceof PathfinderMob || entity instanceof AmbientCreature ) -@@ -79,10 +133,14 @@ public class ActivationRange +@@ -77,10 +129,14 @@ public class ActivationRange */ public static boolean initializeEntityActivationState(Entity entity, SpigotWorldConfig config) { @@ -590,16 +502,7 @@ index 61f180a7c95d83bb88c7df4910c498d9bdf6785a..8cbafad53d20366a36493f22160c4fa3 || entity instanceof Player || entity instanceof ThrowableProjectile || entity instanceof EnderDragon -@@ -91,7 +149,7 @@ public class ActivationRange - || entity instanceof AbstractHurtingProjectile - || entity instanceof LightningBolt - || entity instanceof PrimedTnt -- || entity instanceof EntityFallingBlock // Paper - Always tick falling blocks -+ || entity instanceof FallingBlockEntity // Paper - Always tick falling blocks - || entity instanceof EndCrystal - || entity instanceof FireworkRocketEntity - || entity instanceof ThrownTrident ) -@@ -115,10 +173,25 @@ public class ActivationRange +@@ -113,10 +169,25 @@ public class ActivationRange final int raiderActivationRange = world.spigotConfig.raiderActivationRange; final int animalActivationRange = world.spigotConfig.animalActivationRange; final int monsterActivationRange = world.spigotConfig.monsterActivationRange; @@ -625,7 +528,7 @@ index 61f180a7c95d83bb88c7df4910c498d9bdf6785a..8cbafad53d20366a36493f22160c4fa3 maxRange = Math.min( ( world.spigotConfig.viewDistance << 4 ) - 8, maxRange ); for ( Player player : world.players() ) -@@ -130,6 +203,11 @@ public class ActivationRange +@@ -128,6 +199,11 @@ public class ActivationRange ActivationType.RAIDER.boundingBox = player.getBoundingBox().inflate( raiderActivationRange, 256, raiderActivationRange ); ActivationType.ANIMAL.boundingBox = player.getBoundingBox().inflate( animalActivationRange, 256, animalActivationRange ); ActivationType.MONSTER.boundingBox = player.getBoundingBox().inflate( monsterActivationRange, 256, monsterActivationRange ); @@ -635,46 +538,9 @@ index 61f180a7c95d83bb88c7df4910c498d9bdf6785a..8cbafad53d20366a36493f22160c4fa3 + ActivationType.VILLAGER.boundingBox = player.getBoundingBox().inflate( villagerActivationRange, 256, waterActivationRange ); + // Paper end - int i = Mth.floor( maxBB.minX / 16.0D ); - int j = Mth.floor( maxBB.maxX / 16.0D ); -@@ -140,7 +218,7 @@ public class ActivationRange - { - for ( int j1 = k; j1 <= l; ++j1 ) - { -- LevelChunk chunk = (LevelChunk) world.getChunkIfLoadedImmediately( i1, j1 ); -+ LevelChunk chunk = chunkProvider.getChunkAtIfLoadedMainThreadNoCache( i1, j1 ); // Paper - if ( chunk != null ) - { - activateChunkEntities( chunk ); -@@ -158,19 +236,15 @@ public class ActivationRange - */ - private static void activateChunkEntities(LevelChunk chunk) - { -- for ( java.util.List slice : chunk.entitySlices ) -- { -- for ( Entity entity : (Collection) slice ) -+ // Paper start -+ Entity[] rawData = chunk.entities.getRawData(); -+ for (int i = 0; i < chunk.entities.size(); i++) { -+ Entity entity = rawData[i]; -+ //for ( Entity entity : (Collection) slice ) -+ // Paper end - { -- if ( MinecraftServer.currentTick > entity.activatedTick ) -- { -- if ( entity.defaultActivationState ) -- { -- entity.activatedTick = MinecraftServer.currentTick; -- continue; -- } -- if ( entity.activationType.boundingBox.intersects( entity.getBoundingBox() ) ) -- { -+ if (MinecraftServer.currentTick > entity.activatedTick) { -+ if (entity.defaultActivationState || entity.activationType.boundingBox.intersects(entity.getBoundingBox())) { // Paper - entity.activatedTick = MinecraftServer.currentTick; - } - } -@@ -185,56 +259,105 @@ public class ActivationRange + world.getEntities().get(maxBB, ActivationRange::activateEntity); + } +@@ -162,56 +238,105 @@ public class ActivationRange * @param entity * @return */ @@ -694,7 +560,7 @@ index 61f180a7c95d83bb88c7df4910c498d9bdf6785a..8cbafad53d20366a36493f22160c4fa3 + // Paper end // quick checks. - if ( entity.wasTouchingWater || entity.remainingFireTicks > 0 ) -+ if ( (entity.activationType != ActivationType.WATER && entity.wasTouchingWater && entity.isPushedByWater()) ) // Paper ++ if ( (entity.activationType != ActivationType.WATER && entity.wasTouchingWater && entity.isPushedByFluid()) ) // Paper { - return true; + return 100; // Paper @@ -780,7 +646,7 @@ index 61f180a7c95d83bb88c7df4910c498d9bdf6785a..8cbafad53d20366a36493f22160c4fa3 if (entity instanceof Creeper && ((Creeper) entity).isIgnited()) { // isExplosive - return true; + return 20; // Paper - } ++ } + // Paper start + if (entity instanceof Mob && ((Mob) entity).targetSelector.hasTasks() ) { + return 0; @@ -788,7 +654,7 @@ index 61f180a7c95d83bb88c7df4910c498d9bdf6785a..8cbafad53d20366a36493f22160c4fa3 + if (entity instanceof Pillager) { + Pillager pillager = (Pillager) entity; + // TODO:? -+ } + } + // Paper end } - return false; @@ -796,8 +662,8 @@ index 61f180a7c95d83bb88c7df4910c498d9bdf6785a..8cbafad53d20366a36493f22160c4fa3 } /** -@@ -249,8 +372,19 @@ public class ActivationRange - if ( !entity.inChunk || entity instanceof FireworkRocketEntity ) { +@@ -226,8 +351,19 @@ public class ActivationRange + if ( entity instanceof FireworkRocketEntity ) { return true; } + // Paper start - special case always immunities @@ -817,11 +683,11 @@ index 61f180a7c95d83bb88c7df4910c498d9bdf6785a..8cbafad53d20366a36493f22160c4fa3 // Should this entity tick? if ( !isActive ) -@@ -258,15 +392,19 @@ public class ActivationRange +@@ -235,15 +371,19 @@ public class ActivationRange if ( ( MinecraftServer.currentTick - entity.activatedTick - 1 ) % 20 == 0 ) { // Check immunities every 20 ticks. -- if ( checkEntityImmunities( entity ) ) +- if ( ActivationRange.checkEntityImmunities( entity ) ) - { - // Triggered some sort of immunity, give 20 full ticks before we check again. - entity.activatedTick = MinecraftServer.currentTick + 20; @@ -837,13 +703,13 @@ index 61f180a7c95d83bb88c7df4910c498d9bdf6785a..8cbafad53d20366a36493f22160c4fa3 + } // Add a little performance juice to active entities. Skip 1/4 if not immune. -- } else if ( !entity.defaultActivationState && entity.tickCount % 4 == 0 && !checkEntityImmunities( entity ) ) -+ } else if (entity.tickCount % 4 == 0 && checkEntityImmunities( entity) < 0 ) // Paper +- } else if ( !entity.defaultActivationState && entity.tickCount % 4 == 0 && !ActivationRange.checkEntityImmunities( entity ) ) ++ } else if ( entity.tickCount % 4 == 0 && ActivationRange.checkEntityImmunities( entity ) < 0 ) // Paper { isActive = false; } diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java -index 34ee684901906fc2ef5f0d09680d2686b813e52b..6b015c1f26facb4e82d75b252164dec05731ca6c 100644 +index 8e6eae7cc27f66faede9a3dc74571e1814df3652..308de0757c219c1e5fa8bde182343c4095301cde 100644 --- a/src/main/java/org/spigotmc/SpigotWorldConfig.java +++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java @@ -180,13 +180,59 @@ public class SpigotWorldConfig @@ -873,36 +739,36 @@ index 34ee684901906fc2ef5f0d09680d2686b813e52b..6b015c1f26facb4e82d75b252164dec0 public boolean tickInactiveVillagers = true; private void activationRange() { -+ boolean hasAnimalsConfig = config.getInt("entity-activation-range.animals", animalActivationRange) != animalActivationRange; // Paper - animalActivationRange = getInt( "entity-activation-range.animals", animalActivationRange ); - monsterActivationRange = getInt( "entity-activation-range.monsters", monsterActivationRange ); - raiderActivationRange = getInt( "entity-activation-range.raiders", raiderActivationRange ); - miscActivationRange = getInt( "entity-activation-range.misc", miscActivationRange ); ++ boolean hasAnimalsConfig = config.getInt("entity-activation-range.animals", this.animalActivationRange) != this.animalActivationRange; // Paper + this.animalActivationRange = this.getInt( "entity-activation-range.animals", this.animalActivationRange ); + this.monsterActivationRange = this.getInt( "entity-activation-range.monsters", this.monsterActivationRange ); + this.raiderActivationRange = this.getInt( "entity-activation-range.raiders", this.raiderActivationRange ); + this.miscActivationRange = this.getInt( "entity-activation-range.misc", this.miscActivationRange ); + // Paper start -+ waterActivationRange = getInt( "entity-activation-range.water", waterActivationRange ); -+ villagerActivationRange = getInt( "entity-activation-range.villagers", hasAnimalsConfig ? animalActivationRange : villagerActivationRange ); -+ flyingMonsterActivationRange = getInt( "entity-activation-range.flying-monsters", flyingMonsterActivationRange ); ++ this.waterActivationRange = this.getInt( "entity-activation-range.water", this.waterActivationRange ); ++ this.villagerActivationRange = this.getInt( "entity-activation-range.villagers", hasAnimalsConfig ? this.animalActivationRange : this.villagerActivationRange ); ++ this.flyingMonsterActivationRange = this.getInt( "entity-activation-range.flying-monsters", this.flyingMonsterActivationRange ); + -+ wakeUpInactiveAnimals = getInt("entity-activation-range.wake-up-inactive.animals-max-per-tick", wakeUpInactiveAnimals); -+ wakeUpInactiveAnimalsEvery = getInt("entity-activation-range.wake-up-inactive.animals-every", wakeUpInactiveAnimalsEvery); -+ wakeUpInactiveAnimalsFor = getInt("entity-activation-range.wake-up-inactive.animals-for", wakeUpInactiveAnimalsFor); ++ this.wakeUpInactiveAnimals = this.getInt("entity-activation-range.wake-up-inactive.animals-max-per-tick", this.wakeUpInactiveAnimals); ++ this.wakeUpInactiveAnimalsEvery = this.getInt("entity-activation-range.wake-up-inactive.animals-every", this.wakeUpInactiveAnimalsEvery); ++ this.wakeUpInactiveAnimalsFor = this.getInt("entity-activation-range.wake-up-inactive.animals-for", this.wakeUpInactiveAnimalsFor); + -+ wakeUpInactiveMonsters = getInt("entity-activation-range.wake-up-inactive.monsters-max-per-tick", wakeUpInactiveMonsters); -+ wakeUpInactiveMonstersEvery = getInt("entity-activation-range.wake-up-inactive.monsters-every", wakeUpInactiveMonstersEvery); -+ wakeUpInactiveMonstersFor = getInt("entity-activation-range.wake-up-inactive.monsters-for", wakeUpInactiveMonstersFor); ++ this.wakeUpInactiveMonsters = this.getInt("entity-activation-range.wake-up-inactive.monsters-max-per-tick", this.wakeUpInactiveMonsters); ++ this.wakeUpInactiveMonstersEvery = this.getInt("entity-activation-range.wake-up-inactive.monsters-every", this.wakeUpInactiveMonstersEvery); ++ this.wakeUpInactiveMonstersFor = this.getInt("entity-activation-range.wake-up-inactive.monsters-for", this.wakeUpInactiveMonstersFor); + -+ wakeUpInactiveVillagers = getInt("entity-activation-range.wake-up-inactive.villagers-max-per-tick", wakeUpInactiveVillagers); -+ wakeUpInactiveVillagersEvery = getInt("entity-activation-range.wake-up-inactive.villagers-every", wakeUpInactiveVillagersEvery); -+ wakeUpInactiveVillagersFor = getInt("entity-activation-range.wake-up-inactive.villagers-for", wakeUpInactiveVillagersFor); ++ this.wakeUpInactiveVillagers = this.getInt("entity-activation-range.wake-up-inactive.villagers-max-per-tick", this.wakeUpInactiveVillagers); ++ this.wakeUpInactiveVillagersEvery = this.getInt("entity-activation-range.wake-up-inactive.villagers-every", this.wakeUpInactiveVillagersEvery); ++ this.wakeUpInactiveVillagersFor = this.getInt("entity-activation-range.wake-up-inactive.villagers-for", this.wakeUpInactiveVillagersFor); + -+ wakeUpInactiveFlying = getInt("entity-activation-range.wake-up-inactive.flying-monsters-max-per-tick", wakeUpInactiveFlying); -+ wakeUpInactiveFlyingEvery = getInt("entity-activation-range.wake-up-inactive.flying-monsters-every", wakeUpInactiveFlyingEvery); -+ wakeUpInactiveFlyingFor = getInt("entity-activation-range.wake-up-inactive.flying-monsters-for", wakeUpInactiveFlyingFor); ++ this.wakeUpInactiveFlying = this.getInt("entity-activation-range.wake-up-inactive.flying-monsters-max-per-tick", this.wakeUpInactiveFlying); ++ this.wakeUpInactiveFlyingEvery = this.getInt("entity-activation-range.wake-up-inactive.flying-monsters-every", this.wakeUpInactiveFlyingEvery); ++ this.wakeUpInactiveFlyingFor = this.getInt("entity-activation-range.wake-up-inactive.flying-monsters-for", this.wakeUpInactiveFlyingFor); + -+ villagersWorkImmunityAfter = getInt( "entity-activation-range.villagers-work-immunity-after", villagersWorkImmunityAfter ); -+ villagersWorkImmunityFor = getInt( "entity-activation-range.villagers-work-immunity-for", villagersWorkImmunityFor ); -+ villagersActiveForPanic = getBoolean( "entity-activation-range.villagers-active-for-panic", villagersActiveForPanic ); ++ this.villagersWorkImmunityAfter = this.getInt( "entity-activation-range.villagers-work-immunity-after", this.villagersWorkImmunityAfter ); ++ this.villagersWorkImmunityFor = this.getInt( "entity-activation-range.villagers-work-immunity-for", this.villagersWorkImmunityFor ); ++ this.villagersActiveForPanic = this.getBoolean( "entity-activation-range.villagers-active-for-panic", this.villagersActiveForPanic ); + // Paper end - tickInactiveVillagers = getBoolean( "entity-activation-range.tick-inactive-villagers", tickInactiveVillagers ); - log( "Entity Activation Range: An " + animalActivationRange + " / Mo " + monsterActivationRange + " / Ra " + raiderActivationRange + " / Mi " + miscActivationRange + " / Tiv " + tickInactiveVillagers ); + this.tickInactiveVillagers = this.getBoolean( "entity-activation-range.tick-inactive-villagers", this.tickInactiveVillagers ); + this.log( "Entity Activation Range: An " + this.animalActivationRange + " / Mo " + this.monsterActivationRange + " / Ra " + this.raiderActivationRange + " / Mi " + this.miscActivationRange + " / Tiv " + this.tickInactiveVillagers ); } diff --git a/patches/server-remapped/0429-Increase-Light-Queue-Size.patch b/patches/server/0359-Increase-Light-Queue-Size.patch similarity index 78% rename from patches/server-remapped/0429-Increase-Light-Queue-Size.patch rename to patches/server/0359-Increase-Light-Queue-Size.patch index f5ba65950..980579a32 100644 --- a/patches/server-remapped/0429-Increase-Light-Queue-Size.patch +++ b/patches/server/0359-Increase-Light-Queue-Size.patch @@ -14,12 +14,12 @@ light engine on shutdown... The queue size only puts a cap on max loss, doesn't solve that problem. diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index 6c8e9d498c9a30a1aa88494ba09c3cae012a8fa1..cd248eb6be663e8be33f2c3c6b06b77b6d5753a4 100644 +index 041efecbfcd54384d15ebf771cdfa0e711483997..e29566cad2647da4d9288e912188b57f00e8dd0c 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -@@ -620,4 +620,9 @@ public class PaperWorldConfig { - private void zombieVillagerInfectionChance() { - zombieVillagerInfectionChance = getDouble("zombie-villager-infection-chance", zombieVillagerInfectionChance); +@@ -440,5 +440,10 @@ public class PaperWorldConfig { + disableHopperMoveEvents = getBoolean("hopper.disable-move-event", disableHopperMoveEvents); + log("Hopper Move Item Events: " + (disableHopperMoveEvents ? "disabled" : "enabled")); } + + public int lightQueueSize = 20; @@ -27,11 +27,12 @@ index 6c8e9d498c9a30a1aa88494ba09c3cae012a8fa1..cd248eb6be663e8be33f2c3c6b06b77b + lightQueueSize = getInt("light-queue-size", lightQueueSize); + } } + diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index e33189dc8375a3034910087654607fb531061636..11c6e8ce10c53dcb639145fbda32c5426eb6b3d9 100644 +index 312be2221e1acc44aaf6936533b0eb968f796dc6..494a3afaaa0e3496d30e8d97edbab62b21610dfe 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -775,7 +775,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop (max 5) to automatically fix all light data in the chunks. diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/java/com/destroystokyo/paper/PaperCommand.java -index ff718bc7f521575e6a670e17fcf59a2d30841705..528c860fc0c04431e0ebb2ae6bc96bf9c2d04789 100644 +index 71ffa66973d8994e2a480435ac1ada3fe61600a4..7b5afc5d34b78e6404c1a5c6bb823d9589471f13 100644 --- a/src/main/java/com/destroystokyo/paper/PaperCommand.java +++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java -@@ -11,16 +11,20 @@ import com.google.common.collect.Maps; - import com.google.gson.JsonObject; - import com.google.gson.internal.Streams; - import com.google.gson.stream.JsonWriter; -+import net.minecraft.core.BlockPos; -+import net.minecraft.network.protocol.game.ClientboundLightUpdatePacket; - import net.minecraft.resources.ResourceLocation; - import net.minecraft.server.MCUtil; - import net.minecraft.server.MinecraftServer; +@@ -10,7 +10,8 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerLevel; +-import net.minecraft.world.entity.Entity; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.level.ThreadedLevelLightEngine; - import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.ChunkPos; --import net.minecraft.server.MCUtil; -+import net.minecraft.world.level.chunk.LevelChunk; - import org.apache.commons.lang3.tuple.MutablePair; - import org.apache.commons.lang3.tuple.Pair; - import org.bukkit.Bukkit; -@@ -31,6 +35,7 @@ import org.bukkit.command.Command; + import net.minecraft.resources.ResourceLocation; +@@ -25,15 +26,18 @@ import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.CraftWorld; @@ -40,8 +28,6 @@ index ff718bc7f521575e6a670e17fcf59a2d30841705..528c860fc0c04431e0ebb2ae6bc96bf9 import org.bukkit.entity.Player; import java.io.File; -@@ -39,10 +44,12 @@ import java.io.PrintStream; - import java.io.StringWriter; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.ArrayDeque; @@ -53,18 +39,18 @@ index ff718bc7f521575e6a670e17fcf59a2d30841705..528c860fc0c04431e0ebb2ae6bc96bf9 import java.util.Iterator; import java.util.List; import java.util.Locale; -@@ -52,7 +59,7 @@ import java.util.stream.Collectors; +@@ -43,7 +47,7 @@ import java.util.stream.Collectors; public class PaperCommand extends Command { private static final String BASE_PERM = "bukkit.command.paper."; -- private static final ImmutableSet SUBCOMMANDS = ImmutableSet.builder().add("heap", "entity", "reload", "version", "debug", "chunkinfo", "dumpwaiting", "syncloadinfo").build(); -+ private static final ImmutableSet SUBCOMMANDS = ImmutableSet.builder().add("heap", "entity", "reload", "version", "debug", "chunkinfo", "dumpwaiting", "syncloadinfo", "fixlight").build(); +- private static final ImmutableSet SUBCOMMANDS = ImmutableSet.builder().add("heap", "entity", "reload", "version", "debug", "chunkinfo").build(); ++ private static final ImmutableSet SUBCOMMANDS = ImmutableSet.builder().add("heap", "entity", "reload", "version", "debug", "chunkinfo", "fixlight").build(); public PaperCommand(String name) { super(name); -@@ -173,6 +180,9 @@ public class PaperCommand extends Command { - case "syncloadinfo": - this.doSyncLoadInfo(sender, args); +@@ -158,6 +162,9 @@ public class PaperCommand extends Command { + case "chunkinfo": + doChunkInfo(sender, args); break; + case "fixlight": + this.doFixLight(sender, args); @@ -72,10 +58,10 @@ index ff718bc7f521575e6a670e17fcf59a2d30841705..528c860fc0c04431e0ebb2ae6bc96bf9 case "ver": if (!testPermission(sender, "version")) break; // "ver" needs a special check because it's an alias. All other commands are checked up before the switch statement (because they are present in the SUBCOMMANDS set) case "version": -@@ -190,6 +200,77 @@ public class PaperCommand extends Command { - return true; - } +@@ -413,4 +420,74 @@ public class PaperCommand extends Command { + Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Paper config reload complete."); + } + private void doFixLight(CommandSender sender, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("Only players can use this command"); @@ -97,7 +83,7 @@ index ff718bc7f521575e6a670e17fcf59a2d30841705..528c860fc0c04431e0ebb2ae6bc96bf9 + ServerLevel world = (ServerLevel) handle.level; + ThreadedLevelLightEngine lightengine = world.getChunkSource().getLightEngine(); + -+ BlockPos center = MCUtil.toBlockPosition(player.getLocation()); ++ net.minecraft.core.BlockPos center = MCUtil.toBlockPosition(player.getLocation()); + Deque queue = new ArrayDeque<>(MCUtil.getSpiralOutChunks(center, radius)); + updateLight(sender, world, lightengine, queue); + } @@ -114,7 +100,7 @@ index ff718bc7f521575e6a670e17fcf59a2d30841705..528c860fc0c04431e0ebb2ae6bc96bf9 + updateLight(sender, world, lightengine, queue); + return; + } -+ LevelChunk chunk = (LevelChunk) either.left().orElse(null); ++ net.minecraft.world.level.chunk.LevelChunk chunk = (net.minecraft.world.level.chunk.LevelChunk) either.left().orElse(null); + if (chunk == null) { + updateLight(sender, world, lightengine, queue); + return; @@ -126,7 +112,7 @@ index ff718bc7f521575e6a670e17fcf59a2d30841705..528c860fc0c04431e0ebb2ae6bc96bf9 + for (int y = 0; y < world.getHeight(); y++) { + for (int x = 0; x < 16; x++) { + for (int z = 0; z < 16; z++) { -+ BlockPos pos = new BlockPos(cx + x, y, cz + z); ++ net.minecraft.core.BlockPos pos = new net.minecraft.core.BlockPos(cx + x, y, cz + z); + lightengine.checkBlock(pos); + } + } @@ -136,7 +122,7 @@ index ff718bc7f521575e6a670e17fcf59a2d30841705..528c860fc0c04431e0ebb2ae6bc96bf9 + if (visibleChunk != null) { + world.getChunkSource().chunkMap.addLightTask(visibleChunk, () -> { + MinecraftServer.getServer().processQueue.add(() -> { -+ visibleChunk.sendPacketToTrackedPlayers(new ClientboundLightUpdatePacket(chunk.getPos(), lightengine, true), false); ++ visibleChunk.broadcast(new net.minecraft.network.protocol.game.ClientboundLightUpdatePacket(chunk.getPos(), lightengine, null, null, true), false); + updateLight(sender, world, lightengine, queue); + }); + }); @@ -146,37 +132,48 @@ index ff718bc7f521575e6a670e17fcf59a2d30841705..528c860fc0c04431e0ebb2ae6bc96bf9 + lightengine.setTaskPerBatch(world.paperConfig.lightQueueSize); + }, MinecraftServer.getServer()); + } -+ - private void doSyncLoadInfo(CommandSender sender, String[] args) { - if (!SyncLoadFinder.ENABLED) { - sender.sendMessage(ChatColor.RED + "This command requires the server startup flag '-Dpaper.debug-sync-loads=true' to be set."); + } diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java -index 9ebcfca10071cc42d4f1df02c25de5042c065f38..d907872d80f840b343419f49a6708082da6f921b 100644 +index 56e292e6550b19d0cae9ebad369da730ca1cabd8..3653ec6f93d627092e63cede51f4db2e12b10613 100644 --- a/src/main/java/net/minecraft/server/level/ChunkHolder.java +++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java -@@ -349,6 +349,7 @@ public class ChunkHolder { +@@ -312,7 +312,7 @@ public class ChunkHolder { } -+ public void sendPacketToTrackedPlayers(Packet packet, boolean flag) { broadcast(packet, flag); } // Paper - OBFHELPER - private void broadcast(Packet packet, boolean onlyOnWatchDistanceEdge) { - // Paper start - per player view distance - // there can be potential desync with player's last mapped section and the view distance map, so use the +- private void broadcast(Packet packet, boolean onlyOnWatchDistanceEdge) { ++ public void broadcast(Packet packet, boolean onlyOnWatchDistanceEdge) { // Paper - private -> public + this.playerProvider.getPlayers(this.pos, onlyOnWatchDistanceEdge).forEach((entityplayer) -> { + entityplayer.connection.send(packet); + }); diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 6b51a082cf42bc3ffc550614e385d3956c5f2efb..67f748d5955453ba4873b0c9bb741b5bfe52d655 100644 +index 5473b22d21ea981f245f4826c4d47295890f88ef..480c361c919bbfbebacf9ac94418eac5ed38e233 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -344,11 +344,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - ProcessorHandle mailbox = ProcessorHandle.of("main", mainThreadExecutor::tell); +@@ -123,6 +123,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + private final ChunkTaskPriorityQueueSorter queueSorter; + private final ProcessorHandle> worldgenMailbox; + private final ProcessorHandle> mainThreadMailbox; ++ // Paper start ++ final ProcessorHandle> mailboxLight; ++ public void addLightTask(ChunkHolder playerchunk, Runnable run) { ++ this.mailboxLight.tell(ChunkTaskPriorityQueueSorter.message(playerchunk, run)); ++ } ++ // Paper end + public final ChunkProgressListener progressListener; + private final ChunkStatusUpdateListener chunkStatusListener; + public final ChunkMap.ChunkDistanceManager distanceManager; +@@ -199,11 +205,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.progressListener = worldGenerationProgressListener; -- ProcessorMailbox threadedmailbox1 = ProcessorMailbox.create(workerExecutor, "light"); -+ ProcessorMailbox lightthreaded; ProcessorMailbox threadedmailbox1 = lightthreaded = ProcessorMailbox.create(workerExecutor, "light"); // Paper + this.chunkStatusListener = chunkStatusChangeListener; +- ProcessorMailbox threadedmailbox1 = ProcessorMailbox.create(executor, "light"); ++ ProcessorMailbox lightthreaded; ProcessorMailbox threadedmailbox1 = lightthreaded = ProcessorMailbox.create(executor, "light"); // Paper - this.queueSorter = new ChunkTaskPriorityQueueSorter(ImmutableList.of(threadedmailbox, mailbox, threadedmailbox1), workerExecutor, Integer.MAX_VALUE); + this.queueSorter = new ChunkTaskPriorityQueueSorter(ImmutableList.of(threadedmailbox, mailbox, threadedmailbox1), executor, Integer.MAX_VALUE); this.worldgenMailbox = this.queueSorter.getProcessor(threadedmailbox, false); this.mainThreadMailbox = this.queueSorter.getProcessor(mailbox, false); + this.mailboxLight = this.queueSorter.getProcessor(lightthreaded, false);// Paper this.lightEngine = new ThreadedLevelLightEngine(chunkProvider, this, this.level.dimensionType().hasSkyLight(), threadedmailbox1, this.queueSorter.getProcessor(threadedmailbox1, false)); - this.distanceManager = new ChunkMap.ChunkDistanceManager(workerExecutor, mainThreadExecutor); this.distanceManager.chunkMap = this; // Paper - this.overworldDataStorage = supplier; + this.distanceManager = new ChunkMap.ChunkDistanceManager(executor, mainThreadExecutor); + this.overworldDataStorage = persistentStateManagerFactory; diff --git a/patches/server-remapped/0470-No-Tick-view-distance-implementation.patch b/patches/server/0361-No-Tick-view-distance-implementation.patch similarity index 68% rename from patches/server-remapped/0470-No-Tick-view-distance-implementation.patch rename to patches/server/0361-No-Tick-view-distance-implementation.patch index 9fee42c2d..6fdb3036e 100644 --- a/patches/server-remapped/0470-No-Tick-view-distance-implementation.patch +++ b/patches/server/0361-No-Tick-view-distance-implementation.patch @@ -9,26 +9,26 @@ Per-Player is absent due to difficulty of maintaining the diff required to make it happen. diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java -index 5bcf9cefc29eb20e2cfbfb49e2b2662ec394a87e..a696474b4bd0e32a26dadfbc1257580ee596f0c0 100644 +index f27fadc15cb7f5c782e45885ec6a5a69963beade..2ff4d4921e2076abf415bd3c8f5173ecd6222168 100644 --- a/src/main/java/co/aikar/timings/TimingsExport.java +++ b/src/main/java/co/aikar/timings/TimingsExport.java -@@ -156,7 +156,8 @@ public class TimingsExport extends Thread { +@@ -152,7 +152,8 @@ public class TimingsExport extends Thread { pair("gamerules", toObjectMapper(world.getWorld().getGameRules(), rule -> { return pair(rule, world.getWorld().getGameRuleValue(rule)); })), -- pair("ticking-distance", world.getChunkProvider().playerChunkMap.getEffectiveViewDistance()) -+ pair("ticking-distance", world.getChunkProvider().playerChunkMap.getEffectiveViewDistance()), -+ pair("notick-viewdistance", world.getChunkProvider().playerChunkMap.getEffectiveNoTickViewDistance()) +- pair("ticking-distance", world.getChunkSource().chunkMap.getEffectiveViewDistance()) ++ pair("ticking-distance", world.getChunkSource().chunkMap.getEffectiveViewDistance()), ++ pair("notick-viewdistance", world.getChunkSource().chunkMap.getEffectiveNoTickViewDistance()) )); })); diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index 46ac6d91422423f1e03b86d3efa3241f2599000d..6463d3e4837d032a35654a035f42b8a805e0e286 100644 +index e29566cad2647da4d9288e912188b57f00e8dd0c..3cd8895adecd345c3bdfb8b5e3e9fdf0ef9097db 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -@@ -632,4 +632,9 @@ public class PaperWorldConfig { - phantomIgnoreCreative = getBoolean("phantoms-do-not-spawn-on-creative-players", phantomIgnoreCreative); - phantomOnlyAttackInsomniacs = getBoolean("phantoms-only-attack-insomniacs", phantomOnlyAttackInsomniacs); +@@ -445,5 +445,10 @@ public class PaperWorldConfig { + private void lightQueueSize() { + lightQueueSize = getInt("light-queue-size", lightQueueSize); } + + public int noTickViewDistance; @@ -36,11 +36,12 @@ index 46ac6d91422423f1e03b86d3efa3241f2599000d..6463d3e4837d032a35654a035f42b8a8 + this.noTickViewDistance = this.getInt("viewdistances.no-tick-view-distance", -1); + } } + diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java -index 9abef8550a89df5e15ac28de1a5549d064f29122..d18497a33dc53f6b465e659967bf8c98731c46c0 100644 +index bb0a07a280c7d4885165e9d6488e7741aaa7b47c..9c88426ab1275ee5fb6e28be8b213533dc4ab859 100644 --- a/src/main/java/net/minecraft/server/MCUtil.java +++ b/src/main/java/net/minecraft/server/MCUtil.java -@@ -638,7 +638,8 @@ public final class MCUtil { +@@ -636,7 +636,8 @@ public final class MCUtil { }); worldData.addProperty("name", world.getWorld().getName()); @@ -51,13 +52,13 @@ index 9abef8550a89df5e15ac28de1a5549d064f29122..d18497a33dc53f6b465e659967bf8c98 worldData.addProperty("keep-spawn-loaded-range", world.paperConfig.keepLoadedRange); worldData.addProperty("visible-chunk-count", visibleChunks.size()); diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java -index 0147798c0285f64b8d767dfb2709d92f66ac72ef..9ebcfca10071cc42d4f1df02c25de5042c065f38 100644 +index 3653ec6f93d627092e63cede51f4db2e12b10613..995d7977233f0d7683c00a75c3833f9a1eba7f92 100644 --- a/src/main/java/net/minecraft/server/level/ChunkHolder.java +++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java -@@ -81,6 +81,18 @@ public class ChunkHolder { - } - // Paper end - optimise isOutsideOfRange +@@ -75,6 +75,17 @@ public class ChunkHolder { + boolean isUpdateQueued = false; // Paper + private final ChunkMap chunkMap; // Paper + // Paper start - no-tick view distance + public final LevelChunk getSendingChunk() { + // it's important that we use getChunkAtIfLoadedImmediately to mirror the chunk sending logic used @@ -69,32 +70,31 @@ index 0147798c0285f64b8d767dfb2709d92f66ac72ef..9ebcfca10071cc42d4f1df02c25de504 + return null; + } + // Paper end - no-tick view distance -+ - public ChunkHolder(ChunkPos pos, int level, LevelLightEngine lightingProvider, ChunkHolder.LevelChangeListener levelUpdateListener, ChunkHolder.PlayerProvider playersWatchingChunkProvider) { + + public ChunkHolder(ChunkPos pos, int level, LevelHeightAccessor world, LevelLightEngine lightingProvider, ChunkHolder.LevelChangeListener levelUpdateListener, ChunkHolder.PlayerProvider playersWatchingChunkProvider) { this.futures = new AtomicReferenceArray(ChunkHolder.CHUNK_STATUSES.size()); - this.fullChunkFuture = ChunkHolder.UNLOADED_LEVEL_CHUNK_FUTURE; -@@ -240,7 +252,7 @@ public class ChunkHolder { +@@ -207,7 +218,7 @@ public class ChunkHolder { } - public void blockChanged(BlockPos blockposition) { + public void blockChanged(BlockPos pos) { - LevelChunk chunk = this.getTickingChunk(); + LevelChunk chunk = this.getSendingChunk(); // Paper - no-tick view distance if (chunk != null) { - byte b0 = (byte) SectionPos.blockToSectionCoord(blockposition.getY()); -@@ -256,7 +268,7 @@ public class ChunkHolder { + int i = this.levelHeightAccessor.getSectionIndex(pos.getY()); +@@ -223,7 +234,7 @@ public class ChunkHolder { } - public void sectionLightChanged(LightLayer type, int y) { + public void sectionLightChanged(LightLayer lightType, int y) { - LevelChunk chunk = this.getTickingChunk(); + LevelChunk chunk = this.getSendingChunk(); // Paper - no-tick view distance if (chunk != null) { chunk.setUnsaved(true); -@@ -338,9 +350,48 @@ public class ChunkHolder { +@@ -313,9 +324,48 @@ public class ChunkHolder { } - private void broadcast(Packet packet, boolean onlyOnWatchDistanceEdge) { + public void broadcast(Packet packet, boolean onlyOnWatchDistanceEdge) { // Paper - private -> public - this.playerProvider.getPlayers(this.pos, onlyOnWatchDistanceEdge).forEach((entityplayer) -> { - entityplayer.connection.send(packet); - }); @@ -119,8 +119,8 @@ index 0147798c0285f64b8d767dfb2709d92f66ac72ef..9ebcfca10071cc42d4f1df02c25de504 + int viewDistance = viewDistanceMap.getLastViewDistance(player); + long lastPosition = viewDistanceMap.getLastCoordinate(player); + -+ int distX = Math.abs(MCUtil.getCoordinateX(lastPosition) - this.pos.x); -+ int distZ = Math.abs(MCUtil.getCoordinateZ(lastPosition) - this.pos.z); ++ int distX = Math.abs(net.minecraft.server.MCUtil.getCoordinateX(lastPosition) - this.pos.x); ++ int distZ = Math.abs(net.minecraft.server.MCUtil.getCoordinateZ(lastPosition) - this.pos.z); + + if (Math.max(distX, distZ) == viewDistance) { + player.connection.send(packet); @@ -144,43 +144,22 @@ index 0147798c0285f64b8d767dfb2709d92f66ac72ef..9ebcfca10071cc42d4f1df02c25de504 public CompletableFuture> getOrScheduleFuture(ChunkStatus targetStatus, ChunkMap chunkStorage) { diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 56ca469bf930bcced88efdafc78f464c756a5be9..6b51a082cf42bc3ffc550614e385d3956c5f2efb 100644 +index 480c361c919bbfbebacf9ac94418eac5ed38e233..fdf5d8ede4b01e399272ddebfbd49258b166f00b 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -57,12 +57,14 @@ import net.minecraft.network.protocol.Packet; - import net.minecraft.network.protocol.game.ClientboundLevelChunkPacket; - import net.minecraft.network.protocol.game.ClientboundLightUpdatePacket; - import net.minecraft.network.protocol.game.ClientboundSetChunkCacheCenterPacket; -+import net.minecraft.network.protocol.game.ClientboundSetChunkCacheRadiusPacket; - import net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket; - import net.minecraft.network.protocol.game.ClientboundSetPassengersPacket; - import net.minecraft.network.protocol.game.DebugPackets; - import net.minecraft.server.MCUtil; - import net.minecraft.server.MinecraftServer; - import net.minecraft.server.level.progress.ChunkProgressListener; -+import net.minecraft.server.network.ServerGamePacketListenerImpl; - import net.minecraft.util.CsvOutput; - import net.minecraft.util.Mth; - import net.minecraft.util.profiling.ProfilerFiller; -@@ -144,7 +146,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -122,7 +122,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider private boolean modified; private final ChunkTaskPriorityQueueSorter queueSorter; private final ProcessorHandle> worldgenMailbox; - private final ProcessorHandle> mainThreadMailbox; + public final ProcessorHandle> mainThreadMailbox; // Paper - private -> public -+ // Paper start -+ final ProcessorHandle> mailboxLight; -+ public void addLightTask(ChunkHolder playerchunk, Runnable run) { -+ this.mailboxLight.tell(ChunkTaskPriorityQueueSorter.message(playerchunk, run)); -+ } -+ // Paper end - public final ChunkProgressListener progressListener; - public final ChunkMap.ChunkDistanceManager distanceManager; public final DistanceManager getChunkDistanceManager() { return this.distanceManager; } // Paper - OBFHELPER - private final AtomicInteger tickingGenerated; -@@ -219,6 +227,22 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerMobSpawnMap; // this map is absent from updateMaps since it's controlled at the start of the chunkproviderserver tick - public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerChunkTickRangeMap; - // Paper end - optimise PlayerChunkMap#isOutsideRange + // Paper start + final ProcessorHandle> mailboxLight; + public void addLightTask(ChunkHolder playerchunk, Runnable run) { +@@ -164,21 +164,68 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + + // Paper start - distance maps + private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>(); + // Paper start - no-tick view distance + int noTickViewDistance; + public final int getRawNoTickViewDistance() { @@ -200,15 +179,13 @@ index 56ca469bf930bcced88efdafc78f464c756a5be9..6b51a082cf42bc3ffc550614e385d395 void addPlayerToDistanceMaps(ServerPlayer player) { int chunkX = MCUtil.getChunkCoordinate(player.getX()); -@@ -235,6 +259,19 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - // Paper start - optimise PlayerChunkMap#isOutsideRange - this.playerChunkTickRangeMap.add(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); - // Paper end - optimise PlayerChunkMap#isOutsideRange + int chunkZ = MCUtil.getChunkCoordinate(player.getZ()); + // Note: players need to be explicitly added to distance maps before they can be updated + // Paper start - no-tick view distance + int effectiveTickViewDistance = this.getEffectiveViewDistance(); + int effectiveNoTickViewDistance = Math.max(this.getEffectiveNoTickViewDistance(), effectiveTickViewDistance); + -+ if (!this.cannotLoadChunks(player)) { ++ if (!this.skipPlayer(player)) { + this.playerViewDistanceTickMap.add(player, chunkX, chunkZ, effectiveTickViewDistance); + this.playerViewDistanceNoTickMap.add(player, chunkX, chunkZ, effectiveNoTickViewDistance + 2); // clients need chunk 1 neighbour, and we need another 1 for sending those extra neighbours (as we require neighbours to send) + } @@ -220,10 +197,7 @@ index 56ca469bf930bcced88efdafc78f464c756a5be9..6b51a082cf42bc3ffc550614e385d395 } void removePlayerFromDistanceMaps(ServerPlayer player) { -@@ -247,6 +284,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - this.playerMobSpawnMap.remove(player); - this.playerChunkTickRangeMap.remove(player); - // Paper end - optimise PlayerChunkMap#isOutsideRange + + // Paper start - no-tick view distance + this.playerViewDistanceBroadcastMap.remove(player); + this.playerViewDistanceTickMap.remove(player); @@ -232,15 +206,14 @@ index 56ca469bf930bcced88efdafc78f464c756a5be9..6b51a082cf42bc3ffc550614e385d395 } void updateMaps(ServerPlayer player) { -@@ -264,6 +306,19 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - // Paper start - optimise PlayerChunkMap#isOutsideRange - this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); - // Paper end - optimise PlayerChunkMap#isOutsideRange + int chunkX = MCUtil.getChunkCoordinate(player.getX()); + int chunkZ = MCUtil.getChunkCoordinate(player.getZ()); + // Note: players need to be explicitly added to distance maps before they can be updated + // Paper start - no-tick view distance + int effectiveTickViewDistance = this.getEffectiveViewDistance(); + int effectiveNoTickViewDistance = Math.max(this.getEffectiveNoTickViewDistance(), effectiveTickViewDistance); + -+ if (!this.cannotLoadChunks(player)) { ++ if (!this.skipPlayer(player)) { + this.playerViewDistanceTickMap.update(player, chunkX, chunkZ, effectiveTickViewDistance); + this.playerViewDistanceNoTickMap.update(player, chunkX, chunkZ, effectiveNoTickViewDistance + 2); // clients need chunk 1 neighbour, and we need another 1 for sending those extra neighbours (as we require neighbours to send) + } @@ -252,10 +225,10 @@ index 56ca469bf930bcced88efdafc78f464c756a5be9..6b51a082cf42bc3ffc550614e385d395 } // Paper end -@@ -371,6 +426,45 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - } - }); - // Paper end - optimise PlayerChunkMap#isOutsideRange +@@ -216,6 +263,45 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + this.overworldDataStorage = persistentStateManagerFactory; + this.poiManager = new PoiManager(new File(this.storageFolder, "poi"), dataFixer, dsync, world); + this.setViewDistance(viewDistance); + // Paper start - no-tick view distance + this.setNoTickViewDistance(this.level.paperConfig.noTickViewDistance); + this.playerViewDistanceTickMap = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets, @@ -297,10 +270,10 @@ index 56ca469bf930bcced88efdafc78f464c756a5be9..6b51a082cf42bc3ffc550614e385d395 + // Paper end - no-tick view distance } - public void updatePlayerMobTypeMap(Entity entity) { -@@ -1199,15 +1293,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + private static double euclideanDistanceSquared(ChunkPos pos, Entity entity) { +@@ -863,14 +949,10 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider completablefuture1.thenAcceptAsync((either) -> { - either.mapLeft((chunk) -> { + either.ifLeft((chunk) -> { this.tickingGenerated.getAndIncrement(); - Packet[] apacket = new Packet[2]; - @@ -308,7 +281,6 @@ index 56ca469bf930bcced88efdafc78f464c756a5be9..6b51a082cf42bc3ffc550614e385d395 - this.playerLoadedChunk(entityplayer, apacket, chunk); - }); + // Paper - no-tick view distance - moved to Chunk neighbour update - return Either.left(chunk); }); }, (runnable) -> { - this.mainThreadMailbox.tell(ChunkTaskPriorityQueueSorter.message(holder, runnable)); @@ -316,7 +288,7 @@ index 56ca469bf930bcced88efdafc78f464c756a5be9..6b51a082cf42bc3ffc550614e385d395 }); return completablefuture1; } -@@ -1302,32 +1392,38 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -962,28 +1044,35 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } } @@ -341,7 +313,7 @@ index 56ca469bf930bcced88efdafc78f464c756a5be9..6b51a082cf42bc3ffc550614e385d395 + } - this.getPlayers(chunkcoordintpair, false).forEach((entityplayer) -> { -- int l = checkerboardDistance(chunkcoordintpair, entityplayer, true); +- int l = ChunkMap.checkerboardDistance(chunkcoordintpair, entityplayer, true); - boolean flag = l <= k; - boolean flag1 = l <= this.viewDistance; + // Paper start - no-tick view distance @@ -356,21 +328,17 @@ index 56ca469bf930bcced88efdafc78f464c756a5be9..6b51a082cf42bc3ffc550614e385d395 + + if (this.level != null && this.level.players != null) { // this can be called from constructor, where these aren't set + for (ServerPlayer player : this.level.players) { -+ ServerGamePacketListenerImpl connection = player.connection; ++ net.minecraft.server.network.ServerGamePacketListenerImpl connection = player.connection; + if (connection != null) { + // moved in from PlayerList -+ connection.send(new ClientboundSetChunkCacheRadiusPacket(loadViewDistance)); ++ connection.send(new net.minecraft.network.protocol.game.ClientboundSetChunkCacheRadiusPacket(loadViewDistance)); + } + this.updateMaps(player); ++ // Paper end - no-tick view distance } } -- - } -+ // Paper end - no-tick view distance - protected void updateChunkTracking(ServerPlayer player, ChunkPos pos, Packet[] packets, boolean withinMaxWatchDistance, boolean withinViewDistance) { - if (player.level == this.level) { -@@ -1335,7 +1431,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -995,7 +1084,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos.toLong()); if (playerchunk != null) { @@ -379,15 +347,7 @@ index 56ca469bf930bcced88efdafc78f464c756a5be9..6b51a082cf42bc3ffc550614e385d395 if (chunk != null) { this.playerLoadedChunk(player, packets, chunk); -@@ -1596,6 +1692,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - } - // Paper end - optimise isOutsideOfRange - -+ private boolean cannotLoadChunks(ServerPlayer entityplayer) { return this.skipPlayer(entityplayer); } // Paper - OBFHELPER - private boolean skipPlayer(ServerPlayer player) { - return player.isSpectator() && !this.level.getGameRules().getBoolean(GameRules.RULE_SPECTATORSGENERATECHUNKS); - } -@@ -1623,13 +1720,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1202,13 +1291,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.removePlayerFromDistanceMaps(player); // Paper - distance maps } @@ -402,16 +362,16 @@ index 56ca469bf930bcced88efdafc78f464c756a5be9..6b51a082cf42bc3ffc550614e385d395 } -@@ -1637,7 +1728,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - SectionPos sectionposition = SectionPos.of((Entity) entityplayer); +@@ -1216,7 +1299,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + SectionPos sectionposition = SectionPos.of((Entity) player); - entityplayer.setLastSectionPos(sectionposition); -- entityplayer.connection.send(new ClientboundSetChunkCacheCenterPacket(sectionposition.x(), sectionposition.z())); -+ // Paper - distance map handles this now + player.setLastSectionPos(sectionposition); +- player.connection.send(new ClientboundSetChunkCacheCenterPacket(sectionposition.x(), sectionposition.z())); ++ // player.connection.send(new ClientboundSetChunkCacheCenterPacket(sectionposition.x(), sectionposition.z())); // Paper - distance map handles this now return sectionposition; } -@@ -1682,6 +1773,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1271,6 +1354,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider int k1; int l1; @@ -419,65 +379,26 @@ index 56ca469bf930bcced88efdafc78f464c756a5be9..6b51a082cf42bc3ffc550614e385d395 if (Math.abs(i1 - i) <= this.viewDistance * 2 && Math.abs(j1 - j) <= this.viewDistance * 2) { k1 = Math.min(i, i1) - this.viewDistance; l1 = Math.min(j, j1) - this.viewDistance; -@@ -1690,36 +1782,36 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - - for (int k2 = k1; k2 <= i2; ++k2) { - for (int l2 = l1; l2 <= j2; ++l2) { -- ChunkPos chunkcoordintpair = new ChunkPos(k2, l2); -- boolean flag3 = checkerboardDistance(chunkcoordintpair, i1, j1) <= this.viewDistance; -- boolean flag4 = checkerboardDistance(chunkcoordintpair, i, j) <= this.viewDistance; -+ ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(k2, l2); -+ boolean flag3 = a(chunkcoordintpair, i1, j1) <= this.viewDistance; -+ boolean flag4 = a(chunkcoordintpair, i, j) <= this.viewDistance; - -- this.updateChunkTracking(player, chunkcoordintpair, new Packet[2], flag3, flag4); -+ this.sendChunk(entityplayer, chunkcoordintpair, new Packet[2], flag3, flag4); +@@ -1309,6 +1393,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } } - } else { -- ChunkPos chunkcoordintpair1; -+ ChunkCoordIntPair chunkcoordintpair1; - boolean flag5; - boolean flag6; - - for (k1 = i1 - this.viewDistance; k1 <= i1 + this.viewDistance; ++k1) { - for (l1 = j1 - this.viewDistance; l1 <= j1 + this.viewDistance; ++l1) { -- chunkcoordintpair1 = new ChunkPos(k1, l1); -+ chunkcoordintpair1 = new ChunkCoordIntPair(k1, l1); - flag5 = true; - flag6 = false; -- this.updateChunkTracking(player, chunkcoordintpair1, new Packet[2], true, false); -+ this.sendChunk(entityplayer, chunkcoordintpair1, new Packet[2], true, false); - } - } - - for (k1 = i - this.viewDistance; k1 <= i + this.viewDistance; ++k1) { - for (l1 = j - this.viewDistance; l1 <= j + this.viewDistance; ++l1) { -- chunkcoordintpair1 = new ChunkPos(k1, l1); -+ chunkcoordintpair1 = new ChunkCoordIntPair(k1, l1); - flag5 = false; - flag6 = true; -- this.updateChunkTracking(player, chunkcoordintpair1, new Packet[2], false, true); -+ this.sendChunk(entityplayer, chunkcoordintpair1, new Packet[2], false, true); - } - } -- } -+ }*/ // Paper end - replaced by distance map + } ++ */ // Paper end - replaced by distance map this.updateMaps(player); // Paper - distance maps -@@ -1727,11 +1819,46 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1316,11 +1401,46 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @Override public Stream getPlayers(ChunkPos chunkPos, boolean onlyOnWatchDistanceEdge) { -- return this.playerMap.a(chunkPos.toLong()).filter((entityplayer) -> { -- int i = b(chunkcoordintpair, entityplayer, true); +- return this.playerMap.getPlayers(chunkPos.toLong()).filter((entityplayer) -> { +- int i = ChunkMap.checkerboardDistance(chunkPos, entityplayer, true); + // Paper start - per player view distance + // there can be potential desync with player's last mapped section and the view distance map, so use the + // view distance map here. + com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet inRange = this.playerViewDistanceBroadcastMap.getObjectsInRange(chunkPos); -- return i > this.viewDistance ? false : !flag || i == this.viewDistance; +- return i > this.viewDistance ? false : !onlyOnWatchDistanceEdge || i == this.viewDistance; - }); + if (inRange == null) { + return Stream.empty(); @@ -516,15 +437,15 @@ index 56ca469bf930bcced88efdafc78f464c756a5be9..6b51a082cf42bc3ffc550614e385d395 + // Paper end - per player view distance } - public void addEntity(Entity entity) { // Paper - protected -> public -@@ -1889,7 +2016,48 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + protected void addEntity(Entity entity) { +@@ -1442,7 +1562,48 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } -- private final void sendChunk(ServerPlayer entityplayer, Packet[] apacket, LevelChunk chunk) { this.playerLoadedChunk(entityplayer, apacket, chunk); } // Paper - OBFHELPER +- private void playerLoadedChunk(ServerPlayer player, Packet[] packets, LevelChunk chunk) { + // Paper start + private static int getLightMask(final LevelChunk chunk) { -+ final ChunkSection[] chunkSections = chunk.getSections(); ++ final net.minecraft.world.level.chunk.LevelChunkSection[] chunkSections = chunk.getSections(); + int mask = 0; + + for (int i = 0; i < chunkSections.length; ++i) { @@ -535,7 +456,7 @@ index 56ca469bf930bcced88efdafc78f464c756a5be9..6b51a082cf42bc3ffc550614e385d395 +Sections go from 0..16. Now whenever a section is not empty, it can potentially change lighting for the section itself, the section below and the section above, hence the bitmask 111b, which is 7d. + + */ -+ mask |= (ChunkSection.isEmpty(chunkSections[i]) ? 0 : 7) << i; ++ mask |= (net.minecraft.world.level.chunk.LevelChunkSection.isEmpty(chunkSections[i]) ? 0 : 7) << i; + } + + return mask; @@ -563,24 +484,15 @@ index 56ca469bf930bcced88efdafc78f464c756a5be9..6b51a082cf42bc3ffc550614e385d395 + } + // Paper end + -+ public final void sendChunk(ServerPlayer entityplayer, Packet[] apacket, LevelChunk chunk) { this.playerLoadedChunk(entityplayer, apacket, chunk); } // Paper - OBFHELPER - private void playerLoadedChunk(ServerPlayer player, Packet[] packets, LevelChunk chunk) { ++ public void playerLoadedChunk(ServerPlayer player, Packet[] packets, LevelChunk chunk) { // Paper - private -> public if (packets[0] == null) { - packets[0] = new ClientboundLevelChunkPacket(chunk, 65535, chunk.world.chunkPacketBlockController.shouldModify(player, chunk, 65535)); // Paper - Anti-Xray - Bypass -@@ -2075,7 +2243,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - ChunkPos chunkcoordintpair = new ChunkPos(this.entity.xChunk, this.entity.zChunk); - ChunkHolder playerchunk = ChunkMap.this.getVisibleChunkIfPresent(chunkcoordintpair.toLong()); - -- if (playerchunk != null && playerchunk.getTickingChunk() != null) { -+ if (playerchunk != null && playerchunk.getSendingChunk() != null) { // Paper - no-tick view distance - flag1 = ChunkMap.checkerboardDistance(chunkcoordintpair, player, false) <= ChunkMap.this.viewDistance; - } - } + packets[0] = new ClientboundLevelChunkPacket(chunk); + packets[1] = new ClientboundLightUpdatePacket(chunk.getPos(), this.lightEngine, (BitSet) null, (BitSet) null, true); diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java -index 91c672531087430c47365657a3219ab5980d3467..c9b4025f6c3d1be7bca2ff7337dd86e37d21b53e 100644 +index 45c7ebe67019cdbe88b6617a95d5c40d3a68286c..38eebda226e007c8910e04f502ce218cdfe1d456 100644 --- a/src/main/java/net/minecraft/server/level/DistanceManager.java +++ b/src/main/java/net/minecraft/server/level/DistanceManager.java -@@ -269,8 +269,8 @@ public abstract class DistanceManager { +@@ -275,8 +275,8 @@ public abstract class DistanceManager { return s; } @@ -591,7 +503,7 @@ index 91c672531087430c47365657a3219ab5980d3467..c9b4025f6c3d1be7bca2ff7337dd86e3 } public int getNaturalSpawnChunkCount() { -@@ -388,7 +388,7 @@ public abstract class DistanceManager { +@@ -503,7 +503,7 @@ public abstract class DistanceManager { private void onLevelChange(long pos, int distance, boolean oldWithinViewDistance, boolean withinViewDistance) { if (oldWithinViewDistance != withinViewDistance) { @@ -601,23 +513,22 @@ index 91c672531087430c47365657a3219ab5980d3467..c9b4025f6c3d1be7bca2ff7337dd86e3 if (withinViewDistance) { DistanceManager.this.ticketThrottlerInput.tell(ChunkTaskPriorityQueueSorter.message(() -> { diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 95f1f4727a8e2000931e6f36b862e3ad28334a69..8e4cef60b760be385df81a74834d026f856a78c5 100644 +index 4fef4c0240be90ddcb9640f5719e292d2d5dbdf8..bffc897cb88a54c36432c98264f3416051aeab17 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -249,6 +249,8 @@ public class ServerPlayer extends Player implements ContainerListener { - - double lastEntitySpawnRadiusSquared; // Paper - optimise isOutsideRange, this field is in blocks +@@ -241,6 +241,7 @@ public class ServerPlayer extends Player { + public PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper + public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet cachedSingleHashSet; // Paper + boolean needsChunkCenterUpdate; // Paper - no-tick view distance -+ - public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ServerPlayerGameMode interactionManager) { - super(world, world.getSpawn(), world.getSharedSpawnAngle(), profile); - this.respawnDimension = Level.OVERWORLD; + + public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile) { + super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile); diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index ffc8c9ee8b1768dd809189858ee45658fb9bf1c5..8e00747c1a717836d12a43aa48d667bf801167b0 100644 +index bcc946d2747443c34ee8ac2485a5ab41773c93af..2730923bd0bf3b0f928765b9e09e2299fa9a393d 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -250,7 +250,7 @@ public abstract class PlayerList { +@@ -241,7 +241,7 @@ public abstract class PlayerList { boolean flag1 = gamerules.getBoolean(GameRules.RULE_REDUCEDDEBUGINFO); // Spigot - view distance @@ -626,16 +537,16 @@ index ffc8c9ee8b1768dd809189858ee45658fb9bf1c5..8e00747c1a717836d12a43aa48d667bf player.getBukkitEntity().sendSupportedChannels(); // CraftBukkit playerconnection.send(new ClientboundCustomPayloadPacket(ClientboundCustomPayloadPacket.BRAND, (new FriendlyByteBuf(Unpooled.buffer())).writeUtf(this.getServer().getServerModName()))); playerconnection.send(new ClientboundChangeDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked())); -@@ -904,7 +904,7 @@ public abstract class PlayerList { +@@ -789,7 +789,7 @@ public abstract class PlayerList { // CraftBukkit start LevelData worlddata = worldserver1.getLevelData(); entityplayer1.connection.send(new ClientboundRespawnPacket(worldserver1.dimensionType(), worldserver1.dimension(), BiomeManager.obfuscateSeed(worldserver1.getSeed()), entityplayer1.gameMode.getGameModeForPlayer(), entityplayer1.gameMode.getPreviousGameModeForPlayer(), worldserver1.isDebug(), worldserver1.isFlat(), flag)); - entityplayer1.connection.send(new ClientboundSetChunkCacheRadiusPacket(worldserver1.spigotConfig.viewDistance)); // Spigot + entityplayer1.connection.send(new ClientboundSetChunkCacheRadiusPacket(worldserver1.getChunkSource().chunkMap.getLoadViewDistance())); // Spigot // Paper - no-tick view distance entityplayer1.setLevel(worldserver1); - entityplayer1.removed = false; - entityplayer1.connection.teleport(new Location(worldserver1.getWorld(), entityplayer1.getX(), entityplayer1.getY(), entityplayer1.getZ(), entityplayer1.yRot, entityplayer1.xRot)); -@@ -1372,7 +1372,7 @@ public abstract class PlayerList { + entityplayer1.unsetRemoved(); + entityplayer1.connection.teleport(new Location(worldserver1.getWorld(), entityplayer1.getX(), entityplayer1.getY(), entityplayer1.getZ(), entityplayer1.getYRot(), entityplayer1.getXRot())); +@@ -1273,7 +1273,7 @@ public abstract class PlayerList { public void setViewDistance(int viewDistance) { this.viewDistance = viewDistance; @@ -645,10 +556,10 @@ index ffc8c9ee8b1768dd809189858ee45658fb9bf1c5..8e00747c1a717836d12a43aa48d667bf while (iterator.hasNext()) { diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 5860e7866724abd35bde2a5710d9c92799e5de67..67ab681a9c9157a420de5fd872bde1fc0de24561 100644 +index ddcde88a8c8b748b4dc2583b4dfd0fb8ea9e201e..07e81fa1119bba4981e34e70b9e67f43280f8071 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -525,8 +525,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -521,8 +521,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable { this.setBlocksDirty(blockposition, iblockdata1, iblockdata2); } @@ -664,30 +575,26 @@ index 5860e7866724abd35bde2a5710d9c92799e5de67..67ab681a9c9157a420de5fd872bde1fc if ((i & 1) != 0) { 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 8a14bdda4a408ec1e2b51efeb35467835f62b42c..dbea2a4370ccf24a5084cdabeecbc81f206e910a 100644 +index 521f199e495f3bec232cc9ca36e51e0392afe737..922026da8c234427e0322443004d3c32993adfce 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -27,9 +27,14 @@ import net.minecraft.core.BlockPos; - import net.minecraft.core.Registry; +@@ -33,7 +33,10 @@ import net.minecraft.core.Registry; + import net.minecraft.core.SectionPos; import net.minecraft.nbt.CompoundTag; - import net.minecraft.server.MinecraftServer; + import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.protocol.Packet; import net.minecraft.server.level.ChunkHolder; +import net.minecraft.server.level.ChunkMap; +import net.minecraft.server.level.ChunkTaskPriorityQueueSorter; import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.server.level.TicketType; - import net.minecraft.util.Mth; - import net.minecraft.world.Container; - import net.minecraft.world.entity.Entity; -@@ -242,7 +247,51 @@ public class LevelChunk implements ChunkAccess { + import net.minecraft.util.profiling.ProfilerFiller; +@@ -227,7 +230,51 @@ public class LevelChunk implements ChunkAccess { } protected void onNeighbourChange(final long bitsetBefore, final long bitsetAfter) { + // Paper start - no-tick view distance -+ ServerChunkCache chunkProviderServer = ((ServerLevel)this.world).getChunkSource(); ++ ServerChunkCache chunkProviderServer = ((ServerLevel)this.level).getChunkSource(); + ChunkMap chunkMap = chunkProviderServer.chunkMap; + // this code handles the addition of ticking tickets - the distance map handles the removal + if (!areNeighboursLoaded(bitsetBefore, 2) && areNeighboursLoaded(bitsetAfter, 2)) { @@ -696,7 +603,7 @@ index 8a14bdda4a408ec1e2b51efeb35467835f62b42c..dbea2a4370ccf24a5084cdabeecbc81f + chunkProviderServer.mainThreadProcessor.execute(() -> { + // double check that this condition still holds. + if (LevelChunk.this.areNeighboursLoaded(2) && chunkMap.playerViewDistanceTickMap.getObjectsInRange(LevelChunk.this.coordinateKey) != null) { -+ chunkProviderServer.addTicketAtLevel(TicketType.PLAYER, LevelChunk.this.chunkPos, 31, LevelChunk.this.chunkPos); // 31 -> entity ticking, TODO check on update ++ chunkProviderServer.addTicketAtLevel(net.minecraft.server.level.TicketType.PLAYER, LevelChunk.this.chunkPos, 31, LevelChunk.this.chunkPos); // 31 -> entity ticking, TODO check on update + } + }); + } @@ -711,7 +618,7 @@ index 8a14bdda4a408ec1e2b51efeb35467835f62b42c..dbea2a4370ccf24a5084cdabeecbc81f + if (!LevelChunk.this.areNeighboursLoaded(1)) { + return; + } -+ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet inRange = chunkMap.playerViewDistanceBroadcastMap.getObjectsInRange(LevelChunk.this.coordinateKey); ++ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet inRange = chunkMap.playerViewDistanceBroadcastMap.getObjectsInRange(LevelChunk.this.coordinateKey); + if (inRange == null) { + return; + } @@ -721,11 +628,11 @@ index 8a14bdda4a408ec1e2b51efeb35467835f62b42c..dbea2a4370ccf24a5084cdabeecbc81f + Packet[] chunkPackets = new Packet[2]; + for (int index = 0, len = backingSet.length; index < len; ++index) { + Object temp = backingSet[index]; -+ if (!(temp instanceof ServerPlayer)) { ++ if (!(temp instanceof net.minecraft.server.level.ServerPlayer)) { + continue; + } -+ ServerPlayer player = (ServerPlayer)temp; -+ chunkMap.sendChunk(player, chunkPackets, LevelChunk.this); ++ net.minecraft.server.level.ServerPlayer player = (net.minecraft.server.level.ServerPlayer)temp; ++ chunkMap.playerLoadedChunk(player, chunkPackets, LevelChunk.this); + } + }))); + } @@ -734,28 +641,20 @@ index 8a14bdda4a408ec1e2b51efeb35467835f62b42c..dbea2a4370ccf24a5084cdabeecbc81f } public final boolean isAnyNeighborsLoaded() { -@@ -1131,7 +1180,7 @@ public class LevelChunk implements ChunkAccess { +@@ -1005,7 +1052,7 @@ public class LevelChunk implements ChunkAccess { BlockState iblockdata = this.getBlockState(blockposition); - BlockState iblockdata1 = Block.updateFromNeighbourShapes(iblockdata, (LevelAccessor) this.world, blockposition); + BlockState iblockdata1 = Block.updateFromNeighbourShapes(iblockdata, (LevelAccessor) this.level, blockposition); -- this.world.setBlock(blockposition, iblockdata1, 20); -+ this.world.setBlock(blockposition, iblockdata1, 20 | 2); // Paper - We send chunks before they're ticking ready, so we need to notify here +- this.level.setBlock(blockposition, iblockdata1, 20); ++ this.level.setBlock(blockposition, iblockdata1, 20 | 2); // Paper - We send chunks before they're ticking ready, so we need to notify here } this.postProcessing[i].clear(); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 1a839242e359fa32f32d0e571c6e918ac39642e9..4fc44390f432ef13c9952aa22bbb29bc8bf47975 100644 +index f1cbcdb1e409f8544125dde5f24bff5b07cb5082..1d22119b962840dff789a0619fd2188958f924d0 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -31,6 +31,7 @@ import net.minecraft.network.protocol.game.ClientboundLevelEventPacket; - import net.minecraft.network.protocol.game.ClientboundSetTimePacket; - import net.minecraft.resources.ResourceLocation; - import net.minecraft.server.level.ChunkHolder; -+import net.minecraft.server.level.ChunkMap; - import net.minecraft.server.level.DistanceManager; - import net.minecraft.server.level.ServerLevel; - import net.minecraft.server.level.Ticket; -@@ -2532,10 +2533,39 @@ public class CraftWorld implements World { +@@ -2540,10 +2540,39 @@ public class CraftWorld implements World { // Spigot start @Override public int getViewDistance() { @@ -770,7 +669,7 @@ index 1a839242e359fa32f32d0e571c6e918ac39642e9..4fc44390f432ef13c9952aa22bbb29bc + if (viewDistance < 2 || viewDistance > 32) { + throw new IllegalArgumentException("View distance " + viewDistance + " is out of range of [2, 32]"); + } -+ ChunkMap chunkMap = getHandle().getChunkSource().chunkMap; ++ net.minecraft.server.level.ChunkMap chunkMap = getHandle().getChunkSource().chunkMap; + if (viewDistance != chunkMap.getEffectiveViewDistance()) { + chunkMap.setViewDistance(viewDistance); + } @@ -786,7 +685,7 @@ index 1a839242e359fa32f32d0e571c6e918ac39642e9..4fc44390f432ef13c9952aa22bbb29bc + if ((viewDistance < 2 || viewDistance > 32) && viewDistance != -1) { + throw new IllegalArgumentException("View distance " + viewDistance + " is out of range of [2, 32]"); + } -+ ChunkMap chunkMap = getHandle().getChunkSource().chunkMap; ++ net.minecraft.server.level.ChunkMap chunkMap = getHandle().getChunkSource().chunkMap; + if (viewDistance != chunkMap.getRawNoTickViewDistance()) { + chunkMap.setNoTickViewDistance(viewDistance); + } @@ -797,23 +696,15 @@ index 1a839242e359fa32f32d0e571c6e918ac39642e9..4fc44390f432ef13c9952aa22bbb29bc private final org.bukkit.World.Spigot spigot = new org.bukkit.World.Spigot() { diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index 8cbafad53d20366a36493f22160c4fa3e4ac3eaf..20d5da61fc0594e86c68ea8fb5ebe5517f27f126 100644 +index 2ab585a018290996e7fa9ca6f3ad7d734cd7beaa..a08583863f9fa08016bdfc7949a273eaa4429927 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java -@@ -4,6 +4,7 @@ import java.util.Collection; - import net.minecraft.core.BlockPos; - import net.minecraft.server.MinecraftServer; - import net.minecraft.server.level.ServerChunkCache; -+import net.minecraft.server.level.ServerLevel; - import net.minecraft.util.Mth; - import net.minecraft.world.entity.Entity; - import net.minecraft.world.entity.FlyingMob; -@@ -192,7 +193,7 @@ public class ActivationRange +@@ -188,7 +188,7 @@ public class ActivationRange maxRange = Math.max( maxRange, waterActivationRange ); maxRange = Math.max( maxRange, villagerActivationRange ); // Paper end - maxRange = Math.min( ( world.spigotConfig.viewDistance << 4 ) - 8, maxRange ); -+ maxRange = Math.min( ( ((ServerLevel)world).getChunkSource().chunkMap.getEffectiveViewDistance() << 4 ) - 8, maxRange ); // Paper - no-tick view distance ++ maxRange = Math.min( ( ((net.minecraft.server.level.ServerLevel)world).getChunkSource().chunkMap.getEffectiveViewDistance() << 4 ) - 8, maxRange ); // Paper - no-tick view distance for ( Player player : world.players() ) {