From 2a46c72164697a80f7b257dcc26b980c48b505ff Mon Sep 17 00:00:00 2001 From: Jake Potrebic <15055071+Machine-Maker@users.noreply.github.com> Date: Sun, 13 Jun 2021 18:06:38 -0700 Subject: [PATCH] EVEN MOOOOOAAAAAAARRRRRRR patches :) (#5820) --- Paper-MojangAPI/build.gradle.kts | 26 ++ ...-get-a-BlockState-without-a-snapshot.patch | 4 +- patches/api/0116-RangedEntity-API.patch | 19 +- ...Blocks-to-be-accessed-via-a-long-key.patch | 4 +- .../0181-Add-BlockSoundGroup-interface.patch | 14 +- ...-Add-effect-to-block-break-naturally.patch | 4 +- .../0191-Add-tick-times-API.patch} | 4 +- ...92-Expose-MinecraftServer-isRunning.patch} | 4 +- ...dd-Raw-Byte-ItemStack-Serialization.patch} | 2 +- ...ts-firing-Async-errors-during-shutd.patch} | 2 +- ...5-Make-JavaPluginLoader-thread-safe.patch} | 0 .../0196-Add-Player-Client-Options-API.patch} | 4 +- ...layerAttackEntityCooldownResetEvent.patch} | 0 ...Stack-swapping-the-extended-and-upg.patch} | 0 .../0199-Villager-Restocks-API.patch} | 0 .../0200-Expose-game-version.patch} | 4 +- ...ions-until-after-entity-ticking-is-d.patch | 2 + ...oviderServer-s-chunk-level-checking-.patch | 2 + ...Add-Raw-Byte-ItemStack-Serialization.patch | 102 ----- ...0441-Remove-streams-from-PairedQueue.patch | 79 ---- ...Load-Chunks-for-Login-Asynchronously.patch | 416 ------------------ .../0464-Optimize-Voxel-Shape-Merging.patch | 175 -------- patches/server/0010-Adventure.patch | 4 +- patches/server/0025-Entity-Origin-API.patch | 4 +- .../server/0051-Add-velocity-warnings.patch | 4 +- ...rovide-E-TE-Chunk-count-stat-methods.patch | 4 +- ...PI-for-Reason-Source-Triggering-play.patch | 4 +- .../server/0147-Entity-fromMobSpawner.patch | 4 +- ...-get-a-BlockState-without-a-snapshot.patch | 4 +- ...ld.spawnParticle-API-and-add-Builder.patch | 4 +- ...Item-entities-with-World.spawnEntity.patch | 4 +- .../0206-Fix-CraftEntity-hashCode.patch | 4 +- .../server/0213-Expand-Explosions-API.patch | 4 +- patches/server/0215-RangedEntity-API.patch | 12 +- ...7-Implement-World.getEntity-UUID-API.patch | 4 +- ...loadChunk-int-int-false-load-unconve.patch | 4 +- ...57-Asynchronous-chunk-IO-and-loading.patch | 8 +- patches/server/0272-Add-sun-related-API.patch | 4 +- .../0312-Entity-getEntitySpawnReason.patch | 4 +- patches/server/0320-Add-Heightmap-API.patch | 4 +- ...325-improve-CraftWorld-isChunkLoaded.patch | 4 +- ...le-Keep-Spawn-Loaded-range-per-world.patch | 4 +- .../0328-Implement-CraftBlockSoundGroup.patch | 9 +- ...330-Fix-World-isChunkGenerated-calls.patch | 6 +- ...hanging-entities-that-are-not-ItemFr.patch | 4 +- ...-Add-effect-to-block-break-naturally.patch | 6 +- ...No-Tick-view-distance-implementation.patch | 4 +- ...hunkMap-memory-use-for-visibleChunks.patch | 12 +- ...Add-tick-times-API-and-mspt-command.patch} | 21 +- ...90-Expose-MinecraftServer-isRunning.patch} | 4 +- ...Add-Raw-Byte-ItemStack-Serialization.patch | 58 +++ ...2-Remove-streams-from-Mob-AI-System.patch} | 169 +++---- .../0393-Async-command-map-building.patch} | 6 +- .../0394-Improved-Watchdog-Support.patch} | 169 +++---- .../0395-Optimize-Pathfinding.patch} | 32 +- ...6-Reduce-Either-Optional-allocation.patch} | 2 +- ...0397-Remove-streams-from-PairedQueue.patch | 46 ++ ...-memory-footprint-of-NBTTagCompound.patch} | 35 +- ...ent-opening-inventories-when-frozen.patch} | 29 +- ...00-Optimise-ArraySetSorted-removeIf.patch} | 30 +- ...entity-collision-code-if-not-needed.patch} | 8 +- ...teleport-command-to-valid-locations.patch} | 4 +- ...Implement-Player-Client-Options-API.patch} | 90 +--- ...Chunk-Post-Processing-deadlock-risk.patch} | 13 +- ...ayer-is-attempted-to-be-removed-fro.patch} | 4 +- ...6-Broadcast-join-message-to-console.patch} | 8 +- ...-Broken-behavior-of-PlayerJoinEvent.patch} | 72 +-- ...Load-Chunks-for-Login-Asynchronously.patch | 277 ++++++++++++ ...awn-point-if-spawn-in-unloaded-worl.patch} | 6 +- ...layerAttackEntityCooldownResetEvent.patch} | 4 +- ...llbacks-to-schedule-for-Callback-Ex.patch} | 38 +- ...-fire-BlockFade-on-worldgen-threads.patch} | 8 +- ...tom-creative-and-insomniac-controls.patch} | 39 +- ...-duplication-issues-and-teleport-is.patch} | 24 +- ...0415-Implement-Brigadier-Mojang-API.patch} | 34 +- .../0416-Villager-Restocks-API.patch} | 10 +- ...ickItem-Packet-and-kick-for-invalid.patch} | 16 +- .../0418-Expose-game-version.patch} | 6 +- .../0419-Optimize-Voxel-Shape-Merging.patch | 121 +++++ settings.gradle.kts | 2 +- work/Bukkit | 2 +- work/CraftBukkit | 2 +- 82 files changed, 971 insertions(+), 1418 deletions(-) create mode 100644 Paper-MojangAPI/build.gradle.kts rename patches/{api-unmapped/0190-Add-tick-times-API.patch => api/0191-Add-tick-times-API.patch} (90%) rename patches/{api-unmapped/0191-Expose-MinecraftServer-isRunning.patch => api/0192-Expose-MinecraftServer-isRunning.patch} (88%) rename patches/{api-unmapped/0206-Add-Raw-Byte-ItemStack-Serialization.patch => api/0193-Add-Raw-Byte-ItemStack-Serialization.patch} (96%) rename patches/{api-unmapped/0192-Disable-Sync-Events-firing-Async-errors-during-shutd.patch => api/0194-Disable-Sync-Events-firing-Async-errors-during-shutd.patch} (93%) rename patches/{api-unmapped/0193-Make-JavaPluginLoader-thread-safe.patch => api/0195-Make-JavaPluginLoader-thread-safe.patch} (100%) rename patches/{api-unmapped/0194-Add-Player-Client-Options-API.patch => api/0196-Add-Player-Client-Options-API.patch} (97%) rename patches/{api-unmapped/0195-Add-PlayerAttackEntityCooldownResetEvent.patch => api/0197-Add-PlayerAttackEntityCooldownResetEvent.patch} (100%) rename patches/{api-unmapped/0196-Fix-Potion-toItemStack-swapping-the-extended-and-upg.patch => api/0198-Fix-Potion-toItemStack-swapping-the-extended-and-upg.patch} (100%) rename patches/{api-unmapped/0197-Villager-Restocks-API.patch => api/0199-Villager-Restocks-API.patch} (100%) rename patches/{api-unmapped/0198-Expose-game-version.patch => api/0200-Expose-game-version.patch} (89%) rename patches/{server-remapped => removed/1.17}/0436-Delay-unsafe-actions-until-after-entity-ticking-is-d.patch (95%) rename patches/{server-remapped => removed/1.17}/0446-Optimize-ChunkProviderServer-s-chunk-level-checking-.patch (99%) delete mode 100644 patches/server-remapped/0434-Add-Raw-Byte-ItemStack-Serialization.patch delete mode 100644 patches/server-remapped/0441-Remove-streams-from-PairedQueue.patch delete mode 100644 patches/server-remapped/0453-Load-Chunks-for-Login-Asynchronously.patch delete mode 100644 patches/server-remapped/0464-Optimize-Voxel-Shape-Merging.patch rename patches/{server-remapped/0432-Add-tick-times-API-and-mspt-command.patch => server/0389-Add-tick-times-API-and-mspt-command.patch} (89%) rename patches/{server-remapped/0433-Expose-MinecraftServer-isRunning.patch => server/0390-Expose-MinecraftServer-isRunning.patch} (83%) create mode 100644 patches/server/0391-Add-Raw-Byte-ItemStack-Serialization.patch rename patches/{server-remapped/0435-Remove-streams-from-Mob-AI-System.patch => server/0392-Remove-streams-from-Mob-AI-System.patch} (58%) rename patches/{server-remapped/0437-Async-command-map-building.patch => server/0393-Async-command-map-building.patch} (95%) rename patches/{server-remapped/0438-Improved-Watchdog-Support.patch => server/0394-Improved-Watchdog-Support.patch} (81%) rename patches/{server-remapped/0439-Optimize-Pathfinding.patch => server/0395-Optimize-Pathfinding.patch} (51%) rename patches/{server-remapped/0440-Reduce-Either-Optional-allocation.patch => server/0396-Reduce-Either-Optional-allocation.patch} (95%) create mode 100644 patches/server/0397-Remove-streams-from-PairedQueue.patch rename patches/{server-remapped/0442-Reduce-memory-footprint-of-NBTTagCompound.patch => server/0398-Reduce-memory-footprint-of-NBTTagCompound.patch} (50%) rename patches/{server-remapped/0443-Prevent-opening-inventories-when-frozen.patch => server/0399-Prevent-opening-inventories-when-frozen.patch} (76%) rename patches/{server-remapped/0444-Optimise-ArraySetSorted-removeIf.patch => server/0400-Optimise-ArraySetSorted-removeIf.patch} (60%) rename patches/{server-remapped/0445-Don-t-run-entity-collision-code-if-not-needed.patch => server/0401-Don-t-run-entity-collision-code-if-not-needed.patch} (81%) rename patches/{server-remapped/0447-Restrict-vanilla-teleport-command-to-valid-locations.patch => server/0402-Restrict-vanilla-teleport-command-to-valid-locations.patch} (90%) rename patches/{server-remapped/0448-Implement-Player-Client-Options-API.patch => server/0403-Implement-Player-Client-Options-API.patch} (50%) rename patches/{server-remapped/0449-Fix-Chunk-Post-Processing-deadlock-risk.patch => server/0404-Fix-Chunk-Post-Processing-deadlock-risk.patch} (87%) rename patches/{server-remapped/0450-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch => server/0405-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch} (88%) rename patches/{server-remapped/0451-Broadcast-join-message-to-console.patch => server/0406-Broadcast-join-message-to-console.patch} (65%) rename patches/{server-remapped/0452-Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch => server/0407-Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch} (61%) create mode 100644 patches/server/0408-Load-Chunks-for-Login-Asynchronously.patch rename patches/{server-remapped/0454-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch => server/0409-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch} (79%) rename patches/{server-remapped/0455-Add-PlayerAttackEntityCooldownResetEvent.patch => server/0410-Add-PlayerAttackEntityCooldownResetEvent.patch} (92%) rename patches/{server-remapped/0456-Allow-multiple-callbacks-to-schedule-for-Callback-Ex.patch => server/0411-Allow-multiple-callbacks-to-schedule-for-Callback-Ex.patch} (63%) rename patches/{server-remapped/0457-Don-t-fire-BlockFade-on-worldgen-threads.patch => server/0412-Don-t-fire-BlockFade-on-worldgen-threads.patch} (80%) rename patches/{server-remapped/0458-Add-phantom-creative-and-insomniac-controls.patch => server/0413-Add-phantom-creative-and-insomniac-controls.patch} (68%) rename patches/{server-remapped/0459-Fix-numerous-item-duplication-issues-and-teleport-is.patch => server/0414-Fix-numerous-item-duplication-issues-and-teleport-is.patch} (85%) rename patches/{server-remapped/0460-Implement-Brigadier-Mojang-API.patch => server/0415-Implement-Brigadier-Mojang-API.patch} (86%) rename patches/{server-remapped/0461-Villager-Restocks-API.patch => server/0416-Villager-Restocks-API.patch} (60%) rename patches/{server-remapped/0462-Validate-PickItem-Packet-and-kick-for-invalid.patch => server/0417-Validate-PickItem-Packet-and-kick-for-invalid.patch} (65%) rename patches/{server-remapped/0463-Expose-game-version.patch => server/0418-Expose-game-version.patch} (78%) create mode 100644 patches/server/0419-Optimize-Voxel-Shape-Merging.patch diff --git a/Paper-MojangAPI/build.gradle.kts b/Paper-MojangAPI/build.gradle.kts new file mode 100644 index 000000000..e0ef6532b --- /dev/null +++ b/Paper-MojangAPI/build.gradle.kts @@ -0,0 +1,26 @@ +plugins { + `java-library` + checkstyle +} + +java { + withSourcesJar() + withJavadocJar() +} + +repositories { + mavenCentral() + maven("https://libraries.minecraft.net") +} + +dependencies { + implementation(project(":Paper-API")) + api("com.mojang:brigadier:1.0.18") + + compileOnly("it.unimi.dsi:fastutil") + compileOnly("org.jetbrains:annotations:18.0.0") + + testImplementation("junit:junit:4.13.1") + testImplementation("org.hamcrest:hamcrest-library:1.3") + testImplementation("org.ow2.asm:asm-tree:7.3.1") +} \ No newline at end of file diff --git a/patches/api/0072-API-to-get-a-BlockState-without-a-snapshot.patch b/patches/api/0072-API-to-get-a-BlockState-without-a-snapshot.patch index 17364528b..26c4c4cc1 100644 --- a/patches/api/0072-API-to-get-a-BlockState-without-a-snapshot.patch +++ b/patches/api/0072-API-to-get-a-BlockState-without-a-snapshot.patch @@ -9,10 +9,10 @@ on the real tile entity. This is useful for where performance is needed diff --git a/src/main/java/org/bukkit/block/Block.java b/src/main/java/org/bukkit/block/Block.java -index d4c69573f250309adc442c7cf67ea6fc2f2e3ace..969a6cf404d99c186e73321659240195b8650ffc 100644 +index da0964b1b6555ad50cb2ee47f13a7b9dfb1ab6aa..3ca05a6e86a5329cf452041eac476e3636eec34a 100644 --- a/src/main/java/org/bukkit/block/Block.java +++ b/src/main/java/org/bukkit/block/Block.java -@@ -269,6 +269,16 @@ public interface Block extends Metadatable { +@@ -271,6 +271,16 @@ public interface Block extends Metadatable { @NotNull BlockState getState(); diff --git a/patches/api/0116-RangedEntity-API.patch b/patches/api/0116-RangedEntity-API.patch index f609bc2f0..c86139036 100644 --- a/patches/api/0116-RangedEntity-API.patch +++ b/patches/api/0116-RangedEntity-API.patch @@ -122,23 +122,18 @@ index 9a2252fef56be1ed3ae2169aea46cb567e965c6c..11f38187fca830d974be01fea2966a31 -public interface Pillager extends Illager, InventoryHolder { } +public interface Pillager extends Illager, InventoryHolder, RangedEntity { } // Paper diff --git a/src/main/java/org/bukkit/entity/Skeleton.java b/src/main/java/org/bukkit/entity/Skeleton.java -index 16b1293887cee2bc5267f3da771fb5a6ece1b4e9..1c367f78eadf24850061a84ce63b950b79d3c435 100644 +index 01d838a60d056bf4b4a8ef9d0ac18c6f91f412e6..b7e424ea8a282f45fb8b91c919e4e4526c00be8b 100644 --- a/src/main/java/org/bukkit/entity/Skeleton.java +++ b/src/main/java/org/bukkit/entity/Skeleton.java -@@ -2,11 +2,12 @@ package org.bukkit.entity; - - import org.jetbrains.annotations.Contract; - import org.jetbrains.annotations.NotNull; -+import com.destroystokyo.paper.entity.RangedEntity; - - /** - * Represents a Skeleton. +@@ -7,7 +7,7 @@ package org.bukkit.entity; + * Other skeleton-like entities, such as the {@link WitherSkeleton} or the + * {@link Stray} are not related to this type. */ --public interface Skeleton extends Monster { -+public interface Skeleton extends Monster, RangedEntity { // Paper +-public interface Skeleton extends AbstractSkeleton { ++public interface Skeleton extends AbstractSkeleton, com.destroystokyo.paper.entity.RangedEntity { // Paper /** - * Gets the current type of this skeleton. + * Computes whether or not this skeleton is currently in the process of diff --git a/src/main/java/org/bukkit/entity/Snowman.java b/src/main/java/org/bukkit/entity/Snowman.java index 818efe2a4d1ac0c4d8dca6c757850d99cdc2cb4b..10f8f6d45ae9280651c3ebddd1f90acbd7d6ff29 100644 --- a/src/main/java/org/bukkit/entity/Snowman.java diff --git a/patches/api/0139-Allow-Blocks-to-be-accessed-via-a-long-key.patch b/patches/api/0139-Allow-Blocks-to-be-accessed-via-a-long-key.patch index 7014671c6..6591a86ae 100644 --- a/patches/api/0139-Allow-Blocks-to-be-accessed-via-a-long-key.patch +++ b/patches/api/0139-Allow-Blocks-to-be-accessed-via-a-long-key.patch @@ -91,10 +91,10 @@ index f45bea24a350c3700bdbf4c44aeb1c0562e57d9e..a653a09968123724f9ec5501760257b3 * Gets the highest non-empty (impassable) coordinate at the given * coordinates. diff --git a/src/main/java/org/bukkit/block/Block.java b/src/main/java/org/bukkit/block/Block.java -index 969a6cf404d99c186e73321659240195b8650ffc..b090938f883c486e703cb7c036c47925f3016704 100644 +index 3ca05a6e86a5329cf452041eac476e3636eec34a..18ab5cca036522df2d245f755d6c67904e6398e8 100644 --- a/src/main/java/org/bukkit/block/Block.java +++ b/src/main/java/org/bukkit/block/Block.java -@@ -153,6 +153,72 @@ public interface Block extends Metadatable { +@@ -155,6 +155,72 @@ public interface Block extends Metadatable { */ int getZ(); diff --git a/patches/api/0181-Add-BlockSoundGroup-interface.patch b/patches/api/0181-Add-BlockSoundGroup-interface.patch index 428810f1d..566c91565 100644 --- a/patches/api/0181-Add-BlockSoundGroup-interface.patch +++ b/patches/api/0181-Add-BlockSoundGroup-interface.patch @@ -64,21 +64,13 @@ index 0000000000000000000000000000000000000000..8cf87d228a7006658d52ce0da16c2d74 + Sound getFallSound(); +} diff --git a/src/main/java/org/bukkit/block/Block.java b/src/main/java/org/bukkit/block/Block.java -index b090938f883c486e703cb7c036c47925f3016704..5e2aa4fb8cf8130df21d3172dd94e857317f7653 100644 +index 18ab5cca036522df2d245f755d6c67904e6398e8..5ac36e0f90d0889853736390877aa92ec0ca181b 100644 --- a/src/main/java/org/bukkit/block/Block.java +++ b/src/main/java/org/bukkit/block/Block.java -@@ -1,6 +1,7 @@ - package org.bukkit.block; - - import java.util.Collection; -+ - import org.bukkit.Chunk; - import org.bukkit.FluidCollisionMode; - import org.bukkit.Location; -@@ -560,4 +561,16 @@ public interface Block extends Metadatable { +@@ -587,4 +587,16 @@ public interface Block extends Metadatable { */ @NotNull - BoundingBox getBoundingBox(); + VoxelShape getCollisionShape(); + + // Paper start + /** diff --git a/patches/api/0186-Add-effect-to-block-break-naturally.patch b/patches/api/0186-Add-effect-to-block-break-naturally.patch index 5ccd8c254..ce1785047 100644 --- a/patches/api/0186-Add-effect-to-block-break-naturally.patch +++ b/patches/api/0186-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/block/Block.java b/src/main/java/org/bukkit/block/Block.java -index 5e2aa4fb8cf8130df21d3172dd94e857317f7653..e1cc36fbe808973227c0e8ca7166453235c90279 100644 +index 5ac36e0f90d0889853736390877aa92ec0ca181b..786b8011e98b2fe93cc2418d624f6350ede62d90 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 { +@@ -470,6 +470,18 @@ public interface Block extends Metadatable { */ boolean breakNaturally(@Nullable ItemStack tool); diff --git a/patches/api-unmapped/0190-Add-tick-times-API.patch b/patches/api/0191-Add-tick-times-API.patch similarity index 90% rename from patches/api-unmapped/0190-Add-tick-times-API.patch rename to patches/api/0191-Add-tick-times-API.patch index a4ae8d485..b4d7379b4 100644 --- a/patches/api-unmapped/0190-Add-tick-times-API.patch +++ b/patches/api/0191-Add-tick-times-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add tick times API diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index 49bf621a2c0e5e9641b334a42b2769944c991d5d..4bae8a4387b86c868149f06b490ef6dfced2ff41 100644 +index 02f91b446697b1c637fda3b65b48ec8cf38de66d..1eeb1257888ef2e2d92598e2b1a80286a087dfa5 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java @@ -1590,6 +1590,25 @@ public final class Bukkit { @@ -35,7 +35,7 @@ index 49bf621a2c0e5e9641b334a42b2769944c991d5d..4bae8a4387b86c868149f06b490ef6df /** diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index e448ae78304974f7664b7ef18568a547833ece9f..bea7ffdb00e6de1391e9143901c62f0aceaaf727 100644 +index b038a82ffc298abb5129b6ec20538df5d0b6f595..3c9890ce33231070836ee471206b20cec74e00b4 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java @@ -1345,6 +1345,21 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi diff --git a/patches/api-unmapped/0191-Expose-MinecraftServer-isRunning.patch b/patches/api/0192-Expose-MinecraftServer-isRunning.patch similarity index 88% rename from patches/api-unmapped/0191-Expose-MinecraftServer-isRunning.patch rename to patches/api/0192-Expose-MinecraftServer-isRunning.patch index 33f257012..4a5c20868 100644 --- a/patches/api-unmapped/0191-Expose-MinecraftServer-isRunning.patch +++ b/patches/api/0192-Expose-MinecraftServer-isRunning.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Expose MinecraftServer#isRunning This allows for plugins to detect if the server is actually turning off in onDisable rather than just plugins reloading. diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index 4bae8a4387b86c868149f06b490ef6dfced2ff41..4dadea432c8d79b15fa126b4f0c810e9a72b4029 100644 +index 1eeb1257888ef2e2d92598e2b1a80286a087dfa5..847ba5143660d5c56ff8f2cae2169a51b8927757 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java @@ -1858,6 +1858,15 @@ public final class Bukkit { @@ -26,7 +26,7 @@ index 4bae8a4387b86c868149f06b490ef6dfced2ff41..4dadea432c8d79b15fa126b4f0c810e9 @NotNull diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index bea7ffdb00e6de1391e9143901c62f0aceaaf727..b92261e09790e89788560bf7c9784c8399504810 100644 +index 3c9890ce33231070836ee471206b20cec74e00b4..e6b62ba32e089e2fd8563ec8430b72196f6680e0 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java @@ -1631,5 +1631,12 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi diff --git a/patches/api-unmapped/0206-Add-Raw-Byte-ItemStack-Serialization.patch b/patches/api/0193-Add-Raw-Byte-ItemStack-Serialization.patch similarity index 96% rename from patches/api-unmapped/0206-Add-Raw-Byte-ItemStack-Serialization.patch rename to patches/api/0193-Add-Raw-Byte-ItemStack-Serialization.patch index 8ffb283fa..e88adb86e 100644 --- a/patches/api-unmapped/0206-Add-Raw-Byte-ItemStack-Serialization.patch +++ b/patches/api/0193-Add-Raw-Byte-ItemStack-Serialization.patch @@ -20,7 +20,7 @@ index d6897f43a0692e031bed8a212d9a637ef548cc60..e348034288c74ab80360086d71f0b7f6 // Paper end } diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index bf39989dbe08c93120d75bed6281ae75c460afca..15b48ad1ba5bcf7394fb3f52ce2cc6baa6632f66 100644 +index 290c3f0fd6e8c3407d421b697e0ee01584f4cebd..9a878e4fde31c015e2f3fdf365d5d16c30198685 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java @@ -628,6 +628,30 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, net.kyor diff --git a/patches/api-unmapped/0192-Disable-Sync-Events-firing-Async-errors-during-shutd.patch b/patches/api/0194-Disable-Sync-Events-firing-Async-errors-during-shutd.patch similarity index 93% rename from patches/api-unmapped/0192-Disable-Sync-Events-firing-Async-errors-during-shutd.patch rename to patches/api/0194-Disable-Sync-Events-firing-Async-errors-during-shutd.patch index 5ca0264ed..32392efc4 100644 --- a/patches/api-unmapped/0192-Disable-Sync-Events-firing-Async-errors-during-shutd.patch +++ b/patches/api/0194-Disable-Sync-Events-firing-Async-errors-during-shutd.patch @@ -11,7 +11,7 @@ errors. This isn't an issue on Spigot diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java -index a1a805004941d67abb0b9aa1721e0370c45b5289..26685f59b235ea5b4c4fb7ae21acb5149edaa2b3 100644 +index b83637f872be5fc73500b10c917d71802976b340..49e5d49eb09bb966e47d6a03ac08a527c963b43d 100644 --- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java +++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java @@ -591,7 +591,7 @@ public final class SimplePluginManager implements PluginManager { diff --git a/patches/api-unmapped/0193-Make-JavaPluginLoader-thread-safe.patch b/patches/api/0195-Make-JavaPluginLoader-thread-safe.patch similarity index 100% rename from patches/api-unmapped/0193-Make-JavaPluginLoader-thread-safe.patch rename to patches/api/0195-Make-JavaPluginLoader-thread-safe.patch diff --git a/patches/api-unmapped/0194-Add-Player-Client-Options-API.patch b/patches/api/0196-Add-Player-Client-Options-API.patch similarity index 97% rename from patches/api-unmapped/0194-Add-Player-Client-Options-API.patch rename to patches/api/0196-Add-Player-Client-Options-API.patch index c156119b1..a271a0732 100644 --- a/patches/api-unmapped/0194-Add-Player-Client-Options-API.patch +++ b/patches/api/0196-Add-Player-Client-Options-API.patch @@ -176,7 +176,7 @@ index 0000000000000000000000000000000000000000..f7f171c4ee0b8339b2f8fbe82442d65f + } +} diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index ec87c78d0f9379511467b6d13b9cdfa4c19d15ca..2530c811f52f51d6338900221b4681c952c1c752 100644 +index 685975e7bb8938ce0b2d80855c4c5549f50b262d..e53f641e11dc74c99e656e985caa7c5943fb53a4 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java @@ -2,6 +2,7 @@ package org.bukkit.entity; @@ -187,7 +187,7 @@ index ec87c78d0f9379511467b6d13b9cdfa4c19d15ca..2530c811f52f51d6338900221b4681c9 import com.destroystokyo.paper.Title; // Paper import net.kyori.adventure.text.Component; import com.destroystokyo.paper.profile.PlayerProfile; // Paper -@@ -1909,6 +1910,12 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -1936,6 +1937,12 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * Reset the cooldown counter to 0, effectively starting the cooldown period. */ void resetCooldown(); diff --git a/patches/api-unmapped/0195-Add-PlayerAttackEntityCooldownResetEvent.patch b/patches/api/0197-Add-PlayerAttackEntityCooldownResetEvent.patch similarity index 100% rename from patches/api-unmapped/0195-Add-PlayerAttackEntityCooldownResetEvent.patch rename to patches/api/0197-Add-PlayerAttackEntityCooldownResetEvent.patch diff --git a/patches/api-unmapped/0196-Fix-Potion-toItemStack-swapping-the-extended-and-upg.patch b/patches/api/0198-Fix-Potion-toItemStack-swapping-the-extended-and-upg.patch similarity index 100% rename from patches/api-unmapped/0196-Fix-Potion-toItemStack-swapping-the-extended-and-upg.patch rename to patches/api/0198-Fix-Potion-toItemStack-swapping-the-extended-and-upg.patch diff --git a/patches/api-unmapped/0197-Villager-Restocks-API.patch b/patches/api/0199-Villager-Restocks-API.patch similarity index 100% rename from patches/api-unmapped/0197-Villager-Restocks-API.patch rename to patches/api/0199-Villager-Restocks-API.patch diff --git a/patches/api-unmapped/0198-Expose-game-version.patch b/patches/api/0200-Expose-game-version.patch similarity index 89% rename from patches/api-unmapped/0198-Expose-game-version.patch rename to patches/api/0200-Expose-game-version.patch index 560d2370a..987427e03 100644 --- a/patches/api-unmapped/0198-Expose-game-version.patch +++ b/patches/api/0200-Expose-game-version.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Expose game version diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index 86ac6702b3aeab1126b2b2879b87ef3883793d44..12214ce2af7363d40cf44652e46f05c5c1f2fe5a 100644 +index 847ba5143660d5c56ff8f2cae2169a51b8927757..2c9d2739e78d5c422574f5ddda078ca395c0fa6d 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java @@ -118,6 +118,18 @@ public final class Bukkit { @@ -28,7 +28,7 @@ index 86ac6702b3aeab1126b2b2879b87ef3883793d44..12214ce2af7363d40cf44652e46f05c5 * Gets a view of all currently logged in players. This {@linkplain * Collections#unmodifiableCollection(Collection) view} is a reused diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index 16a74b834c4d4b907f9b11ccf9ef9804514df224..360decea2eb6de4c567fa4cceea8f19bceff6823 100644 +index e6b62ba32e089e2fd8563ec8430b72196f6680e0..46d1086bd7d7f91b4337c8463974d4b9d501cbf0 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java @@ -97,6 +97,16 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi diff --git a/patches/server-remapped/0436-Delay-unsafe-actions-until-after-entity-ticking-is-d.patch b/patches/removed/1.17/0436-Delay-unsafe-actions-until-after-entity-ticking-is-d.patch similarity index 95% rename from patches/server-remapped/0436-Delay-unsafe-actions-until-after-entity-ticking-is-d.patch rename to patches/removed/1.17/0436-Delay-unsafe-actions-until-after-entity-ticking-is-d.patch index 9fb51d1e3..2c856fd18 100644 --- a/patches/server-remapped/0436-Delay-unsafe-actions-until-after-entity-ticking-is-d.patch +++ b/patches/removed/1.17/0436-Delay-unsafe-actions-until-after-entity-ticking-is-d.patch @@ -5,6 +5,8 @@ Subject: [PATCH] Delay unsafe actions until after entity ticking is done This will help prevent many cases of unregistering entities during entity ticking +1.17: Not used anywhere in 1.16.5 server, and no more tickingEntities bool on ServerLevel + diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java index 4e75cc5e52a5295e32ccadb371702a405bb518bb..b9978d296b83e73d3395b8254c0e8ccd9b36d0fa 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java diff --git a/patches/server-remapped/0446-Optimize-ChunkProviderServer-s-chunk-level-checking-.patch b/patches/removed/1.17/0446-Optimize-ChunkProviderServer-s-chunk-level-checking-.patch similarity index 99% rename from patches/server-remapped/0446-Optimize-ChunkProviderServer-s-chunk-level-checking-.patch rename to patches/removed/1.17/0446-Optimize-ChunkProviderServer-s-chunk-level-checking-.patch index e6f625565..083f25a75 100644 --- a/patches/server-remapped/0446-Optimize-ChunkProviderServer-s-chunk-level-checking-.patch +++ b/patches/removed/1.17/0446-Optimize-ChunkProviderServer-s-chunk-level-checking-.patch @@ -8,6 +8,8 @@ These can be hot functions (i.e entity ticking and block ticking), so inline where possible, and avoid the abstraction of the Either class. +1.17: needs to be looked at again + diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java index 3744cce8611ac01b1b6c76cd3c4890795c1f06a2..531fe1259a1d60ff69321c3fefbf97f7141e6475 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java diff --git a/patches/server-remapped/0434-Add-Raw-Byte-ItemStack-Serialization.patch b/patches/server-remapped/0434-Add-Raw-Byte-ItemStack-Serialization.patch deleted file mode 100644 index 4f867cd88..000000000 --- a/patches/server-remapped/0434-Add-Raw-Byte-ItemStack-Serialization.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mariell Hoversholm -Date: Thu, 30 Apr 2020 16:56:54 +0200 -Subject: [PATCH] Add Raw Byte ItemStack Serialization - -Serializes using NBT which is safer for server data migrations than bukkits format. - -diff --git a/src/main/java/net/minecraft/nbt/NbtIo.java b/src/main/java/net/minecraft/nbt/NbtIo.java -index b3838e709c1581c25da7738c9a03a827761845b1..05ace1d046e32a261e67bff5afc18c2d32e1a8aa 100644 ---- a/src/main/java/net/minecraft/nbt/NbtIo.java -+++ b/src/main/java/net/minecraft/nbt/NbtIo.java -@@ -51,6 +51,7 @@ public class NbtIo { - return nbttagcompound; - } - -+ public static CompoundTag readNBT(InputStream inputstream) throws IOException { return readCompressed(inputstream); } // Paper - OBFHELPER - public static CompoundTag readCompressed(InputStream stream) throws IOException { - DataInputStream datainputstream = new DataInputStream(new BufferedInputStream(new GZIPInputStream(stream))); - Throwable throwable = null; -@@ -106,6 +107,7 @@ public class NbtIo { - - } - -+ public static void writeNBT(CompoundTag nbttagcompound, OutputStream outputstream) throws IOException { writeCompressed(nbttagcompound, outputstream); } // Paper - OBFHELPER - public static void writeCompressed(CompoundTag tag, OutputStream stream) throws IOException { - DataOutputStream dataoutputstream = new DataOutputStream(new BufferedOutputStream(new GZIPOutputStream(stream))); - Throwable throwable = null; -diff --git a/src/main/java/net/minecraft/util/datafix/DataFixers.java b/src/main/java/net/minecraft/util/datafix/DataFixers.java -index 950a4b67f9091af551ec1036ebeb943e3b335e91..dc4e2fc26e1bc2c545f955d30c052bb86e3ef614 100644 ---- a/src/main/java/net/minecraft/util/datafix/DataFixers.java -+++ b/src/main/java/net/minecraft/util/datafix/DataFixers.java -@@ -78,6 +78,7 @@ public class DataFixers { - return datafixerbuilder.build(Util.bootstrapExecutor()); - } - -+ public static DataFixer getDataFixer() { return getDataFixer(); } // Paper - OBFHELPER - public static DataFixer getDataFixer() { - return DataFixers.DATA_FIXER; - } -diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index ac996d581925c8f92832009945c766962e5b51c5..458cdfbeac9d757c9721acd4557a548affa0ede1 100644 ---- a/src/main/java/net/minecraft/world/item/ItemStack.java -+++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -196,6 +196,7 @@ public final class ItemStack { - this.updateEmptyCacheFlag(); - } - -+ public static ItemStack fromCompound(CompoundTag nbttagcompound) { return of(nbttagcompound); } // Paper - OBFHELPER - public static ItemStack of(CompoundTag tag) { - try { - return new ItemStack(tag); -diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 86b319337fc41a09dd45df466df60cadaed1343f..a5a5038a84434e69fda8f6b41d2f00b4989e25ae 100644 ---- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -378,6 +378,46 @@ public final class CraftMagicNumbers implements UnsafeValues { - public boolean isSupportedApiVersion(String apiVersion) { - return apiVersion != null && SUPPORTED_API.contains(apiVersion); - } -+ -+ @Override -+ public byte[] serializeItem(ItemStack item) { -+ Preconditions.checkNotNull(item, "null cannot be serialized"); -+ Preconditions.checkArgument(item.getType() != Material.AIR, "air cannot be serialized"); -+ -+ java.io.ByteArrayOutputStream outputStream = new java.io.ByteArrayOutputStream(); -+ CompoundTag compound = (item instanceof CraftItemStack ? ((CraftItemStack) item).getHandle() : CraftItemStack.asNMSCopy(item)).save(new CompoundTag()); -+ compound.putInt("DataVersion", getDataVersion()); -+ try { -+ net.minecraft.nbt.NbtIo.writeNBT( -+ compound, -+ outputStream -+ ); -+ } catch (IOException ex) { -+ throw new RuntimeException(ex); -+ } -+ -+ return outputStream.toByteArray(); -+ } -+ -+ @Override -+ public ItemStack deserializeItem(byte[] data) { -+ Preconditions.checkNotNull(data, "null cannot be deserialized"); -+ Preconditions.checkArgument(data.length > 0, "cannot deserialize nothing"); -+ -+ try { -+ CompoundTag compound = net.minecraft.nbt.NbtIo.readNBT( -+ new java.io.ByteArrayInputStream(data) -+ ); -+ int dataVersion = compound.getInt("DataVersion"); -+ -+ Preconditions.checkArgument(dataVersion <= getDataVersion(), "Newer version! Server downgrades are not supported!"); -+ Dynamic converted = DataFixers.getDataFixer().update(References.ITEM_STACK, new Dynamic(NbtOps.INSTANCE, compound), dataVersion, getDataVersion()); -+ return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.fromCompound((CompoundTag) converted.getValue())); -+ } catch (IOException ex) { -+ com.destroystokyo.paper.util.SneakyThrow.sneaky(ex); -+ throw new RuntimeException(); -+ } -+ } - // Paper end - - /** diff --git a/patches/server-remapped/0441-Remove-streams-from-PairedQueue.patch b/patches/server-remapped/0441-Remove-streams-from-PairedQueue.patch deleted file mode 100644 index 935abedc0..000000000 --- a/patches/server-remapped/0441-Remove-streams-from-PairedQueue.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Mon, 6 Apr 2020 18:10:43 -0700 -Subject: [PATCH] Remove streams from PairedQueue - -We shouldn't be doing stream calls just to see if the queue is -empty. This creates loads of garbage thanks to how often it's called. - -diff --git a/src/main/java/net/minecraft/util/thread/StrictQueue.java b/src/main/java/net/minecraft/util/thread/StrictQueue.java -index cdc572b0261034248960fa13b8412e874fd20db5..07938519b699a31a280f3f419b34fb7cf6cf6883 100644 ---- a/src/main/java/net/minecraft/util/thread/StrictQueue.java -+++ b/src/main/java/net/minecraft/util/thread/StrictQueue.java -@@ -20,32 +20,30 @@ public interface StrictQueue { - - public static final class FixedPriorityQueue implements StrictQueue { - -- private final List> queueList; -+ private final List> queueList; private final List> getQueues() { return this.queueList; } // Paper - OBFHELPER - - public FixedPriorityQueue(int priorityCount) { -- this.queueList = (List) IntStream.range(0, priorityCount).mapToObj((j) -> { -- return Queues.newConcurrentLinkedQueue(); -- }).collect(Collectors.toList()); -+ // Paper start - remove streams -+ this.queueList = new java.util.ArrayList<>(priorityCount); // queues -+ for (int j = 0; j < priorityCount; ++j) { -+ this.getQueues().add(Queues.newConcurrentLinkedQueue()); -+ } -+ // Paper end - remove streams - } - - @Nullable - @Override - public Runnable pop() { -- Iterator iterator = this.queueList.iterator(); -- -- Runnable runnable; -- -- do { -- if (!iterator.hasNext()) { -- return null; -+ // Paper start - remove iterator creation -+ for (int i = 0, len = this.getQueues().size(); i < len; ++i) { -+ Queue queue = this.getQueues().get(i); -+ Runnable ret = queue.poll(); -+ if (ret != null) { -+ return ret; - } -- -- Queue queue = (Queue) iterator.next(); -- -- runnable = (Runnable) queue.poll(); -- } while (runnable == null); -- -- return runnable; -+ } -+ return null; -+ // Paper end - remove iterator creation - } - - public boolean push(StrictQueue.IntRunnable message) { -@@ -57,7 +55,16 @@ public interface StrictQueue { - - @Override - public boolean isEmpty() { -- return this.queueList.stream().allMatch(Collection::isEmpty); -+ // Paper start - remove streams -+ // why are we doing streams every time we might want to execute a task? -+ for (int i = 0, len = this.getQueues().size(); i < len; ++i) { -+ Queue queue = this.getQueues().get(i); -+ if (!queue.isEmpty()) { -+ return false; -+ } -+ } -+ return true; -+ // Paper end - remove streams - } - } - diff --git a/patches/server-remapped/0453-Load-Chunks-for-Login-Asynchronously.patch b/patches/server-remapped/0453-Load-Chunks-for-Login-Asynchronously.patch deleted file mode 100644 index f02494b2a..000000000 --- a/patches/server-remapped/0453-Load-Chunks-for-Login-Asynchronously.patch +++ /dev/null @@ -1,416 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Sun, 19 Apr 2020 04:28:29 -0400 -Subject: [PATCH] Load Chunks for Login Asynchronously - - -diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index b3ca4300b280a24f3ed2acaffdd6ae2cdffd140d..97a582614ad28f9fa864ae9be4860658e5979214 100644 ---- a/src/main/java/net/minecraft/server/level/ChunkMap.java -+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -145,7 +145,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - private final ProcessorHandle> worldgenMailbox; - private final ProcessorHandle> mainThreadMailbox; - public final ChunkProgressListener progressListener; -- public final ChunkMap.ChunkDistanceManager distanceManager; -+ public final ChunkMap.ChunkDistanceManager distanceManager; public final DistanceManager getChunkDistanceManager() { return this.distanceManager; } // Paper - OBFHELPER - private final AtomicInteger tickingGenerated; - public final StructureManager structureManager; // Paper - private -> public - private final File storageFolder; -diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index b45fe750c8ca838e1beebff4077e5819eec2836c..79fb63c40dd0543a6f629e78f390f23f34992ba1 100644 ---- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java -+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -629,7 +629,7 @@ public class ServerChunkCache extends ChunkSource { - return this.mainThreadProcessor.pollTask(); - } - -- private boolean runDistanceManagerUpdates() { -+ public boolean runDistanceManagerUpdates() { // Paper - private -> public - boolean flag = this.distanceManager.runAllUpdates(this.chunkMap); - boolean flag1 = this.chunkMap.promoteChunkMap(); - -diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 75a095e0c2177dc1b46b080597ff8f12f1480acc..24c508ade61a6ad90b0ef73cdc995f531ef18263 100644 ---- a/src/main/java/net/minecraft/server/level/ServerPlayer.java -+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -32,6 +32,7 @@ import net.minecraft.core.Vec3i; - import net.minecraft.nbt.CompoundTag; - import net.minecraft.nbt.NbtOps; - import net.minecraft.nbt.Tag; -+import net.minecraft.network.Connection; - import net.minecraft.network.chat.ChatType; - import net.minecraft.network.chat.Component; - import net.minecraft.network.chat.HoverEvent; -@@ -172,6 +173,7 @@ public class ServerPlayer extends Player implements ContainerListener { - - private static final Logger LOGGER = LogManager.getLogger(); - public ServerGamePacketListenerImpl connection; -+ public Connection networkManager; // Paper - public final MinecraftServer server; - public final ServerPlayerGameMode gameMode; - public final Deque removeQueue = new ArrayDeque<>(); // Paper -@@ -238,6 +240,7 @@ public class ServerPlayer extends Player implements ContainerListener { - public boolean joining = true; - public boolean sentListPacket = false; - public boolean supressTrackerForLogin = false; // Paper -+ public boolean didPlayerJoinEvent = false; // Paper - public Integer clientViewDistance; - // CraftBukkit end - public PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper -diff --git a/src/main/java/net/minecraft/server/level/TicketType.java b/src/main/java/net/minecraft/server/level/TicketType.java -index d09e4857b6c40410d134fa81b48e95919a7373bd..583587457790df826a8a3239a4bd1d0f1dcab1da 100644 ---- a/src/main/java/net/minecraft/server/level/TicketType.java -+++ b/src/main/java/net/minecraft/server/level/TicketType.java -@@ -21,6 +21,7 @@ public class TicketType { - public static final TicketType FORCED = create("forced", Comparator.comparingLong(ChunkPos::toLong)); - public static final TicketType LIGHT = create("light", Comparator.comparingLong(ChunkPos::toLong)); - public static final TicketType PORTAL = create("portal", Vec3i::compareTo, 300); -+ public static final TicketType LOGIN = create("login", Long::compareTo, 100); // Paper - public static final TicketType POST_TELEPORT = create("post_teleport", Integer::compareTo, 5); - public static final TicketType UNKNOWN = create("unknown", Comparator.comparingLong(ChunkPos::toLong), 1); - public static final TicketType PLUGIN = create("plugin", (a, b) -> 0); // CraftBukkit -diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 09a663cc53cdf8ae45352b280200c8170dbbcdfc..1bed6e69bf3cc1ab9b0c1259de4f643bf58371aa 100644 ---- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -220,6 +220,7 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener { - private static final Logger LOGGER = LogManager.getLogger(); - public final Connection connection; - private final MinecraftServer server; -+ public Runnable playerJoinReady; // Paper - public ServerPlayer player; - private int tickCount; - private long keepAliveTime = Util.getMillis(); private void setLastPing(long lastPing) { this.keepAliveTime = lastPing;}; private long getLastPing() { return this.keepAliveTime;}; // Paper - OBFHELPER -@@ -298,6 +299,15 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener { - // CraftBukkit end - - public void tick() { -+ // Paper start - login async -+ Runnable playerJoinReady = this.playerJoinReady; -+ if (playerJoinReady != null) { -+ this.playerJoinReady = null; -+ playerJoinReady.run(); -+ } -+ // Don't tick if not valid (dead), otherwise we load chunks below -+ if (this.player.valid) { -+ // Paper end - this.resetPosition(); - this.player.xo = this.player.getX(); - this.player.yo = this.player.getY(); -@@ -339,7 +349,7 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener { - this.lastVehicle = null; - this.clientVehicleIsFloating = false; - this.aboveGroundVehicleTickCount = 0; -- } -+ }} // Paper - end if (valid) - - this.server.getProfiler().push("keepAlive"); - // Paper Start - give clients a longer time to respond to pings as per pre 1.12.2 timings -diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index 9631fa93b821c7f6bc6dc707c2c82cce2ae8291e..e229c7735ba88be3d8721440104958408a2a075e 100644 ---- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -@@ -86,7 +86,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener - } - // Paper end - } else if (this.state == ServerLoginPacketListenerImpl.State.DELAY_ACCEPT) { -- ServerPlayer entityplayer = this.server.getPlayerList().getPlayer(this.gameProfile.getId()); -+ ServerPlayer entityplayer = this.server.getPlayerList().getActivePlayer(this.gameProfile.getId()); // Paper - - if (entityplayer == null) { - this.state = ServerLoginPacketListenerImpl.State.READY_TO_ACCEPT; -@@ -186,7 +186,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener - } - - this.connection.send(new ClientboundGameProfilePacket(this.gameProfile)); -- ServerPlayer entityplayer = this.server.getPlayerList().getPlayer(this.gameProfile.getId()); -+ ServerPlayer entityplayer = this.server.getPlayerList().getActivePlayer(this.gameProfile.getId()); // Paper - - if (entityplayer != null) { - this.state = ServerLoginPacketListenerImpl.State.DELAY_ACCEPT; -diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 454d60566743e02e7e55868c7bb45e30583dfa8f..ffc8c9ee8b1768dd809189858ee45658fb9bf1c5 100644 ---- a/src/main/java/net/minecraft/server/players/PlayerList.java -+++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -36,6 +36,7 @@ import net.minecraft.network.protocol.Packet; - import net.minecraft.network.protocol.game.ClientboundChangeDifficultyPacket; - import net.minecraft.network.protocol.game.ClientboundChatPacket; - import net.minecraft.network.protocol.game.ClientboundCustomPayloadPacket; -+import net.minecraft.network.protocol.game.ClientboundDisconnectPacket; - import net.minecraft.network.protocol.game.ClientboundEntityEventPacket; - import net.minecraft.network.protocol.game.ClientboundGameEventPacket; - import net.minecraft.network.protocol.game.ClientboundLoginPacket; -@@ -59,6 +60,8 @@ import net.minecraft.server.MCUtil; - import net.minecraft.server.MinecraftServer; - import net.minecraft.server.PlayerAdvancements; - import net.minecraft.server.ServerScoreboard; -+import net.minecraft.server.level.ChunkHolder; -+import net.minecraft.server.level.ChunkMap; - import net.minecraft.server.level.ServerLevel; - import net.minecraft.server.level.ServerPlayer; - import net.minecraft.server.level.ServerPlayerGameMode; -@@ -124,11 +127,12 @@ public abstract class PlayerList { - private static final SimpleDateFormat BAN_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z"); - private final MinecraftServer server; - public final List players = new java.util.concurrent.CopyOnWriteArrayList(); // CraftBukkit - ArrayList -> CopyOnWriteArrayList: Iterator safety -- private final Map playersByUUID = Maps.newHashMap(); -+ private final Map playersByUUID = Maps.newHashMap();Map getUUIDMap() { return playersByUUID; } // Paper - OBFHELPER - private final UserBanList bans; - private final IpBanList ipBans; - private final ServerOpList ops; - private final UserWhiteList whitelist; -+ private final Map pendingPlayers = Maps.newHashMap(); // Paper - // CraftBukkit start - // private final Map o; - // private final Map p; -@@ -167,6 +171,11 @@ public abstract class PlayerList { - } - - public void placeNewPlayer(Connection connection, ServerPlayer player) { -+ ServerPlayer prev = pendingPlayers.put(player.getUUID(), player);// Paper -+ if (prev != null) { -+ disconnectPendingPlayer(prev); -+ } -+ player.networkManager = connection; // Paper - player.loginTime = System.currentTimeMillis(); // Paper - GameProfile gameprofile = player.getGameProfile(); - GameProfileCache usercache = this.server.getProfileCache(); -@@ -180,7 +189,7 @@ public abstract class PlayerList { - if (nbttagcompound != null && nbttagcompound.contains("bukkit")) { - CompoundTag bukkit = nbttagcompound.getCompound("bukkit"); - s = bukkit.contains("lastKnownName", 8) ? bukkit.getString("lastKnownName") : s; -- } -+ }String lastKnownName = s; // Paper - // CraftBukkit end - - if (nbttagcompound != null) { -@@ -255,34 +264,79 @@ public abstract class PlayerList { - player.getRecipeBook().sendInitialRecipeBook(player); - this.updateEntireScoreboard(worldserver1.getScoreboard(), player); - this.server.invalidateStatus(); -+ // Paper start - async load spawn in chunk -+ ServerLevel finalWorldserver = worldserver1; -+ int chunkX = loc.getBlockX() >> 4; -+ int chunkZ = loc.getBlockZ() >> 4; -+ final ChunkPos pos = new ChunkPos(chunkX, chunkZ); -+ ChunkMap playerChunkMap = worldserver1.getChunkSource().chunkMap; -+ playerChunkMap.getChunkDistanceManager().addTicketAtLevel(TicketType.LOGIN, pos, 31, pos.toLong()); -+ worldserver1.getChunkSource().runDistanceManagerUpdates(); -+ worldserver1.getChunkSource().getChunkAtAsynchronously(chunkX, chunkZ, true, true).thenApply(chunk -> { -+ ChunkHolder updatingChunk = playerChunkMap.getUpdatingChunkIfPresent(pos.toLong()); -+ if (updatingChunk != null) { -+ return updatingChunk.getEntityTickingFuture(); -+ } else { -+ return java.util.concurrent.CompletableFuture.completedFuture(chunk); -+ } -+ }).thenAccept(chunk -> { -+ playerconnection.playerJoinReady = () -> { -+ postChunkLoadJoin( -+ player, finalWorldserver, connection, playerconnection, -+ nbttagcompound, connection.getRemoteAddress().toString(), lastKnownName -+ ); -+ }; -+ }); -+ } -+ -+ public ServerPlayer getActivePlayer(UUID uuid) { -+ ServerPlayer player = this.getUUIDMap().get(uuid); -+ return player != null ? player : pendingPlayers.get(uuid); -+ } -+ -+ void disconnectPendingPlayer(ServerPlayer entityplayer) { -+ TranslatableComponent msg = new TranslatableComponent("multiplayer.disconnect.duplicate_login", new Object[0]); -+ entityplayer.networkManager.send(new ClientboundDisconnectPacket(msg), (future) -> { -+ entityplayer.networkManager.disconnect(msg); -+ entityplayer.networkManager = null; -+ }); -+ } -+ -+ private void postChunkLoadJoin(ServerPlayer entityplayer, ServerLevel worldserver1, Connection networkmanager, ServerGamePacketListenerImpl playerconnection, CompoundTag nbttagcompound, String s1, String s) { -+ pendingPlayers.remove(entityplayer.getUUID(), entityplayer); -+ if (!networkmanager.isConnected()) { -+ return; -+ } -+ entityplayer.didPlayerJoinEvent = true; -+ // Paper end - TranslatableComponent chatmessage; - -- if (player.getGameProfile().getName().equalsIgnoreCase(s)) { -- chatmessage = new TranslatableComponent("multiplayer.player.joined", new Object[]{player.getDisplayName()}); -+ if (entityplayer.getGameProfile().getName().equalsIgnoreCase(s)) { -+ chatmessage = new TranslatableComponent("multiplayer.player.joined", new Object[]{entityplayer.getDisplayName()}); - } else { -- chatmessage = new TranslatableComponent("multiplayer.player.joined.renamed", new Object[]{player.getDisplayName(), s}); -+ chatmessage = new TranslatableComponent("multiplayer.player.joined.renamed", new Object[]{entityplayer.getDisplayName(), s}); - } - // CraftBukkit start - chatmessage.withStyle(ChatFormatting.YELLOW); - Component joinMessage = chatmessage; // Paper - Adventure - -- playerconnection.teleport(player.getX(), player.getY(), player.getZ(), player.yRot, player.xRot); -- this.players.add(player); -- this.playersByName.put(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT), player); // Spigot -- this.playersByUUID.put(player.getUUID(), player); -+ playerconnection.teleport(entityplayer.getX(), entityplayer.getY(), entityplayer.getZ(), entityplayer.yRot, entityplayer.xRot); -+ this.players.add(entityplayer); -+ this.playersByName.put(entityplayer.getScoreboardName().toLowerCase(java.util.Locale.ROOT), entityplayer); // Spigot -+ this.playersByUUID.put(entityplayer.getUUID(), entityplayer); - // this.sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, new EntityPlayer[]{entityplayer})); // CraftBukkit - replaced with loop below - - // Paper start - correctly register player BEFORE PlayerJoinEvent, so the entity is valid and doesn't require tick delay hacks -- player.supressTrackerForLogin = true; -- worldserver1.addNewPlayer(player); -- this.server.getCustomBossEvents().onPlayerConnect(player); // see commented out section below worldserver.addPlayerJoin(entityplayer); -- mountSavedVehicle(player, worldserver1, nbttagcompound); -+ entityplayer.supressTrackerForLogin = true; -+ worldserver1.addNewPlayer(entityplayer); -+ this.server.getCustomBossEvents().onPlayerConnect(entityplayer); // see commented out section below worldserver.addPlayerJoin(entityplayer); -+ mountSavedVehicle(entityplayer, worldserver1, nbttagcompound); - // Paper end - // CraftBukkit start -- PlayerJoinEvent playerJoinEvent = new org.bukkit.event.player.PlayerJoinEvent(cserver.getPlayer(player), PaperAdventure.asAdventure(chatmessage)); // Paper - Adventure -+ PlayerJoinEvent playerJoinEvent = new org.bukkit.event.player.PlayerJoinEvent(cserver.getPlayer(entityplayer), PaperAdventure.asAdventure(chatmessage)); // Paper - Adventure - cserver.getPluginManager().callEvent(playerJoinEvent); - -- if (!player.connection.connection.isConnected()) { -+ if (!entityplayer.connection.connection.isConnected()) { - return; - } - -@@ -297,51 +351,51 @@ public abstract class PlayerList { - // CraftBukkit end - - // CraftBukkit start - sendAll above replaced with this loop -- ClientboundPlayerInfoPacket packet = new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, player); -+ ClientboundPlayerInfoPacket packet = new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, entityplayer); - - for (int i = 0; i < this.players.size(); ++i) { - ServerPlayer entityplayer1 = (ServerPlayer) this.players.get(i); - -- if (entityplayer1.getBukkitEntity().canSee(player.getBukkitEntity())) { -+ if (entityplayer1.getBukkitEntity().canSee(entityplayer.getBukkitEntity())) { - entityplayer1.connection.send(packet); - } - -- if (!player.getBukkitEntity().canSee(entityplayer1.getBukkitEntity())) { -+ if (!entityplayer.getBukkitEntity().canSee(entityplayer1.getBukkitEntity())) { - continue; - } - -- player.connection.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, new ServerPlayer[] { entityplayer1})); -+ entityplayer.connection.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, new ServerPlayer[] { entityplayer1})); - } -- player.sentListPacket = true; -- player.supressTrackerForLogin = false; // Paper -- ((ServerLevel)player.level).getChunkSource().chunkMap.addEntity(player); // Paper - track entity now -+ entityplayer.sentListPacket = true; -+ entityplayer.supressTrackerForLogin = false; // Paper -+ ((ServerLevel)entityplayer.level).getChunkSource().chunkMap.addEntity(entityplayer); // Paper - track entity now - // CraftBukkit end - -- player.connection.send(new ClientboundSetEntityDataPacket(player.getId(), player.getEntityData(), true)); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn -+ entityplayer.connection.send(new ClientboundSetEntityDataPacket(entityplayer.getId(), entityplayer.getEntityData(), true)); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn - - // CraftBukkit start - Only add if the player wasn't moved in the event -- if (player.level == worldserver1 && !worldserver1.players().contains(player)) { -- worldserver1.addNewPlayer(player); -- this.server.getCustomBossEvents().onPlayerConnect(player); -+ if (entityplayer.level == worldserver1 && !worldserver1.players().contains(entityplayer)) { -+ worldserver1.addNewPlayer(entityplayer); -+ this.server.getCustomBossEvents().onPlayerConnect(entityplayer); - } - -- worldserver1 = player.getLevel(); // CraftBukkit - Update in case join event changed it -+ worldserver1 = entityplayer.getLevel(); // CraftBukkit - Update in case join event changed it - // CraftBukkit end -- this.sendLevelInfo(player, worldserver1); -+ this.sendLevelInfo(entityplayer, worldserver1); - if (!this.server.getResourcePack().isEmpty()) { -- player.sendTexturePack(this.server.getResourcePack(), this.server.getResourcePackHash()); -+ entityplayer.sendTexturePack(this.server.getResourcePack(), this.server.getResourcePackHash()); - } - -- Iterator iterator = player.getActiveEffects().iterator(); -+ Iterator iterator = entityplayer.getActiveEffects().iterator(); - - while (iterator.hasNext()) { - MobEffectInstance mobeffect = (MobEffectInstance) iterator.next(); - -- playerconnection.send(new ClientboundUpdateMobEffectPacket(player.getId(), mobeffect)); -+ playerconnection.send(new ClientboundUpdateMobEffectPacket(entityplayer.getId(), mobeffect)); - } - - // Paper start - move vehicle into method so it can be called above - short circuit around that code -- onPlayerJoinFinish(player, worldserver1, s1); -+ onPlayerJoinFinish(entityplayer, worldserver1, s1); - } - private void mountSavedVehicle(ServerPlayer entityplayer, ServerLevel worldserver1, CompoundTag nbttagcompound) { - // Paper end -@@ -492,6 +546,7 @@ public abstract class PlayerList { - - protected void save(ServerPlayer player) { - if (!player.getBukkitEntity().isPersistent()) return; // CraftBukkit -+ if (!player.didPlayerJoinEvent) return; // Paper - If we never fired PJE, we disconnected during login. Data has not changed, and additionally, our saved vehicle is not loaded! If we save now, we will lose our vehicle (CraftBukkit bug) - this.playerIo.save(player); - ServerStatsCounter serverstatisticmanager = (ServerStatsCounter) player.getStats(); // CraftBukkit - -@@ -519,7 +574,7 @@ public abstract class PlayerList { - } - - PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(cserver.getPlayer(entityplayer), net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, com.destroystokyo.paper.PaperConfig.useDisplayNameInQuit ? entityplayer.getBukkitEntity().displayName() : net.kyori.adventure.text.Component.text(entityplayer.getScoreboardName()))); -- cserver.getPluginManager().callEvent(playerQuitEvent); -+ if (entityplayer.didPlayerJoinEvent) cserver.getPluginManager().callEvent(playerQuitEvent); // Paper - if we disconnected before join ever fired, don't fire quit - entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage()); - - if (server.isSameThread()) entityplayer.doTick(); // SPIGOT-924 // Paper - don't tick during emergency shutdowns (Watchdog) -@@ -572,6 +627,13 @@ public abstract class PlayerList { - // this.p.remove(uuid); - // CraftBukkit end - } -+ // Paper start -+ entityplayer1 = pendingPlayers.get(uuid); -+ if (entityplayer1 == entityplayer) { -+ pendingPlayers.remove(uuid); -+ } -+ entityplayer.networkManager = null; -+ // Paper end - - // CraftBukkit start - // this.sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, new EntityPlayer[]{entityplayer})); -@@ -589,7 +651,7 @@ public abstract class PlayerList { - cserver.getScoreboardManager().removePlayer(entityplayer.getBukkitEntity()); - // CraftBukkit end - -- return playerQuitEvent.quitMessage(); // Paper - Adventure -+ return entityplayer.didPlayerJoinEvent ? playerQuitEvent.quitMessage() : null; // CraftBukkit // Paper - Adventure // Paper - don't print quit if we never printed join - } - - // CraftBukkit start - Whole method, SocketAddress to LoginListener, added hostname to signature, return EntityPlayer -@@ -608,6 +670,13 @@ public abstract class PlayerList { - list.add(entityplayer); - } - } -+ // Paper start - check pending players too -+ entityplayer = pendingPlayers.get(uuid); -+ if (entityplayer != null) { -+ this.pendingPlayers.remove(uuid); -+ disconnectPendingPlayer(entityplayer); -+ } -+ // Paper end - - Iterator iterator = list.iterator(); - -diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index b8dcc91a191f25ca578e0858abf6c1b874fee15d..9f0371282f5829d26dc9618c3d466bccaa4cd3af 100644 ---- a/src/main/java/net/minecraft/world/entity/Entity.java -+++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -1371,7 +1371,7 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s - this.yo = y; - this.zo = d4; - this.setPos(d3, y, d4); -- level.getChunk((int) Math.floor(this.getX()) >> 4, (int) Math.floor(this.getZ()) >> 4); // CraftBukkit -+ if (valid) level.getChunk((int) Math.floor(this.getX()) >> 4, (int) Math.floor(this.getZ()) >> 4); // CraftBukkit // Paper - } - - public void moveTo(Vec3 vec3d) { diff --git a/patches/server-remapped/0464-Optimize-Voxel-Shape-Merging.patch b/patches/server-remapped/0464-Optimize-Voxel-Shape-Merging.patch deleted file mode 100644 index 935b12df1..000000000 --- a/patches/server-remapped/0464-Optimize-Voxel-Shape-Merging.patch +++ /dev/null @@ -1,175 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Sun, 3 May 2020 22:35:09 -0400 -Subject: [PATCH] Optimize Voxel Shape Merging - -This method shows up as super hot in profiler, and also a high "self" time. - -Upon analyzing, it appears most usages of this method fall down to the final -else statement of the nasty ternary. - -Upon even further analyzation, it appears then the majority of those have a -consistent list 1.... One with Infinity head and Tails. - -First optimization is to detect these infinite states and immediately return that -VoxelShapeMergerList so we can avoid testing the rest for most cases. - -Break the method into 2 to help the JVM promote inlining of this fast path. - -Then it was also noticed that VoxelShapeMergerList constructor is also a hotspot -with a high self time... - -Well, knowing that in most cases our list 1 is actualy the same value, it allows -us to know that with an infinite list1, the result on the merger is essentially -list2 as the final values. - -This let us analyze the 2 potential states (Infinite with 2 sources or 4 sources) -and compute a deterministic result for the MergerList values. - -Additionally, this lets us avoid even allocating new objects for this too, further -reducing memory usage. - -diff --git a/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java b/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java -index f0e74daa5bb9e88c028225e7c71deb04c481a7ac..abbe05b07831423eccf8779e854251dec5fbc2ae 100644 ---- a/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java -+++ b/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java -@@ -6,10 +6,16 @@ import it.unimi.dsi.fastutil.ints.IntArrayList; - - public final class IndirectMerger implements IndexMerger { - -- private final DoubleArrayList result; -+ private final DoubleList a; // Paper - private final IntArrayList firstIndices; - private final IntArrayList secondIndices; - -+ // Paper start -+ private static final IntArrayList INFINITE_B_1 = new IntArrayList(new int[]{1, 1}); -+ private static final IntArrayList INFINITE_B_0 = new IntArrayList(new int[]{0, 0}); -+ private static final IntArrayList INFINITE_C = new IntArrayList(new int[]{0, 1}); -+ // Paper end -+ - protected IndirectMerger(DoubleList first, DoubleList second, boolean includeFirstOnly, boolean includeSecondOnly) { - int i = 0; - int j = 0; -@@ -18,7 +24,23 @@ public final class IndirectMerger implements IndexMerger { - int l = second.size(); - int i1 = k + l; - -- this.result = new DoubleArrayList(i1); -+ // Paper start - optimize common path of infinity doublelist -+ int size = first.size(); -+ double tail = first.getDouble(size - 1); -+ double head = first.getDouble(0); -+ if (head == Double.NEGATIVE_INFINITY && tail == Double.POSITIVE_INFINITY && !includeFirstOnly && !includeSecondOnly && (size == 2 || size == 4)) { -+ this.a = second; -+ if (size == 2) { -+ this.firstIndices = INFINITE_B_0; -+ } else { -+ this.firstIndices = INFINITE_B_1; -+ } -+ this.secondIndices = INFINITE_C; -+ return; -+ } -+ // Paper end -+ -+ this.a = new DoubleArrayList(i1); - this.firstIndices = new IntArrayList(i1); - this.secondIndices = new IntArrayList(i1); - -@@ -27,8 +49,8 @@ public final class IndirectMerger implements IndexMerger { - boolean flag3 = j < l; - - if (!flag2 && !flag3) { -- if (this.result.isEmpty()) { -- this.result.add(Math.min(first.getDouble(k - 1), second.getDouble(l - 1))); -+ if (this.a.isEmpty()) { -+ this.a.add(Math.min(first.getDouble(k - 1), second.getDouble(l - 1))); - } - - return; -@@ -41,9 +63,9 @@ public final class IndirectMerger implements IndexMerger { - if (!(d0 >= d1 - 1.0E-7D)) { // Paper - decompile error - welcome to hell - this.firstIndices.add(i - 1); - this.secondIndices.add(j - 1); -- this.result.add(d1); -+ this.a.add(d1); - d0 = d1; -- } else if (!this.result.isEmpty()) { -+ } else if (!this.a.isEmpty()) { - this.firstIndices.set(this.firstIndices.size() - 1, i - 1); - this.secondIndices.set(this.secondIndices.size() - 1, j - 1); - } -@@ -53,7 +75,7 @@ public final class IndirectMerger implements IndexMerger { - - @Override - public boolean forMergedIndexes(IndexMerger.IndexConsumer predicate) { -- for (int i = 0; i < this.result.size() - 1; ++i) { -+ for (int i = 0; i < this.a.size() - 1; ++i) { - if (!predicate.merge(this.firstIndices.getInt(i), this.secondIndices.getInt(i), i)) { - return false; - } -@@ -64,6 +86,6 @@ public final class IndirectMerger implements IndexMerger { - - @Override - public DoubleList getList() { -- return this.result; -+ return this.a; - } - } -diff --git a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java -index c14d5ebe16a693834ed218af8f737714065b2e17..1603eb3f7d90a4b3a028b20776566db77d09c123 100644 ---- a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java -+++ b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java -@@ -329,19 +329,46 @@ public final class Shapes { - } - - @VisibleForTesting -- protected static IndexMerger createIndexMerger(int size, DoubleList first, DoubleList second, boolean includeFirst, boolean includeSecond) { -- int j = first.size() - 1; -- int k = second.size() - 1; -+ private static IndexMerger createIndexMerger(int size, DoubleList first, DoubleList second, boolean includeFirst, boolean includeSecond) { // Paper - private -+ // Paper start - fast track the most common scenario -+ // doublelist is usually a DoubleArrayList with Infinite head/tails that falls to the final else clause -+ // This is actually the most common path, so jump to it straight away -+ if (first.getDouble(0) == Double.NEGATIVE_INFINITY && first.getDouble(first.size() - 1) == Double.POSITIVE_INFINITY) { -+ return new IndirectMerger(first, second, includeFirst, includeSecond); -+ } -+ // Split out rest to hopefully inline the above -+ return lessCommonMerge(size, first, second, includeFirst, includeSecond); -+ } -+ -+ private static IndexMerger lessCommonMerge(int i, DoubleList doublelist, DoubleList doublelist1, boolean flag, boolean flag1) { -+ int j = doublelist.size() - 1; -+ int k = doublelist1.size() - 1; -+ // Paper note - Rewrite below as optimized order if instead of nasty ternary - -- if (first instanceof CubePointRange && second instanceof CubePointRange) { -+ if (doublelist instanceof CubePointRange && doublelist1 instanceof CubePointRange) { - long l = lcm(j, k); - -- if ((long) size * l <= 256L) { -+ if ((long) i * l <= 256L) { - return new DiscreteCubeMerger(j, k); - } - } - -- return (IndexMerger) (first.getDouble(j) < second.getDouble(0) - 1.0E-7D ? new NonOverlappingMerger(first, second, false) : (second.getDouble(k) < first.getDouble(0) - 1.0E-7D ? new NonOverlappingMerger(second, first, true) : (j == k && Objects.equals(first, second) ? (first instanceof IdenticalMerger ? (IndexMerger) first : (second instanceof IdenticalMerger ? (IndexMerger) second : new IdenticalMerger(first))) : new IndirectMerger(first, second, includeFirst, includeSecond)))); -+ // Identical happens more often than Disjoint -+ if (j == k && Objects.equals(doublelist, doublelist1)) { -+ if (doublelist instanceof IdenticalMerger) { -+ return (IndexMerger) doublelist; -+ } else if (doublelist1 instanceof IdenticalMerger) { -+ return (IndexMerger) doublelist1; -+ } -+ return new IdenticalMerger(doublelist); -+ } else if (doublelist.getDouble(j) < doublelist1.getDouble(0) - 1.0E-07) { -+ return new NonOverlappingMerger(doublelist, doublelist1, false); -+ } else if (doublelist1.getDouble(k) < doublelist.getDouble(0) - 1.0E-07) { -+ return new NonOverlappingMerger(doublelist1, doublelist, true); -+ } else { -+ return new IndirectMerger(doublelist, doublelist1, flag, flag1); -+ } -+ // Paper end - } - - public interface DoubleLineConsumer { diff --git a/patches/server/0010-Adventure.patch b/patches/server/0010-Adventure.patch index 4f747860d..1da3dba94 100644 --- a/patches/server/0010-Adventure.patch +++ b/patches/server/0010-Adventure.patch @@ -1956,10 +1956,10 @@ index cf69a45f038c2b8336010f5fe277313fd0513b5b..a7966aa0846637efdc43df1ca97cbc5d public net.minecraft.world.item.enchantment.Enchantment getHandle() { return this.target; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 98407b26cb94088fd931c445d4ed65eae5b7ecce..408e5a68986a91183d08ce06d385867b947ac04e 100644 +index 78d1621c1b5f1870829d92720e2151e9f9d9a8b5..6722d97d498fb2951b7dd8af3b68dd771ce8f5c1 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -807,6 +807,19 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -808,6 +808,19 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return this.getHandle().getVehicle().getBukkitEntity(); } diff --git a/patches/server/0025-Entity-Origin-API.patch b/patches/server/0025-Entity-Origin-API.patch index cdae1bf4b..1029b368c 100644 --- a/patches/server/0025-Entity-Origin-API.patch +++ b/patches/server/0025-Entity-Origin-API.patch @@ -114,10 +114,10 @@ index 394164f50256ad9a167e15531a9202875abb6cb6..abc62c560816d945642d830a020deb28 @Nullable diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 408e5a68986a91183d08ce06d385867b947ac04e..e5549f33a472133a8ce8533b5b827560a550f7ae 100644 +index 6722d97d498fb2951b7dd8af3b68dd771ce8f5c1..417357f6a187747a5e27fa60a57cee3fb91f3d2e 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -1097,4 +1097,12 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1098,4 +1098,12 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return this.spigot; } // Spigot end diff --git a/patches/server/0051-Add-velocity-warnings.patch b/patches/server/0051-Add-velocity-warnings.patch index 2a5b77ca9..0039fad82 100644 --- a/patches/server/0051-Add-velocity-warnings.patch +++ b/patches/server/0051-Add-velocity-warnings.patch @@ -17,10 +17,10 @@ index 4b6e6f120edc0e2c3dd3f81c5b9fb96980e41a33..6dab7f65401d5f01e094454b392042cc static { ConfigurationSerialization.registerClass(CraftOfflinePlayer.class); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index e5549f33a472133a8ce8533b5b827560a550f7ae..380cd00e55bbdc8851483a5f469e01a5ba48e955 100644 +index 417357f6a187747a5e27fa60a57cee3fb91f3d2e..808169e6d78b9e3647763239bbd05fcfba6449a6 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -432,10 +432,40 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -433,10 +433,40 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { public void setVelocity(Vector velocity) { Preconditions.checkArgument(velocity != null, "velocity"); velocity.checkFinite(); diff --git a/patches/server/0125-Provide-E-TE-Chunk-count-stat-methods.patch b/patches/server/0125-Provide-E-TE-Chunk-count-stat-methods.patch index 84141dee3..b2f4bbed0 100644 --- a/patches/server/0125-Provide-E-TE-Chunk-count-stat-methods.patch +++ b/patches/server/0125-Provide-E-TE-Chunk-count-stat-methods.patch @@ -20,10 +20,10 @@ index 52d80086deff664fcfd8952b7cabbfa1f48ad131..a86b5272c0ac4dd64f796f7fd025c7a3 private boolean tickingBlockEntities; public final Thread thread; diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 26f89f747eba69caaee3cbca71a1d48f2378b4cc..c9f11030ff928d3dca5cfbe48af057eb0480f898 100644 +index 1de08dd42366c9988fdcde265b92823e25e48b99..7b1f853913a3d858718a6067b3927946c7e50114 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -271,6 +271,57 @@ public class CraftWorld implements World { +@@ -272,6 +272,57 @@ public class CraftWorld implements World { private int waterAmbientSpawn = -1; private int ambientSpawn = -1; diff --git a/patches/server/0128-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch b/patches/server/0128-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch index 443029cb4..26eef0feb 100644 --- a/patches/server/0128-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch +++ b/patches/server/0128-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch @@ -314,10 +314,10 @@ index 11ed01b3ebe4c71e3d3c767887a5dca6033fdf3c..52b2b27f8f8b542a930d649ed6904b4b @Override diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index c9f11030ff928d3dca5cfbe48af057eb0480f898..9925d1f68c35a29156a152a8cc4b653ba280374b 100644 +index 7b1f853913a3d858718a6067b3927946c7e50114..efff3e9590e3fd66d9ab56173c986f5b51bbe559 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -1837,7 +1837,7 @@ public class CraftWorld implements World { +@@ -1838,7 +1838,7 @@ public class CraftWorld implements World { } else if (TNTPrimed.class.isAssignableFrom(clazz)) { entity = new PrimedTnt(this.world, x, y, z, null); } else if (ExperienceOrb.class.isAssignableFrom(clazz)) { diff --git a/patches/server/0147-Entity-fromMobSpawner.patch b/patches/server/0147-Entity-fromMobSpawner.patch index 34ebf1b31..c8b928e2b 100644 --- a/patches/server/0147-Entity-fromMobSpawner.patch +++ b/patches/server/0147-Entity-fromMobSpawner.patch @@ -49,10 +49,10 @@ index 037dafb59e54047d1d54474c44897d35b8f46c98..e310c1eb1108780bcff4d7ba9d49cefa if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, pos).isCancelled()) { Entity vehicle = entity.getVehicle(); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 380cd00e55bbdc8851483a5f469e01a5ba48e955..af8552f21f598f99151e59fe44df40f13caa3ead 100644 +index 808169e6d78b9e3647763239bbd05fcfba6449a6..a2a7b6a62ea1292fce37581863bee931d1497223 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -1134,5 +1134,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1135,5 +1135,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { Location origin = getHandle().origin; return origin == null ? null : origin.clone(); } diff --git a/patches/server/0167-API-to-get-a-BlockState-without-a-snapshot.patch b/patches/server/0167-API-to-get-a-BlockState-without-a-snapshot.patch index c5483d657..0ad07b41d 100644 --- a/patches/server/0167-API-to-get-a-BlockState-without-a-snapshot.patch +++ b/patches/server/0167-API-to-get-a-BlockState-without-a-snapshot.patch @@ -58,10 +58,10 @@ index 77645019c88d61dde28b7598d8a29b7d0c23c209..8a079ee3ed243fd19b1dd7eed2de1dd3 return null; } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -index 6128eb5a793365822d9b00a86629ad4d86c61da9..ca03ed4b1581df2b7db272d6f330174a9d277153 100644 +index 923948e7fc63a778ca126c99e1189357bb490dee..bf12cb6a1f991372206e462e46f2686decff11a6 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -@@ -313,7 +313,21 @@ public class CraftBlock implements Block { +@@ -316,7 +316,21 @@ public class CraftBlock implements Block { @Override public BlockState getState() { diff --git a/patches/server/0196-Expand-World.spawnParticle-API-and-add-Builder.patch b/patches/server/0196-Expand-World.spawnParticle-API-and-add-Builder.patch index 719bc3db5..c403b862a 100644 --- a/patches/server/0196-Expand-World.spawnParticle-API-and-add-Builder.patch +++ b/patches/server/0196-Expand-World.spawnParticle-API-and-add-Builder.patch @@ -34,10 +34,10 @@ index 18ab943ea2a959f012c3f75957fcb05dbe4ee6ff..c7ac5b323c731e5a7929f87d59e62796 if (this.sendParticles(entityplayer, force, d0, d1, d2, packetplayoutworldparticles)) { // CraftBukkit diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 9925d1f68c35a29156a152a8cc4b653ba280374b..fbc82598a2f7ea439bb371ecf074b486ae09c355 100644 +index efff3e9590e3fd66d9ab56173c986f5b51bbe559..8574cca2582d5eaf3720df1c42fda38957d18230 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -2357,11 +2357,17 @@ public class CraftWorld implements World { +@@ -2358,11 +2358,17 @@ public class CraftWorld implements World { @Override public void spawnParticle(Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, T data, boolean force) { diff --git a/patches/server/0201-Allow-spawning-Item-entities-with-World.spawnEntity.patch b/patches/server/0201-Allow-spawning-Item-entities-with-World.spawnEntity.patch index 5f114f6ef..110d6d75e 100644 --- a/patches/server/0201-Allow-spawning-Item-entities-with-World.spawnEntity.patch +++ b/patches/server/0201-Allow-spawning-Item-entities-with-World.spawnEntity.patch @@ -8,10 +8,10 @@ This API has more capabilities than .dropItem with the Consumer function Item can be set inside of the Consumer pre spawn function. diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index fbc82598a2f7ea439bb371ecf074b486ae09c355..e744a793062acce339c4914eb2eff2a8c2ff6f1b 100644 +index 8574cca2582d5eaf3720df1c42fda38957d18230..082ca9db7e925dfb36998135bea7be298a691b86 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -1506,6 +1506,10 @@ public class CraftWorld implements World { +@@ -1507,6 +1507,10 @@ public class CraftWorld implements World { if (Boat.class.isAssignableFrom(clazz)) { entity = new net.minecraft.world.entity.vehicle.Boat(this.world, x, y, z); entity.moveTo(x, y, z, yaw, pitch); diff --git a/patches/server/0206-Fix-CraftEntity-hashCode.patch b/patches/server/0206-Fix-CraftEntity-hashCode.patch index 9c66bc30b..b260b9440 100644 --- a/patches/server/0206-Fix-CraftEntity-hashCode.patch +++ b/patches/server/0206-Fix-CraftEntity-hashCode.patch @@ -21,10 +21,10 @@ check is essentially the same as this.getHandle() == other.getHandle() However, replaced it too to make it clearer of intent. diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index af8552f21f598f99151e59fe44df40f13caa3ead..b9089ba658d38397cf07245e31e6d40b3a2a5f2b 100644 +index a2a7b6a62ea1292fce37581863bee931d1497223..e57fef24ee5159142ec4f05a9e76a34c6e153386 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -783,14 +783,15 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -784,14 +784,15 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return false; } final CraftEntity other = (CraftEntity) obj; diff --git a/patches/server/0213-Expand-Explosions-API.patch b/patches/server/0213-Expand-Explosions-API.patch index 211ac6f05..b9c8b6499 100644 --- a/patches/server/0213-Expand-Explosions-API.patch +++ b/patches/server/0213-Expand-Explosions-API.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Expand Explosions API Add Entity as a Source capability, and add more API choices, and on Location. diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index e744a793062acce339c4914eb2eff2a8c2ff6f1b..c3a57510cd17203c65c15de0544d5656eb7a0b7b 100644 +index 082ca9db7e925dfb36998135bea7be298a691b86..20269c9084dd2a4f941e98e25c40bd3f3af43bcc 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -890,6 +890,12 @@ public class CraftWorld implements World { +@@ -891,6 +891,12 @@ public class CraftWorld implements World { public boolean createExplosion(double x, double y, double z, float power, boolean setFire, boolean breakBlocks, Entity source) { return !this.world.explode(source == null ? null : ((CraftEntity) source).getHandle(), x, y, z, power, setFire, breakBlocks ? Explosion.BlockInteraction.BREAK : Explosion.BlockInteraction.NONE).wasCanceled; } diff --git a/patches/server/0215-RangedEntity-API.patch b/patches/server/0215-RangedEntity-API.patch index 96a8f6424..1cfaceeec 100644 --- a/patches/server/0215-RangedEntity-API.patch +++ b/patches/server/0215-RangedEntity-API.patch @@ -111,17 +111,17 @@ index 06786fba1fef36e8fc3d0f5650160123f728a6d1..beea227855f0b978e655efc298024120 public CraftPillager(CraftServer server, net.minecraft.world.entity.monster.Pillager entity) { super(server, entity); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java -index 4cd3dfd3466f384aab06dacd388e8053b045b046..b2d3244cca4d9d108159f3537d8a9aace3f8e77f 100644 +index 7a73ada3d8b8085591308275ece4a9ce617314d3..3b19cd5a232f38d373359072925be12f6c075d4a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java -@@ -6,7 +6,7 @@ import org.bukkit.entity.EntityType; +@@ -5,7 +5,7 @@ import org.bukkit.craftbukkit.CraftServer; + import org.bukkit.entity.EntityType; import org.bukkit.entity.Skeleton; - import org.bukkit.entity.Skeleton.SkeletonType; --public class CraftSkeleton extends CraftMonster implements Skeleton { -+public class CraftSkeleton extends CraftMonster implements Skeleton, com.destroystokyo.paper.entity.CraftRangedEntity { // Paper +-public class CraftSkeleton extends CraftAbstractSkeleton implements Skeleton { ++public class CraftSkeleton extends CraftAbstractSkeleton implements Skeleton, com.destroystokyo.paper.entity.CraftRangedEntity { // Paper - public CraftSkeleton(CraftServer server, AbstractSkeleton entity) { + public CraftSkeleton(CraftServer server, net.minecraft.world.entity.monster.Skeleton entity) { super(server, entity); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java index 6a82d567d96a42bfea0e38afb4e8de13eb3ad5a2..659e2959c5330e4764ea1edc7f8de9f464f9ff52 100644 diff --git a/patches/server/0217-Implement-World.getEntity-UUID-API.patch b/patches/server/0217-Implement-World.getEntity-UUID-API.patch index db3675e02..0e8d1dd59 100644 --- a/patches/server/0217-Implement-World.getEntity-UUID-API.patch +++ b/patches/server/0217-Implement-World.getEntity-UUID-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Implement World.getEntity(UUID) API diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index c3a57510cd17203c65c15de0544d5656eb7a0b7b..e819031a4176a54a06c5a09ee29eda4db4f6cc08 100644 +index 20269c9084dd2a4f941e98e25c40bd3f3af43bcc..951445d5dba92ada70ce239098c702dd7b8ce0f1 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -1296,6 +1296,15 @@ public class CraftWorld implements World { +@@ -1297,6 +1297,15 @@ public class CraftWorld implements World { return list; } diff --git a/patches/server/0256-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch b/patches/server/0256-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch index a54b182f7..d3469898d 100644 --- a/patches/server/0256-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch +++ b/patches/server/0256-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Make CraftWorld#loadChunk(int, int, false) load unconverted diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index e819031a4176a54a06c5a09ee29eda4db4f6cc08..43e47c345a0d2e00f13f0112d26d93b004009ac9 100644 +index 951445d5dba92ada70ce239098c702dd7b8ce0f1..ad9a4d4a9363741cc47f142c24fa6f4858dd947f 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -506,7 +506,7 @@ public class CraftWorld implements World { +@@ -507,7 +507,7 @@ public class CraftWorld implements World { @Override public boolean loadChunk(int x, int z, boolean generate) { org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot diff --git a/patches/server/0257-Asynchronous-chunk-IO-and-loading.patch b/patches/server/0257-Asynchronous-chunk-IO-and-loading.patch index dda7a3dcd..ea7e8e8fa 100644 --- a/patches/server/0257-Asynchronous-chunk-IO-and-loading.patch +++ b/patches/server/0257-Asynchronous-chunk-IO-and-loading.patch @@ -3678,10 +3678,10 @@ index 844d65612d9c4c19d02a2b0a5b90cd44de9f17c9..cfd4c38ca99b183f23716f82c972c14b + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 43e47c345a0d2e00f13f0112d26d93b004009ac9..b8565aa86b478adb6fca6d433637ddb342ce6dcb 100644 +index ad9a4d4a9363741cc47f142c24fa6f4858dd947f..a19de8405de8ee29afc112556e4684b042c6f4ab 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -2424,6 +2424,34 @@ public class CraftWorld implements World { +@@ -2425,6 +2425,34 @@ public class CraftWorld implements World { public DragonBattle getEnderDragonBattle() { return (this.getHandle().dragonFight() == null) ? null : new CraftDragonBattle(this.getHandle().dragonFight()); } @@ -3717,7 +3717,7 @@ index 43e47c345a0d2e00f13f0112d26d93b004009ac9..b8565aa86b478adb6fca6d433637ddb3 // Spigot start @Override diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index b9089ba658d38397cf07245e31e6d40b3a2a5f2b..c381ea321b0fb3498e3f101ee059ac7d42aa029a 100644 +index e57fef24ee5159142ec4f05a9e76a34c6e153386..d0774636b151e8dbd778f2e2f2e3de154ff18494 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -13,6 +13,7 @@ import net.minecraft.nbt.CompoundTag; @@ -3728,7 +3728,7 @@ index b9089ba658d38397cf07245e31e6d40b3a2a5f2b..c381ea321b0fb3498e3f101ee059ac7d import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.AreaEffectCloud; import net.minecraft.world.entity.Entity; -@@ -515,6 +516,28 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -516,6 +517,28 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { this.entity.setYHeadRot(yaw); } diff --git a/patches/server/0272-Add-sun-related-API.patch b/patches/server/0272-Add-sun-related-API.patch index f3352dd10..52e76a976 100644 --- a/patches/server/0272-Add-sun-related-API.patch +++ b/patches/server/0272-Add-sun-related-API.patch @@ -18,10 +18,10 @@ index 8451baff82cb7ec7615ab50a409724897ccf4d95..32e8ae0d2a0f78af671a632c4d1be58a float f = this.getBrightness(); BlockPos blockposition = new BlockPos(this.getX(), this.getEyeY(), this.getZ()); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index b8565aa86b478adb6fca6d433637ddb342ce6dcb..fda8858375a08e0aac15ca00751df5a34ed6a0f2 100644 +index a19de8405de8ee29afc112556e4684b042c6f4ab..be4c05259f176e9ef5c25db2b1745df5ea4d5789 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -866,6 +866,13 @@ public class CraftWorld implements World { +@@ -867,6 +867,13 @@ public class CraftWorld implements World { } } diff --git a/patches/server/0312-Entity-getEntitySpawnReason.patch b/patches/server/0312-Entity-getEntitySpawnReason.patch index 90d47b684..fbcb73d40 100644 --- a/patches/server/0312-Entity-getEntitySpawnReason.patch +++ b/patches/server/0312-Entity-getEntitySpawnReason.patch @@ -105,10 +105,10 @@ index 12a78685848b7fd945a472902d8200ea1d50b9ec..3aadcb472ab808ee981065ddfa86be6c // Spigot Start if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, pos).isCancelled()) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index c381ea321b0fb3498e3f101ee059ac7d42aa029a..33bc56eba4229d844e3af6ff4662d96450e929af 100644 +index d0774636b151e8dbd778f2e2f2e3de154ff18494..98d3818d38f487fc7e1302ee4af9e4898efec809 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -1163,5 +1163,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1164,5 +1164,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { public boolean fromMobSpawner() { return getHandle().spawnedViaMobSpawner; } diff --git a/patches/server/0320-Add-Heightmap-API.patch b/patches/server/0320-Add-Heightmap-API.patch index 4c7380555..59f0009d9 100644 --- a/patches/server/0320-Add-Heightmap-API.patch +++ b/patches/server/0320-Add-Heightmap-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add Heightmap API diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index fda8858375a08e0aac15ca00751df5a34ed6a0f2..5f93589106bcf29eabd4544951fa3ad36e00c5a6 100644 +index be4c05259f176e9ef5c25db2b1745df5ea4d5789..ea587597bfb205531c03eb0c0c9bde31ea6ab53b 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -341,6 +341,29 @@ public class CraftWorld implements World { +@@ -342,6 +342,29 @@ public class CraftWorld implements World { return this.getHighestBlockYAt(x, z, org.bukkit.HeightMap.MOTION_BLOCKING); } diff --git a/patches/server/0325-improve-CraftWorld-isChunkLoaded.patch b/patches/server/0325-improve-CraftWorld-isChunkLoaded.patch index cb95e90f0..4eb97bfd1 100644 --- a/patches/server/0325-improve-CraftWorld-isChunkLoaded.patch +++ b/patches/server/0325-improve-CraftWorld-isChunkLoaded.patch @@ -9,10 +9,10 @@ waiting for the execution queue to get to our request; We can just query the chunk status and get a response now, vs having to wait diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 5f93589106bcf29eabd4544951fa3ad36e00c5a6..a7eb8f69b49bb0229de9e5a4400a4424555ac1dd 100644 +index ea587597bfb205531c03eb0c0c9bde31ea6ab53b..a112daf93daeab6d34416bc7c8a69acfc207c98b 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -412,13 +412,13 @@ public class CraftWorld implements World { +@@ -413,13 +413,13 @@ public class CraftWorld implements World { @Override public boolean isChunkLoaded(int x, int z) { diff --git a/patches/server/0326-Configurable-Keep-Spawn-Loaded-range-per-world.patch b/patches/server/0326-Configurable-Keep-Spawn-Loaded-range-per-world.patch index 9d6f848e8..82b32a8df 100644 --- a/patches/server/0326-Configurable-Keep-Spawn-Loaded-range-per-world.patch +++ b/patches/server/0326-Configurable-Keep-Spawn-Loaded-range-per-world.patch @@ -225,10 +225,10 @@ index 4185e6bcf9b2bb65b2a0fa5fcbeb5684615169a7..dbc29442f2b2ad3ea451910f4944e901 this.maxCount = i * i; } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index a7eb8f69b49bb0229de9e5a4400a4424555ac1dd..30305736b7dc023ad5eb3a177914560b3fec64ee 100644 +index a112daf93daeab6d34416bc7c8a69acfc207c98b..98b2d054b6436e3fdb8fadd03369a65cf4156843 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -1974,15 +1974,21 @@ public class CraftWorld implements World { +@@ -1975,15 +1975,21 @@ public class CraftWorld implements World { @Override public void setKeepSpawnInMemory(boolean keepLoaded) { diff --git a/patches/server/0328-Implement-CraftBlockSoundGroup.patch b/patches/server/0328-Implement-CraftBlockSoundGroup.patch index 76559b8fc..6cb5b0632 100644 --- a/patches/server/0328-Implement-CraftBlockSoundGroup.patch +++ b/patches/server/0328-Implement-CraftBlockSoundGroup.patch @@ -49,14 +49,13 @@ index 0000000000000000000000000000000000000000..9a516520d975f52169e346adc4ec6d9d + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -index ca03ed4b1581df2b7db272d6f330174a9d277153..0a9ed9992a2fc97472a06591a5d129a767ce21af 100644 +index bf12cb6a1f991372206e462e46f2686decff11a6..75dd8cbadae9a2d18931dd49f49f8f1e14b50da5 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -@@ -749,4 +749,11 @@ public class CraftBlock implements Block { - AABB aabb = shape.bounds(); - return new BoundingBox(this.getX() + aabb.minX, this.getY() + aabb.minY, this.getZ() + aabb.minZ, this.getX() + aabb.maxX, this.getY() + aabb.maxY, this.getZ() + aabb.maxZ); +@@ -764,4 +764,10 @@ public class CraftBlock implements Block { + VoxelShape shape = this.getNMS().getCollisionShape(world, position); + return new CraftVoxelShape(shape); } -+ + // Paper start + @Override + public com.destroystokyo.paper.block.BlockSoundGroup getSoundGroup() { diff --git a/patches/server/0330-Fix-World-isChunkGenerated-calls.patch b/patches/server/0330-Fix-World-isChunkGenerated-calls.patch index 953566fa3..8cfc74e92 100644 --- a/patches/server/0330-Fix-World-isChunkGenerated-calls.patch +++ b/patches/server/0330-Fix-World-isChunkGenerated-calls.patch @@ -272,7 +272,7 @@ index 211ab6cffe78c61fcff12ef7ffba904c4cae57b2..1bee455235ece8aa299a2baeede027d2 } + diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 30305736b7dc023ad5eb3a177914560b3fec64ee..4841591539fdd5a01f9ded0ee510991602c266a4 100644 +index 98b2d054b6436e3fdb8fadd03369a65cf4156843..f9c58de7fa8b3c2ab5ac78cf0b366df69e0b40df 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -20,6 +20,7 @@ import java.util.Objects; @@ -283,7 +283,7 @@ index 30305736b7dc023ad5eb3a177914560b3fec64ee..4841591539fdd5a01f9ded0ee5109916 import java.util.function.Predicate; import java.util.stream.Collectors; import net.minecraft.core.BlockPos; -@@ -417,8 +418,22 @@ public class CraftWorld implements World { +@@ -418,8 +419,22 @@ public class CraftWorld implements World { @Override public boolean isChunkGenerated(int x, int z) { @@ -307,7 +307,7 @@ index 30305736b7dc023ad5eb3a177914560b3fec64ee..4841591539fdd5a01f9ded0ee5109916 } catch (IOException ex) { throw new RuntimeException(ex); } -@@ -529,20 +544,48 @@ public class CraftWorld implements World { +@@ -530,20 +545,48 @@ public class CraftWorld implements World { @Override public boolean loadChunk(int x, int z, boolean generate) { org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot diff --git a/patches/server/0340-Fix-spawning-of-hanging-entities-that-are-not-ItemFr.patch b/patches/server/0340-Fix-spawning-of-hanging-entities-that-are-not-ItemFr.patch index 8a4a109b1..019515cce 100644 --- a/patches/server/0340-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 4841591539fdd5a01f9ded0ee510991602c266a4..f1cbcdb1e409f8544125dde5f24bff5b07cb5082 100644 +index f9c58de7fa8b3c2ab5ac78cf0b366df69e0b40df..053878ce00b77367b403a8c52f0d81f485022c59 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -1881,7 +1881,12 @@ public class CraftWorld implements World { +@@ -1882,7 +1882,12 @@ public class CraftWorld implements World { height = 9; } diff --git a/patches/server/0357-Add-effect-to-block-break-naturally.patch b/patches/server/0357-Add-effect-to-block-break-naturally.patch index f0c758d80..1f77985ef 100644 --- a/patches/server/0357-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 0a9ed9992a2fc97472a06591a5d129a767ce21af..ca95a6b1b156b37f839c6479733e5184691af66c 100644 +index 75dd8cbadae9a2d18931dd49f49f8f1e14b50da5..64c304cab8c7c4c9c29f73465f99c11f224a72bd 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -@@ -632,6 +632,13 @@ public class CraftBlock implements Block { +@@ -635,6 +635,13 @@ public class CraftBlock implements Block { @Override public boolean breakNaturally(ItemStack item) { @@ -22,7 +22,7 @@ index 0a9ed9992a2fc97472a06591a5d129a767ce21af..ca95a6b1b156b37f839c6479733e5184 // 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(); -@@ -641,6 +648,7 @@ public class CraftBlock implements Block { +@@ -644,6 +651,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, this.world.getMinecraftWorld(), position, this.world.getBlockEntity(position), null, nmsItem); diff --git a/patches/server/0361-No-Tick-view-distance-implementation.patch b/patches/server/0361-No-Tick-view-distance-implementation.patch index 6fdb3036e..3087bd1ec 100644 --- a/patches/server/0361-No-Tick-view-distance-implementation.patch +++ b/patches/server/0361-No-Tick-view-distance-implementation.patch @@ -651,10 +651,10 @@ index 521f199e495f3bec232cc9ca36e51e0392afe737..922026da8c234427e0322443004d3c32 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 f1cbcdb1e409f8544125dde5f24bff5b07cb5082..1d22119b962840dff789a0619fd2188958f924d0 100644 +index 053878ce00b77367b403a8c52f0d81f485022c59..b6134895d1b04d3ea7340e77f70efa23cff8b568 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -2540,10 +2540,39 @@ public class CraftWorld implements World { +@@ -2541,10 +2541,39 @@ public class CraftWorld implements World { // Spigot start @Override public int getViewDistance() { diff --git a/patches/server/0386-Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch b/patches/server/0386-Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch index 71138d108..8118c956e 100644 --- a/patches/server/0386-Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch +++ b/patches/server/0386-Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch @@ -246,10 +246,10 @@ index 382a68c76e8946840de62f05483870689de80278..8523fbd66ed42cd5b959d57cab515fa4 if (optional.isPresent()) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 1d22119b962840dff789a0619fd2188958f924d0..1023a0d5d1699b28d380e017b386a9b3986f1250 100644 +index b6134895d1b04d3ea7340e77f70efa23cff8b568..72c9ad9f75c20d6c1a6d54e2913e2f9918c11ffd 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -286,6 +286,7 @@ public class CraftWorld implements World { +@@ -287,6 +287,7 @@ public class CraftWorld implements World { @Override public int getTileEntityCount() { @@ -257,7 +257,7 @@ index 1d22119b962840dff789a0619fd2188958f924d0..1023a0d5d1699b28d380e017b386a9b3 // We don't use the full world tile entity list, so we must iterate chunks Long2ObjectLinkedOpenHashMap chunks = world.getChunkSource().chunkMap.visibleChunkMap; int size = 0; -@@ -297,6 +298,7 @@ public class CraftWorld implements World { +@@ -298,6 +299,7 @@ public class CraftWorld implements World { size += chunk.blockEntities.size(); } return size; @@ -265,7 +265,7 @@ index 1d22119b962840dff789a0619fd2188958f924d0..1023a0d5d1699b28d380e017b386a9b3 } @Override -@@ -306,6 +308,7 @@ public class CraftWorld implements World { +@@ -307,6 +309,7 @@ public class CraftWorld implements World { @Override public int getChunkCount() { @@ -273,7 +273,7 @@ index 1d22119b962840dff789a0619fd2188958f924d0..1023a0d5d1699b28d380e017b386a9b3 int ret = 0; for (ChunkHolder chunkHolder : world.getChunkSource().chunkMap.visibleChunkMap.values()) { -@@ -314,7 +317,7 @@ public class CraftWorld implements World { +@@ -315,7 +318,7 @@ public class CraftWorld implements World { } } @@ -282,7 +282,7 @@ index 1d22119b962840dff789a0619fd2188958f924d0..1023a0d5d1699b28d380e017b386a9b3 } @Override -@@ -441,6 +444,14 @@ public class CraftWorld implements World { +@@ -442,6 +445,14 @@ public class CraftWorld implements World { @Override public Chunk[] getLoadedChunks() { diff --git a/patches/server-remapped/0432-Add-tick-times-API-and-mspt-command.patch b/patches/server/0389-Add-tick-times-API-and-mspt-command.patch similarity index 89% rename from patches/server-remapped/0432-Add-tick-times-API-and-mspt-command.patch rename to patches/server/0389-Add-tick-times-API-and-mspt-command.patch index 0f2cf4005..81685ed79 100644 --- a/patches/server-remapped/0432-Add-tick-times-API-and-mspt-command.patch +++ b/patches/server/0389-Add-tick-times-API-and-mspt-command.patch @@ -87,13 +87,13 @@ index ddbc8cb712c50038922eded75dd6ca85fe851078..78271b400c79578d043b20a5389a37b1 version = getInt("config-version", 20); set("config-version", 20); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 087f31ac0cc7816b1cbeffc45be6927b174dee62..99ee9de92264381a064066bc22bb66b4b2852a2e 100644 +index fa3a9d763f7072c68b126ce95fee191aab576e43..91ae80ee1020dc017faef7c8be8487132c547fe4 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -217,6 +217,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop +Date: Thu, 30 Apr 2020 16:56:54 +0200 +Subject: [PATCH] Add Raw Byte ItemStack Serialization + +Serializes using NBT which is safer for server data migrations than bukkits format. + +diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +index ad8d6a84e1a66e03ae15269e36bc787148f12396..88d5c7a0d7de2e896433d85fbd5425351f51b64d 100644 +--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java ++++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +@@ -378,6 +378,46 @@ public final class CraftMagicNumbers implements UnsafeValues { + public boolean isSupportedApiVersion(String apiVersion) { + return apiVersion != null && SUPPORTED_API.contains(apiVersion); + } ++ ++ @Override ++ public byte[] serializeItem(ItemStack item) { ++ Preconditions.checkNotNull(item, "null cannot be serialized"); ++ Preconditions.checkArgument(item.getType() != Material.AIR, "air cannot be serialized"); ++ ++ java.io.ByteArrayOutputStream outputStream = new java.io.ByteArrayOutputStream(); ++ CompoundTag compound = (item instanceof CraftItemStack ? ((CraftItemStack) item).getHandle() : CraftItemStack.asNMSCopy(item)).save(new CompoundTag()); ++ compound.putInt("DataVersion", getDataVersion()); ++ try { ++ net.minecraft.nbt.NbtIo.writeCompressed( ++ compound, ++ outputStream ++ ); ++ } catch (IOException ex) { ++ throw new RuntimeException(ex); ++ } ++ ++ return outputStream.toByteArray(); ++ } ++ ++ @Override ++ public ItemStack deserializeItem(byte[] data) { ++ Preconditions.checkNotNull(data, "null cannot be deserialized"); ++ Preconditions.checkArgument(data.length > 0, "cannot deserialize nothing"); ++ ++ try { ++ CompoundTag compound = net.minecraft.nbt.NbtIo.readCompressed( ++ new java.io.ByteArrayInputStream(data) ++ ); ++ int dataVersion = compound.getInt("DataVersion"); ++ ++ Preconditions.checkArgument(dataVersion <= getDataVersion(), "Newer version! Server downgrades are not supported!"); ++ Dynamic converted = DataFixers.getDataFixer().update(References.ITEM_STACK, new Dynamic(NbtOps.INSTANCE, compound), dataVersion, getDataVersion()); ++ return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.of((CompoundTag) converted.getValue())); ++ } catch (IOException ex) { ++ com.destroystokyo.paper.util.SneakyThrow.sneaky(ex); ++ throw new RuntimeException(); ++ } ++ } + // Paper end + + /** diff --git a/patches/server-remapped/0435-Remove-streams-from-Mob-AI-System.patch b/patches/server/0392-Remove-streams-from-Mob-AI-System.patch similarity index 58% rename from patches/server-remapped/0435-Remove-streams-from-Mob-AI-System.patch rename to patches/server/0392-Remove-streams-from-Mob-AI-System.patch index 019eef698..12d3a671c 100644 --- a/patches/server-remapped/0435-Remove-streams-from-Mob-AI-System.patch +++ b/patches/server/0392-Remove-streams-from-Mob-AI-System.patch @@ -10,25 +10,21 @@ Also optimise the stream.anyMatch statement to move to a bitset where we can replace the call with a single bitwise operation. 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 558dd72c47930f6993952467f83b5a54ead95d92..acc6306d659cd65a043d12cd42dcbaf55aaf5250 100644 +index d92ddc8a4c0f5249b7ff4f97af1ea3db413b2983..8c2ec30a35e86f2b30863045b586a67e485c624b 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 -@@ -1,10 +1,12 @@ - package net.minecraft.world.entity.ai.goal; - -+import com.destroystokyo.paper.util.set.OptimizedSmallEnumSet; // Paper - remove streams from pathfindergoalselector +@@ -3,7 +3,8 @@ package net.minecraft.world.entity.ai.goal; import java.util.EnumSet; public abstract class Goal { - - private final EnumSet flags = EnumSet.noneOf(Goal.Flag.class); + private final EnumSet flags = EnumSet.noneOf(Goal.Flag.class); // Paper unused, but dummy to prevent plugins from crashing as hard. Theyll need to support paper in a special case if this is super important, but really doesn't seem like it would be. -+ private final OptimizedSmallEnumSet goalTypes = new OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector ++ private final com.destroystokyo.paper.util.set.OptimizedSmallEnumSet goalTypes = new com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector - public Goal() {} + public abstract boolean canUse(); -@@ -28,16 +30,20 @@ public abstract class Goal { - public void tick() {} +@@ -25,8 +26,10 @@ public abstract class Goal { + } public void setFlags(EnumSet controls) { - this.flags.clear(); @@ -39,7 +35,8 @@ index 558dd72c47930f6993952467f83b5a54ead95d92..acc6306d659cd65a043d12cd42dcbaf5 + // Paper end - remove streams from pathfindergoalselector } - public String toString() { + @Override +@@ -34,8 +37,10 @@ public abstract class Goal { return this.getClass().getSimpleName(); } @@ -53,42 +50,35 @@ index 558dd72c47930f6993952467f83b5a54ead95d92..acc6306d659cd65a043d12cd42dcbaf5 public static enum Flag { 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 9bd2ee05a0de6678ad8933a8ffbe0ae66bd073b4..5da2d780c17522e07c733a5e23b17ec760c7b342 100644 +index f29ace7b6a27a602102d37d43a6dd0571f218dfe..bcb2c5480872eef6f21746003380f71b8d44f5c8 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 -@@ -1,8 +1,10 @@ - package net.minecraft.world.entity.ai.goal; - -+import com.destroystokyo.paper.util.set.OptimizedSmallEnumSet; // Paper - remove streams from pathfindergoalselector - import com.google.common.collect.Sets; - import java.util.EnumMap; - import java.util.EnumSet; -+import java.util.Iterator; // Paper - remove streams from pathfindergoalselector - import java.util.Map; - import java.util.Set; - import java.util.function.Supplier; -@@ -28,7 +30,8 @@ public class GoalSelector { - private final Map lockedFlags = new EnumMap(Goal.Flag.class); - private final Set availableGoals = Sets.newLinkedHashSet(); private Set getTasks() { return availableGoals; }// Paper - OBFHELPER +@@ -28,10 +28,12 @@ public class GoalSelector { + private final Map lockedFlags = new EnumMap<>(Goal.Flag.class); + private final Set availableGoals = Sets.newLinkedHashSet(); private final Supplier profiler; - private final EnumSet disabledFlags = EnumSet.noneOf(Goal.Flag.class); + private final EnumSet disabledFlags = EnumSet.noneOf(Goal.Flag.class); // Paper unused, but dummy to prevent plugins from crashing as hard. Theyll need to support paper in a special case if this is super important, but really doesn't seem like it would be. -+ private final OptimizedSmallEnumSet goalTypes = new OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector - 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 final com.destroystokyo.paper.util.set.OptimizedSmallEnumSet goalTypes = new com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector + private int tickCount; + private int newGoalRate = 3; + private int curRate; ++ private static final Goal.Flag[] PATHFINDER_GOAL_TYPES = Goal.Flag.values(); // Paper - remove streams from pathfindergoalselector -@@ -56,35 +59,38 @@ public class GoalSelector { + public GoalSelector(Supplier profiler) { + this.profiler = profiler; +@@ -61,47 +63,95 @@ public class GoalSelector { + } // 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; - }).filter(WrappedGoal::isRunning).forEach(WrappedGoal::stop); -- this.availableGoals.removeIf((pathfindergoalwrapped) -> { -- return pathfindergoalwrapped.getGoal() == goal; +- this.availableGoals.removeIf((wrappedGoal) -> { +- return wrappedGoal.getGoal() == goal; - }); + // Paper start - remove streams from pathfindergoalselector -+ for (Iterator iterator = this.availableGoals.iterator(); iterator.hasNext();) { ++ for (java.util.Iterator iterator = this.availableGoals.iterator(); iterator.hasNext();) { + WrappedGoal goalWrapped = iterator.next(); + if (goalWrapped.getGoal() != goal) { + continue; @@ -101,76 +91,57 @@ index 9bd2ee05a0de6678ad8933a8ffbe0ae66bd073b4..5da2d780c17522e07c733a5e23b17ec7 + // Paper end - remove streams from pathfindergoalselector } -+ private static final Goal.Flag[] PATHFINDER_GOAL_TYPES = Goal.Flag.values(); // Paper - remove streams from pathfindergoalselector -+ public void tick() { - ProfilerFiller gameprofilerfiller = (ProfilerFiller) this.profiler.get(); - - gameprofilerfiller.push("goalCleanup"); -- this.getRunningGoals().filter((pathfindergoalwrapped) -> { -- boolean flag; -- -- if (pathfindergoalwrapped.isRunning()) { -- Stream stream = pathfindergoalwrapped.getFlags().stream(); -- EnumSet enumset = this.disabledFlags; -- -- this.disabledFlags.getClass(); -- if (!stream.anyMatch(enumset::contains) && pathfindergoalwrapped.canContinueToUse()) { -- flag = false; -- return flag; -- } -+ // Paper start - remove streams from pathfindergoalselector -+ for (Iterator iterator = this.availableGoals.iterator(); iterator.hasNext();) { -+ WrappedGoal wrappedGoal = iterator.next(); -+ if (!wrappedGoal.isRunning()) { -+ continue; - } -- -- flag = true; -- return flag; + ProfilerFiller profilerFiller = this.profiler.get(); + profilerFiller.push("goalCleanup"); +- this.getRunningGoals().filter((wrappedGoal) -> { +- return !wrappedGoal.isRunning() || wrappedGoal.getFlags().stream().anyMatch(this.disabledFlags::contains) || !wrappedGoal.canContinueToUse(); - }).forEach(Goal::stop); +- this.lockedFlags.forEach((flag, wrappedGoal) -> { ++ // Paper start - remove streams from pathfindergoalselector ++ for (java.util.Iterator iterator = this.availableGoals.iterator(); iterator.hasNext();) { ++ WrappedGoal wrappedGoal = iterator.next(); + if (!wrappedGoal.isRunning()) { +- this.lockedFlags.remove(flag); ++ continue; ++ } + if (!this.goalTypes.hasCommonElements(wrappedGoal.getGoalTypes()) && wrappedGoal.canContinueToUse()) { + continue; + } + wrappedGoal.stop(); + } + // Paper end - remove streams from pathfindergoalselector - this.lockedFlags.forEach((pathfindergoal_type, pathfindergoalwrapped) -> { - if (!pathfindergoalwrapped.isRunning()) { - this.lockedFlags.remove(pathfindergoal_type); -@@ -93,30 +99,58 @@ public class GoalSelector { ++ this.lockedFlags.forEach((pathfindergoal_type, pathfindergoalwrapped) -> { ++ if (!pathfindergoalwrapped.isRunning()) { ++ this.lockedFlags.remove(pathfindergoal_type); + } + }); - gameprofilerfiller.pop(); - gameprofilerfiller.push("goalUpdate"); -- this.availableGoals.stream().filter((pathfindergoalwrapped) -> { -- return !pathfindergoalwrapped.isRunning(); -- }).filter((pathfindergoalwrapped) -> { -- Stream stream = pathfindergoalwrapped.getFlags().stream(); -- EnumSet enumset = this.disabledFlags; -- -- this.disabledFlags.getClass(); -- return stream.noneMatch(enumset::contains); -- }).filter((pathfindergoalwrapped) -> { -- return pathfindergoalwrapped.getFlags().stream().allMatch((pathfindergoal_type) -> { -- return ((WrappedGoal) this.lockedFlags.getOrDefault(pathfindergoal_type, GoalSelector.NO_GOAL)).canBeReplacedBy(pathfindergoalwrapped); + profilerFiller.pop(); + profilerFiller.push("goalUpdate"); +- this.availableGoals.stream().filter((wrappedGoal) -> { +- return !wrappedGoal.isRunning(); +- }).filter((wrappedGoal) -> { +- return wrappedGoal.getFlags().stream().noneMatch(this.disabledFlags::contains); +- }).filter((wrappedGoal) -> { +- return wrappedGoal.getFlags().stream().allMatch((flag) -> { +- return this.lockedFlags.getOrDefault(flag, NO_GOAL).canBeReplacedBy(wrappedGoal); - }); -- }).filter(WrappedGoal::canUse).forEach((pathfindergoalwrapped) -> { -- pathfindergoalwrapped.getFlags().forEach((pathfindergoal_type) -> { -- WrappedGoal pathfindergoalwrapped1 = (WrappedGoal) this.lockedFlags.getOrDefault(pathfindergoal_type, GoalSelector.NO_GOAL); -- -- pathfindergoalwrapped1.stop(); -- this.lockedFlags.put(pathfindergoal_type, pathfindergoalwrapped); +- }).filter(WrappedGoal::canUse).forEach((wrappedGoal) -> { +- wrappedGoal.getFlags().forEach((flag) -> { +- WrappedGoal wrappedGoal2 = this.lockedFlags.getOrDefault(flag, NO_GOAL); +- wrappedGoal2.stop(); +- this.lockedFlags.put(flag, wrappedGoal); - }); -- pathfindergoalwrapped.start(); -- }); ++ + // Paper start - remove streams from pathfindergoalselector -+ goal_update_loop: for (Iterator iterator = this.availableGoals.iterator(); iterator.hasNext();) { ++ goal_update_loop: for (java.util.Iterator iterator = this.availableGoals.iterator(); iterator.hasNext();) { + WrappedGoal wrappedGoal = iterator.next(); + if (wrappedGoal.isRunning()) { + continue; + } + -+ OptimizedSmallEnumSet wrappedGoalSet = wrappedGoal.getGoalTypes(); ++ com.destroystokyo.paper.util.set.OptimizedSmallEnumSet wrappedGoalSet = wrappedGoal.getGoalTypes(); + + if (this.goalTypes.hasCommonElements(wrappedGoalSet)) { + continue; @@ -201,25 +172,25 @@ index 9bd2ee05a0de6678ad8933a8ffbe0ae66bd073b4..5da2d780c17522e07c733a5e23b17ec7 + wrapped.stop(); + this.lockedFlags.put(type, wrappedGoal); + } -+ -+ wrappedGoal.start(); + wrappedGoal.start(); +- }); + } + // Paper end - remove streams from pathfindergoalselector - gameprofilerfiller.pop(); - gameprofilerfiller.push("goalTick"); + profilerFiller.pop(); + profilerFiller.push("goalTick"); - this.getRunningGoals().forEach(WrappedGoal::tick); + // Paper start - remove streams from pathfindergoalselector -+ for (Iterator iterator = this.availableGoals.iterator(); iterator.hasNext();) { ++ for (java.util.Iterator iterator = this.availableGoals.iterator(); iterator.hasNext();) { + WrappedGoal wrappedGoal = iterator.next(); + if (wrappedGoal.isRunning()) { + wrappedGoal.tick(); + } + } + // Paper end - remove streams from pathfindergoalselector - gameprofilerfiller.pop(); + profilerFiller.pop(); } -@@ -125,11 +159,11 @@ public class GoalSelector { +@@ -118,11 +168,11 @@ public class GoalSelector { } public void disableControlFlag(Goal.Flag control) { @@ -234,10 +205,10 @@ index 9bd2ee05a0de6678ad8933a8ffbe0ae66bd073b4..5da2d780c17522e07c733a5e23b17ec7 public void setControlFlag(Goal.Flag control, boolean enabled) { 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 81b4618a7979ee8dd25e1749c084de9262318ef4..984146b2b6eb3e498433b1c4971397848166d9c9 100644 +index 1e915b999f4261fb27846a0e559ea22e4b09b4db..037cc5d2b41161e040fc9b264a0dd04827c29681 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 -@@ -59,9 +59,10 @@ public class WrappedGoal extends Goal { +@@ -58,9 +58,10 @@ public class WrappedGoal extends Goal { this.goal.setFlags(controls); } @@ -250,4 +221,4 @@ index 81b4618a7979ee8dd25e1749c084de9262318ef4..984146b2b6eb3e498433b1c497139784 + // Paper end - remove streams from pathfindergoalselector } - public boolean isRunning() { return this.isRunning(); } // Paper - OBFHELPER + public boolean isRunning() { diff --git a/patches/server-remapped/0437-Async-command-map-building.patch b/patches/server/0393-Async-command-map-building.patch similarity index 95% rename from patches/server-remapped/0437-Async-command-map-building.patch rename to patches/server/0393-Async-command-map-building.patch index 87f32eb78..12df4c5c7 100644 --- a/patches/server-remapped/0437-Async-command-map-building.patch +++ b/patches/server/0393-Async-command-map-building.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Async command map building diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java -index 44f2e8a3741afc0e3c3bca3b0864e37ecf83e5d4..8154d9327c5411bbfea3bfa4d99d57feab764664 100644 +index 7ca6a1a3f10cb19d759f6d4dc9d5458ac0fc05d3..13e358e0eac3bfd426d924b6f745e001df76c64a 100644 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java @@ -29,6 +29,7 @@ import net.minecraft.network.chat.MutableComponent; @@ -16,7 +16,7 @@ index 44f2e8a3741afc0e3c3bca3b0864e37ecf83e5d4..8154d9327c5411bbfea3bfa4d99d57fe import net.minecraft.server.commands.AdvancementCommands; import net.minecraft.server.commands.AttributeCommand; import net.minecraft.server.commands.BanIpCommands; -@@ -328,25 +329,40 @@ public class Commands { +@@ -335,25 +336,40 @@ public class Commands { if ( org.spigotmc.SpigotConfig.tabComplete < 0 ) return; // Spigot // CraftBukkit start // Register Vanilla commands into builtRoot as before @@ -61,7 +61,7 @@ index 44f2e8a3741afc0e3c3bca3b0864e37ecf83e5d4..8154d9327c5411bbfea3bfa4d99d57fe event.getPlayer().getServer().getPluginManager().callEvent(event); // Remove labels that were removed during the event -@@ -356,7 +372,7 @@ public class Commands { +@@ -363,7 +379,7 @@ public class Commands { } } // CraftBukkit end diff --git a/patches/server-remapped/0438-Improved-Watchdog-Support.patch b/patches/server/0394-Improved-Watchdog-Support.patch similarity index 81% rename from patches/server-remapped/0438-Improved-Watchdog-Support.patch rename to patches/server/0394-Improved-Watchdog-Support.patch index 928b62d52..be6786aad 100644 --- a/patches/server-remapped/0438-Improved-Watchdog-Support.patch +++ b/patches/server/0394-Improved-Watchdog-Support.patch @@ -41,7 +41,7 @@ This also moves all plugins who register "delayed init" tasks to occur just befo are properly accounted for and wont trip watchdog on init. diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java -index 0b9e689d57705965721b5c55bc45d36657f360e4..dee00aac05f1acf050f05d4db557a08dd0f301c8 100644 +index e3b74dbdf8e14219a56fab939f3174e0c2f66de6..218f5bafeed8551b55b91c7fccaf6935c8b631ca 100644 --- a/src/main/java/com/destroystokyo/paper/Metrics.java +++ b/src/main/java/com/destroystokyo/paper/Metrics.java @@ -92,7 +92,12 @@ public class Metrics { @@ -59,10 +59,10 @@ index 0b9e689d57705965721b5c55bc45d36657f360e4..dee00aac05f1acf050f05d4db557a08d // Many servers tend to restart at a fixed time at xx:00 which causes an uneven distribution of requests on the // bStats backend. To circumvent this problem, we introduce some randomness into the initial and second delay. diff --git a/src/main/java/net/minecraft/CrashReport.java b/src/main/java/net/minecraft/CrashReport.java -index 4008fbe506e74f2c463dc7b12f5dd0f3b6fc342d..766ab2fe536a2acccaec28e922ccf8993b0790dc 100644 +index bda7137b3435c9b7610be258cefb6b4ac2c1d47a..09f56e49383d3f5413ad4c28f3a7664e4d9570bd 100644 --- a/src/main/java/net/minecraft/CrashReport.java +++ b/src/main/java/net/minecraft/CrashReport.java -@@ -257,6 +257,7 @@ public class CrashReport { +@@ -231,6 +231,7 @@ public class CrashReport { } public static CrashReport forThrowable(Throwable cause, String title) { @@ -70,32 +70,20 @@ index 4008fbe506e74f2c463dc7b12f5dd0f3b6fc342d..766ab2fe536a2acccaec28e922ccf899 while (cause instanceof CompletionException && cause.getCause() != null) { cause = cause.getCause(); } -diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java -index c2f747226f10479c826849af898538610a2dd659..83f9f97586f8c0e9d228923e4fec6f121a6702e2 100644 ---- a/src/main/java/net/minecraft/Util.java -+++ b/src/main/java/net/minecraft/Util.java -@@ -129,6 +129,7 @@ public class Util { - return Util.IO_POOL; - } - -+ public static void shutdownServerThreadPool() { shutdownExecutors(); } // Paper - OBFHELPER - public static void shutdownExecutors() { - shutdownExecutor(Util.BACKGROUND_EXECUTOR); - shutdownExecutor(Util.IO_POOL); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 99ee9de92264381a064066bc22bb66b4b2852a2e..e5ad635a480d32e7a10ee92c65cfc18a98beafad 100644 +index 91ae80ee1020dc017faef7c8be8487132c547fe4..11fd6d24ed0612e4df1a0493907178fb9c455d1c 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -269,7 +269,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); public int autosavePeriod; - public boolean serverAutoSave = false; // Paper public Commands vanillaCommandDispatcher; - private boolean forceTicks; + public boolean forceTicks; // Paper // CraftBukkit end // Spigot start public static final int TPS = 20; -@@ -279,6 +279,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); Thread thread = new Thread(() -> { -@@ -851,6 +854,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { -+ world.tickingEntities = false; -+ }); + } + // Paper end // CraftBukkit end MinecraftServer.LOGGER.info("Stopping server"); MinecraftTimings.stopServer(); // Paper -@@ -930,7 +951,18 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { CompletableFuture completablefuture; -diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index b9978d296b83e73d3395b8254c0e8ccd9b36d0fa..bf4e50cd1d561456c033cda2d5c5487c5e3fe1eb 100644 ---- a/src/main/java/net/minecraft/server/level/ServerLevel.java -+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -171,7 +171,7 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl - private final Queue toAddAfterTick = Queues.newArrayDeque(); - public final List players = Lists.newArrayList(); // Paper - private -> public - public final ServerChunkCache chunkSource; // Paper - public -- boolean tickingEntities; -+ public boolean tickingEntities; // Paper - expose for watchdog - // Paper start - List afterEntityTickingTasks = Lists.newArrayList(); - public void doIfNotEntityTicking(java.lang.Runnable run) { diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 30666fca36b683158ff60302684b5093f5536e24..984ac19dcab446531c816e365c7c149e2c49d567 100644 +index 18485689bcbf7818c3ca5b82086acef51888603b..3431d28fd69c634ee0a941796308b88bb51bdaac 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -503,7 +503,7 @@ public abstract class PlayerList { - cserver.getPluginManager().callEvent(playerQuitEvent); +@@ -505,7 +505,7 @@ public abstract class PlayerList { + this.cserver.getPluginManager().callEvent(playerQuitEvent); entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage()); - entityplayer.doTick(); // SPIGOT-924 @@ -316,30 +287,22 @@ index 30666fca36b683158ff60302684b5093f5536e24..984ac19dcab446531c816e365c7c149e // Paper start - Remove from collideRule team if needed diff --git a/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java b/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java -index a5ce61be7d6e85ac289730d9671e66a7190529f9..add18ba4833686ff51fbb280b0a5759f142b3f91 100644 +index 0ef3c4982df88a7991a56d983ac733daa8adc507..cdd797c6fc7507a0e6376f7d9c521be8f1d6decc 100644 --- a/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java +++ b/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java -@@ -135,6 +135,7 @@ public abstract class BlockableEventLoop implements Processo +@@ -148,6 +148,7 @@ public abstract class BlockableEventLoop implements Profiler try { task.run(); - } catch (Exception exception) { -+ if (exception.getCause() instanceof ThreadDeath) throw exception; // Paper - BlockableEventLoop.LOGGER.fatal("Error executing task on {}", this.name(), exception); + } catch (Exception var3) { ++ if (var3.getCause() instanceof ThreadDeath) throw var3; // Paper + LOGGER.fatal("Error executing task on {}", this.name(), var3); } diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 632f32405053fbcff2fd26fa99f98c6add9f9dc7..5860e7866724abd35bde2a5710d9c92799e5de67 100644 +index 5fccec12c0325dd9873905c5c3559128c3b4d9ad..03271675b4997588bd8f6774856aef25cdd4fa05 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -858,6 +858,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { - - gameprofilerfiller.pop(); - } catch (Throwable throwable) { -+ if (throwable instanceof ThreadDeath) throw throwable; // Paper - // Paper start - Prevent tile entity and entity crashes - String msg = "TileEntity threw exception at " + tileentity.getLevel().getWorld().getName() + ":" + tileentity.getBlockPos().getX() + "," + tileentity.getBlockPos().getY() + "," + tileentity.getBlockPos().getZ(); - System.err.println(msg); -@@ -932,6 +933,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -836,6 +836,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { try { tickConsumer.accept(entity); } catch (Throwable throwable) { @@ -347,11 +310,23 @@ index 632f32405053fbcff2fd26fa99f98c6add9f9dc7..5860e7866724abd35bde2a5710d9c927 // Paper start - Prevent tile entity and entity crashes String msg = "Entity threw exception at " + entity.level.getWorld().getName() + ":" + entity.getX() + "," + entity.getY() + "," + entity.getZ(); System.err.println(msg); +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 59a77541bbda880ae8f84e3535a2b6112caa78fb..a63dc77db41dab79f03ef7384da55c1cdeca5d98 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java ++++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +@@ -1320,6 +1320,7 @@ public class LevelChunk implements ChunkAccess { + + gameprofilerfiller.pop(); + } catch (Throwable throwable) { ++ if (throwable instanceof ThreadDeath) throw throwable; // Paper + // Paper start - Prevent tile entity and entity crashes + String msg = "TileEntity threw exception at " + LevelChunk.this.getLevel().getWorld().getName() + ":" + this.getPos().getX() + "," + this.getPos().getY() + "," + this.getPos().getZ(); + System.err.println(msg); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 3f35e93b42efd03ff1002f09962fe3da51fb4c3f..43c37e660a8a7f9d326ad38e66f9aa7c53c7b87c 100644 +index 3423de396e0fadfa29714f5fcac4b579a8ff0967..4c0b94a56fab161fca92b594f55e1c846524d5e8 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1839,7 +1839,7 @@ public final class CraftServer implements Server { +@@ -1840,7 +1840,7 @@ public final class CraftServer implements Server { @Override public boolean isPrimaryThread() { @@ -361,7 +336,7 @@ index 3f35e93b42efd03ff1002f09962fe3da51fb4c3f..43c37e660a8a7f9d326ad38e66f9aa7c // Paper start diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index c519ceca6f7788ca7c5d74ad1001dbc09f62681c..c288b89bf5a22269823ba1d18af217032d7c6a36 100644 +index fd48cfe3dfaf7c867becfbf90246af2f33a74612..2904cbda94a8fb986d94022c11061f98938237dd 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -12,6 +12,8 @@ import java.util.logging.Level; @@ -410,7 +385,7 @@ index c519ceca6f7788ca7c5d74ad1001dbc09f62681c..c288b89bf5a22269823ba1d18af21703 try { options = parser.parse(args); } catch (joptsimple.OptionException ex) { -@@ -251,8 +283,64 @@ public class Main { +@@ -255,8 +287,64 @@ public class Main { } catch (Throwable t) { t.printStackTrace(); } @@ -476,7 +451,7 @@ index c519ceca6f7788ca7c5d74ad1001dbc09f62681c..c288b89bf5a22269823ba1d18af21703 private static List asList(String... params) { return Arrays.asList(params); diff --git a/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java b/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java -index 449e99d1b673870ed6892f6ab2c715a2db35c35d..c7ed6e0f8a989cec97700df2b15198c9c481c549 100644 +index b4a19d80bbf71591f25729fd0e98590350cb31d0..d752720f2f234b9dbd2117333fee1bfad663ec02 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java +++ b/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java @@ -12,12 +12,27 @@ public class ServerShutdownThread extends Thread { @@ -496,7 +471,7 @@ index 449e99d1b673870ed6892f6ab2c715a2db35c35d..c7ed6e0f8a989cec97700df2b15198c9 org.spigotmc.AsyncCatcher.enabled = false; // Spigot org.spigotmc.AsyncCatcher.shuttingDown = true; // Paper + server.forceTicks = true; - server.close(); + this.server.close(); + while (!server.hasFullyShutdown) Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); @@ -509,7 +484,7 @@ index 449e99d1b673870ed6892f6ab2c715a2db35c35d..c7ed6e0f8a989cec97700df2b15198c9 } } diff --git a/src/main/java/org/spigotmc/RestartCommand.java b/src/main/java/org/spigotmc/RestartCommand.java -index 6dab105cd7cc4340c031c395c0346d4731355d79..6498dc4c6630bfef1a52edf74d8574e5e4876720 100644 +index a142a56a920e153ed84c08cece993f10d76f7793..92d97a5810a379b427a99b4c63fb9844d823a84f 100644 --- a/src/main/java/org/spigotmc/RestartCommand.java +++ b/src/main/java/org/spigotmc/RestartCommand.java @@ -139,7 +139,7 @@ public class RestartCommand extends Command @@ -522,10 +497,10 @@ index 6dab105cd7cc4340c031c395c0346d4731355d79..6498dc4c6630bfef1a52edf74d8574e5 String[] split = restartScript.split( " " ); if ( split.length > 0 && new File( split[0] ).isFile() ) diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java -index 33a66322d253c7562ae5acbdbc6cc87f7d72a9af..26c9adf7af4328ce2d8e08568019c5b438e28b05 100644 +index 1ffb208094f521883ef0e23baf5fb29380b14273..4d271cae88c16ed2419f896c728fdff612540500 100644 --- a/src/main/java/org/spigotmc/WatchdogThread.java +++ b/src/main/java/org/spigotmc/WatchdogThread.java -@@ -13,6 +13,7 @@ import org.bukkit.Bukkit; +@@ -12,6 +12,7 @@ import org.bukkit.Bukkit; public class WatchdogThread extends Thread { @@ -533,21 +508,21 @@ index 33a66322d253c7562ae5acbdbc6cc87f7d72a9af..26c9adf7af4328ce2d8e08568019c5b4 private static WatchdogThread instance; private long timeoutTime; private boolean restart; -@@ -41,6 +42,7 @@ public class WatchdogThread extends Thread +@@ -40,6 +41,7 @@ public class WatchdogThread extends Thread { - if ( instance == null ) + if ( WatchdogThread.instance == null ) { + if (timeoutTime <= 0) timeoutTime = 300; // Paper - instance = new WatchdogThread( timeoutTime * 1000L, restart ); - instance.start(); + WatchdogThread.instance = new WatchdogThread( timeoutTime * 1000L, restart ); + WatchdogThread.instance.start(); } else @@ -71,12 +73,13 @@ public class WatchdogThread extends Thread // Paper start Logger log = Bukkit.getServer().getLogger(); - long currentTime = monotonicMillis(); -- if ( lastTick != 0 && timeoutTime > 0 && currentTime > lastTick + earlyWarningEvery && !Boolean.getBoolean("disable.watchdog") ) + long currentTime = WatchdogThread.monotonicMillis(); +- if ( this.lastTick != 0 && this.timeoutTime > 0 && currentTime > this.lastTick + this.earlyWarningEvery && !Boolean.getBoolean("disable.watchdog")) // Paper - Add property to disable + MinecraftServer server = MinecraftServer.getServer(); -+ if (lastTick != 0 && timeoutTime > 0 && hasStarted && (!server.isRunning() || (currentTime > lastTick + earlyWarningEvery && !DISABLE_WATCHDOG) )) ++ if ( this.lastTick != 0 && this.timeoutTime > 0 && WatchdogThread.hasStarted && (!server.isRunning() || (currentTime > this.lastTick + this.earlyWarningEvery && !DISABLE_WATCHDOG) )) // Paper - add property to disable { - boolean isLongTimeout = currentTime > lastTick + timeoutTime; + boolean isLongTimeout = currentTime > lastTick + timeoutTime || (!server.isRunning() && !server.hasStopped() && currentTime > lastTick + 1000); @@ -561,17 +536,17 @@ index 33a66322d253c7562ae5acbdbc6cc87f7d72a9af..26c9adf7af4328ce2d8e08568019c5b4 @@ -118,7 +121,7 @@ public class WatchdogThread extends Thread log.log( Level.SEVERE, "------------------------------" ); log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper - ChunkTaskManager.dumpAllChunkLoadInfo(); // Paper -- dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log ); -+ dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( server.serverThread.getId(), Integer.MAX_VALUE ), log ); + com.destroystokyo.paper.io.chunk.ChunkTaskManager.dumpAllChunkLoadInfo(); // Paper +- WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log ); ++ WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( server.serverThread.getId(), Integer.MAX_VALUE ), log ); log.log( Level.SEVERE, "------------------------------" ); // // Paper start - Only print full dump on long timeouts -@@ -139,9 +142,25 @@ public class WatchdogThread extends Thread +@@ -138,9 +141,25 @@ public class WatchdogThread extends Thread if ( isLongTimeout ) { -- if ( restart && !MinecraftServer.getServer().hasStopped() ) +- if ( this.restart && !MinecraftServer.getServer().hasStopped() ) + if ( !server.hasStopped() ) { - RestartCommand.restart(); diff --git a/patches/server-remapped/0439-Optimize-Pathfinding.patch b/patches/server/0395-Optimize-Pathfinding.patch similarity index 51% rename from patches/server-remapped/0439-Optimize-Pathfinding.patch rename to patches/server/0395-Optimize-Pathfinding.patch index 9f2777798..4e073805b 100644 --- a/patches/server-remapped/0439-Optimize-Pathfinding.patch +++ b/patches/server/0395-Optimize-Pathfinding.patch @@ -7,27 +7,10 @@ Prevents pathfinding from spamming failures for things such as arrow attacks. diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java -index a362506f38e8d30543b6cd6d215db561290dac76..c501e42b6fef4af065807182dc5b4c444e74e310 100644 +index 69edca1ef95c37b11fe3f793e6a8f8a674bd7f6f..3f4d7552e7f219aec043f0cc06a816758e5a3f66 100644 --- a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java -@@ -11,6 +11,7 @@ import net.minecraft.core.Position; - import net.minecraft.core.Vec3i; - import net.minecraft.network.protocol.game.DebugPackets; - import net.minecraft.server.MCUtil; -+import net.minecraft.server.MinecraftServer; - import net.minecraft.util.Mth; - import net.minecraft.world.entity.Entity; - import net.minecraft.world.entity.Mob; -@@ -32,7 +33,7 @@ public abstract class PathNavigation { - protected final Mob mob; public Entity getEntity() { return mob; } // Paper - OBFHELPER - protected final Level level; - @Nullable -- protected Path path; -+ protected Path path; protected final Path getCurrentPath() { return this.path; } // Paper - OBFHELPER - protected double speedModifier; - protected int tick; - protected int lastStuckCheck; -@@ -184,10 +185,30 @@ public abstract class PathNavigation { +@@ -190,9 +190,29 @@ public abstract class PathNavigation { return this.moveTo(this.createPath(x, y, z, 1), speed); } @@ -38,21 +21,20 @@ index a362506f38e8d30543b6cd6d215db561290dac76..c501e42b6fef4af065807182dc5b4c44 + public boolean moveTo(Entity entity, double speed) { + // Paper start - Pathfinding optimizations -+ if (this.pathfindFailures > 10 && this.getCurrentPath() == null && MinecraftServer.currentTick < this.lastFailure + 40) { ++ if (this.pathfindFailures > 10 && this.path == null && net.minecraft.server.MinecraftServer.currentTick < this.lastFailure + 40) { + return false; + } + // Paper end - Path pathentity = this.createPath(entity, 1); - -- return pathentity != null && this.moveTo(pathentity, speed); + Path path = this.createPath(entity, 1); +- return path != null && this.moveTo(path, speed); + // Paper start - Pathfinding optimizations -+ if (pathentity != null && this.moveTo(pathentity, speed)) { ++ if (path != null && this.moveTo(path, speed)) { + this.lastFailure = 0; + this.pathfindFailures = 0; + return true; + } else { + this.pathfindFailures++; -+ this.lastFailure = MinecraftServer.currentTick; ++ this.lastFailure = net.minecraft.server.MinecraftServer.currentTick; + return false; + } + // Paper end diff --git a/patches/server-remapped/0440-Reduce-Either-Optional-allocation.patch b/patches/server/0396-Reduce-Either-Optional-allocation.patch similarity index 95% rename from patches/server-remapped/0440-Reduce-Either-Optional-allocation.patch rename to patches/server/0396-Reduce-Either-Optional-allocation.patch index 991b0f903..0f4641263 100644 --- a/patches/server-remapped/0440-Reduce-Either-Optional-allocation.patch +++ b/patches/server/0396-Reduce-Either-Optional-allocation.patch @@ -7,7 +7,7 @@ In order to get chunk values, we shouldn't need to create an optional each time. diff --git a/src/main/java/com/mojang/datafixers/util/Either.java b/src/main/java/com/mojang/datafixers/util/Either.java -index fc8dbdf43833d76d8dc5f4e92575ca2965afa93a..ab71cdb3a8c2bec036ece630a0e0f088653e928f 100644 +index a90adac7bd7ebd423f480e9ae0f44cb9d521fa4f..3f65fe71024928e35111fc6719a290aab9a6859e 100644 --- a/src/main/java/com/mojang/datafixers/util/Either.java +++ b/src/main/java/com/mojang/datafixers/util/Either.java @@ -22,7 +22,7 @@ public abstract class Either implements App, L> { diff --git a/patches/server/0397-Remove-streams-from-PairedQueue.patch b/patches/server/0397-Remove-streams-from-PairedQueue.patch new file mode 100644 index 000000000..91f6f25ab --- /dev/null +++ b/patches/server/0397-Remove-streams-from-PairedQueue.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Mon, 6 Apr 2020 18:10:43 -0700 +Subject: [PATCH] Remove streams from PairedQueue + +We shouldn't be doing stream calls just to see if the queue is +empty. This creates loads of garbage thanks to how often it's called. + +diff --git a/src/main/java/net/minecraft/util/thread/StrictQueue.java b/src/main/java/net/minecraft/util/thread/StrictQueue.java +index 66591e23bc9e0df968fb6b291a3ad3773debdf29..c4a20df21e1fe5556fddac64b52d542579758e2c 100644 +--- a/src/main/java/net/minecraft/util/thread/StrictQueue.java ++++ b/src/main/java/net/minecraft/util/thread/StrictQueue.java +@@ -22,9 +22,12 @@ public interface StrictQueue { + private final List> queueList; + + public FixedPriorityQueue(int priorityCount) { +- this.queueList = IntStream.range(0, priorityCount).mapToObj((i) -> { +- return Queues.newConcurrentLinkedQueue(); +- }).collect(Collectors.toList()); ++ // Paper start - remove streams ++ this.queueList = new java.util.ArrayList<>(priorityCount); // queues ++ for (int j = 0; j < priorityCount; ++j) { ++ this.queueList.add(Queues.newConcurrentLinkedQueue()); ++ } ++ // Paper end - remove streams + } + + @Nullable +@@ -49,7 +52,16 @@ public interface StrictQueue { + + @Override + public boolean isEmpty() { +- return this.queueList.stream().allMatch(Collection::isEmpty); ++ // Paper start - remove streams ++ // why are we doing streams every time we might want to execute a task? ++ for (int i = 0, len = this.queueList.size(); i < len; ++i) { ++ Queue queue = this.queueList.get(i); ++ if (!queue.isEmpty()) { ++ return false; ++ } ++ } ++ return true; ++ // Paper end - remove streams + } + + @Override diff --git a/patches/server-remapped/0442-Reduce-memory-footprint-of-NBTTagCompound.patch b/patches/server/0398-Reduce-memory-footprint-of-NBTTagCompound.patch similarity index 50% rename from patches/server-remapped/0442-Reduce-memory-footprint-of-NBTTagCompound.patch rename to patches/server/0398-Reduce-memory-footprint-of-NBTTagCompound.patch index dcba632a3..cea824d10 100644 --- a/patches/server-remapped/0442-Reduce-memory-footprint-of-NBTTagCompound.patch +++ b/patches/server/0398-Reduce-memory-footprint-of-NBTTagCompound.patch @@ -8,45 +8,36 @@ is important because we clone chunk data after reading it for safety. So, reduce the impact of the clone on GC. diff --git a/src/main/java/net/minecraft/nbt/CompoundTag.java b/src/main/java/net/minecraft/nbt/CompoundTag.java -index a91bf94ed9f2f353a685194fc91c4b101ccc1232..c856ca720a9329a94bb07eaa3060c034f95718b3 100644 +index 750df4ab2fbfdcf759f4d3451340e66b6764391d..1aa3af8c7714b2c850fb4264c863db8e639e6284 100644 --- a/src/main/java/net/minecraft/nbt/CompoundTag.java +++ b/src/main/java/net/minecraft/nbt/CompoundTag.java -@@ -26,6 +26,7 @@ import net.minecraft.ReportedException; - import net.minecraft.network.chat.Component; - import net.minecraft.network.chat.MutableComponent; - import net.minecraft.network.chat.TextComponent; -+import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; // Paper - import org.apache.logging.log4j.LogManager; - import org.apache.logging.log4j.Logger; - -@@ -47,7 +48,7 @@ public class CompoundTag implements Tag { +@@ -34,7 +34,7 @@ public class CompoundTag implements Tag { if (i > 512) { throw new RuntimeException("Tried to read NBT tag with too high complexity, depth > 512"); } else { -- HashMap hashmap = Maps.newHashMap(); -+ Object2ObjectOpenHashMap hashmap = new Object2ObjectOpenHashMap<>(8, 0.8f); // Paper - reduce memory footprint of NBTTagCompound +- Map map = Maps.newHashMap(); ++ it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap map = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(8, 0.8f); // Paper - reduce memory footprint of NBTTagCompound - byte b0; - -@@ -83,7 +84,7 @@ public class CompoundTag implements Tag { + byte b; + while((b = CompoundTag.readNamedTagType(dataInput, nbtAccounter)) != 0) { +@@ -67,7 +67,7 @@ public class CompoundTag implements Tag { } public CompoundTag() { - this(Maps.newHashMap()); -+ this(new Object2ObjectOpenHashMap<>(8, 0.8f)); // Paper - reduce memory footprint of NBTTagCompound ++ this(new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(8, 0.8f)); // Paper - reduce memory footprint of NBTTagCompound } @Override -@@ -417,9 +418,17 @@ public class CompoundTag implements Tag { +@@ -374,8 +374,16 @@ public class CompoundTag implements Tag { @Override public CompoundTag copy() { - Map map = Maps.newHashMap(Maps.transformValues(this.tags, Tag::copy)); -+ // Paper start - reduce memory footprint of NBTTagCompound -+ Object2ObjectOpenHashMap ret = new Object2ObjectOpenHashMap<>(this.tags.size(), 0.8f); - - return new CompoundTag(map); -+ Iterator> iterator = (this.tags instanceof Object2ObjectOpenHashMap) ? ((Object2ObjectOpenHashMap)this.tags).object2ObjectEntrySet().fastIterator() : this.tags.entrySet().iterator(); ++ // Paper start - reduce memory footprint of NBTTagCompound ++ it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(this.tags.size(), 0.8f); ++ java.util.Iterator> iterator = (this.tags instanceof it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap) ? ((it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap)this.tags).object2ObjectEntrySet().fastIterator() : this.tags.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + ret.put(entry.getKey(), entry.getValue().copy()); @@ -56,4 +47,4 @@ index a91bf94ed9f2f353a685194fc91c4b101ccc1232..c856ca720a9329a94bb07eaa3060c034 + // Paper end - reduce memory footprint of NBTTagCompound } - public boolean equals(Object object) { + @Override diff --git a/patches/server-remapped/0443-Prevent-opening-inventories-when-frozen.patch b/patches/server/0399-Prevent-opening-inventories-when-frozen.patch similarity index 76% rename from patches/server-remapped/0443-Prevent-opening-inventories-when-frozen.patch rename to patches/server/0399-Prevent-opening-inventories-when-frozen.patch index 7b2a22a56..29b12f74d 100644 --- a/patches/server-remapped/0443-Prevent-opening-inventories-when-frozen.patch +++ b/patches/server/0399-Prevent-opening-inventories-when-frozen.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Prevent opening inventories when frozen diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 162b1a8c6ab57aafa4f6deefc842755a8e14208e..efacfcaab444270b985f3a7fe0ef97e33c18a9de 100644 +index bfa91166c18110877f751a5325e59623a05325d0..42c2862530cff79a9b09850faccb683df1f2a5c8 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -557,7 +557,7 @@ public class ServerPlayer extends Player implements ContainerListener { +@@ -608,7 +608,7 @@ public class ServerPlayer extends Player { containerUpdateDelay = level.paperConfig.containerUpdateTickRate; } // Paper end @@ -17,43 +17,34 @@ index 162b1a8c6ab57aafa4f6deefc842755a8e14208e..efacfcaab444270b985f3a7fe0ef97e3 this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); // Paper this.containerMenu = this.inventoryMenu; } -@@ -1404,7 +1404,7 @@ public class ServerPlayer extends Player implements ContainerListener { +@@ -1449,7 +1449,7 @@ public class ServerPlayer extends Player { } else { // CraftBukkit start this.containerMenu = container; - this.connection.send(new ClientboundOpenScreenPacket(container.containerId, container.getType(), container.getTitle())); + if (!isImmobile()) this.connection.send(new ClientboundOpenScreenPacket(container.containerId, container.getType(), container.getTitle())); // Paper // CraftBukkit end - container.addSlotListener(this); + this.initMenu(container); return OptionalInt.of(this.containerCounter); -@@ -2206,7 +2206,7 @@ public class ServerPlayer extends Player implements ContainerListener { - } - - @Override -- protected boolean isImmobile() { -+ public boolean isImmobile() { // Paper - protected > public - return super.isImmobile() || (this.connection != null && this.connection.isDisconnected()); // Paper - } - diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -index a73c6ddd6bf66cc21ae5b25daacdece8cbfeeeac..ae6faa331fcbefd99ee1cd92c88926d767fc50ee 100644 +index 43cee8b0b2b94d6db6303a1631731ed515eb806d..31b62dc1ee06b254c398cbfe157283fb199ef0fe 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -@@ -323,7 +323,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { +@@ -322,7 +322,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { if (adventure$title == null) adventure$title = io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.deserialize(container.getBukkitView().getTitle()); // Paper //player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, CraftChatMessage.fromString(title)[0])); // Paper // Paper - comment - player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper + if (!player.isImmobile()) player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper - getHandle().containerMenu = container; - getHandle().containerMenu.addSlotListener(player); + player.containerMenu = container; + player.initMenu(container); } -@@ -397,7 +397,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { +@@ -396,7 +396,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { net.kyori.adventure.text.Component adventure$title = inventory.title(); // Paper if (adventure$title == null) adventure$title = io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.deserialize(inventory.getTitle()); // Paper //player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, CraftChatMessage.fromString(title)[0])); // Paper - comment - player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper + if (!player.isImmobile()) player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper player.containerMenu = container; - player.containerMenu.addSlotListener(player); + player.initMenu(container); } diff --git a/patches/server-remapped/0444-Optimise-ArraySetSorted-removeIf.patch b/patches/server/0400-Optimise-ArraySetSorted-removeIf.patch similarity index 60% rename from patches/server-remapped/0444-Optimise-ArraySetSorted-removeIf.patch rename to patches/server/0400-Optimise-ArraySetSorted-removeIf.patch index dad03aa17..1f9f1e2e4 100644 --- a/patches/server-remapped/0444-Optimise-ArraySetSorted-removeIf.patch +++ b/patches/server/0400-Optimise-ArraySetSorted-removeIf.patch @@ -6,30 +6,19 @@ Subject: [PATCH] Optimise ArraySetSorted#removeIf Remove iterator allocation and ensure the call is always O(n) diff --git a/src/main/java/net/minecraft/util/SortedArraySet.java b/src/main/java/net/minecraft/util/SortedArraySet.java -index 93813a508be1e1e600a8211f9822f2087328de70..8f03847eeb95ccdb69ad181b38b8724c9c72a76b 100644 +index d1b2ba24ef54e01c6249c3b2ca16e80f03c001a6..5f1c4c6b9e36f2d6ec43b82cc0e2cae24b800dc4 100644 --- a/src/main/java/net/minecraft/util/SortedArraySet.java +++ b/src/main/java/net/minecraft/util/SortedArraySet.java -@@ -10,8 +10,8 @@ import java.util.NoSuchElementException; - public class SortedArraySet extends AbstractSet { - - private final Comparator comparator; -- private T[] contents; -- private int size; -+ private T[] contents; private final T[] getBackingArray() { return this.contents; } // Paper - OBFHELPER -+ private int size; private final int getSize() { return this.size; } private final void setSize(int value) { this.size = value; } // Paper - OBFHELPER - - private SortedArraySet(int initialCapacity, Comparator comparator) { - this.comparator = comparator; -@@ -22,6 +22,42 @@ public class SortedArraySet extends AbstractSet { +@@ -22,6 +22,41 @@ public class SortedArraySet extends AbstractSet { + this.contents = (T[])castRawArray(new Object[initialCapacity]); } } - + // Paper start - optimise removeIf + @Override + public boolean removeIf(java.util.function.Predicate filter) { + // prev. impl used an iterator, which could be n^2 and creates garbage -+ int i = 0, len = this.getSize(); -+ T[] backingArray = this.getBackingArray(); ++ int i = 0, len = this.size; ++ T[] backingArray = this.contents; + + for (;;) { + if (i >= len) { @@ -55,11 +44,10 @@ index 93813a508be1e1e600a8211f9822f2087328de70..8f03847eeb95ccdb69ad181b38b8724c + + // cleanup end + Arrays.fill(backingArray, lastIndex, len, null); -+ this.setSize(lastIndex); ++ this.size = lastIndex; + return true; + } + // Paper end - optimise removeIf -+ - public static > SortedArraySet create(int initialCapacity) { - return new SortedArraySet<>(initialCapacity, (Comparator)Comparator.naturalOrder()); // Paper - decompile fix - } + + public static > SortedArraySet create() { + return create(10); diff --git a/patches/server-remapped/0445-Don-t-run-entity-collision-code-if-not-needed.patch b/patches/server/0401-Don-t-run-entity-collision-code-if-not-needed.patch similarity index 81% rename from patches/server-remapped/0445-Don-t-run-entity-collision-code-if-not-needed.patch rename to patches/server/0401-Don-t-run-entity-collision-code-if-not-needed.patch index 474688a9b..ce4b9003b 100644 --- a/patches/server-remapped/0445-Don-t-run-entity-collision-code-if-not-needed.patch +++ b/patches/server/0401-Don-t-run-entity-collision-code-if-not-needed.patch @@ -7,19 +7,19 @@ Will not run if max entity craming is disabled and the max collisions per entity is less than or equal to 0 diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 43fbe7d220f61802ae0cb0620ad078c5df7b69bc..46b962183e2e27ed93054ad9fb6d8ecbf70bc5f9 100644 +index 6cc2d26403aa5074218b4b76e2d8ed9e8409a0ae..0fd79c399e723b5a9db04c8f2fe7b6ec66c0cf44 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -2941,10 +2941,16 @@ public abstract class LivingEntity extends Entity { +@@ -3256,10 +3256,16 @@ public abstract class LivingEntity extends Entity { protected void serverAiStep() {} protected void pushEntities() { -+ // Paper - start don't run getEntities if we're not going to use its result ++ // Paper start - don't run getEntities if we're not going to use its result + int i = this.level.getGameRules().getInt(GameRules.RULE_MAX_ENTITY_CRAMMING); + if (i <= 0 && level.paperConfig.maxCollisionsPerEntity <= 0) { + return; + } -+ // Paper - end don't run getEntities if we're not going to use its result ++ // Paper end - don't run getEntities if we're not going to use its result List list = this.level.getEntities(this, this.getBoundingBox(), EntitySelector.pushableBy(this)); if (!list.isEmpty()) { diff --git a/patches/server-remapped/0447-Restrict-vanilla-teleport-command-to-valid-locations.patch b/patches/server/0402-Restrict-vanilla-teleport-command-to-valid-locations.patch similarity index 90% rename from patches/server-remapped/0447-Restrict-vanilla-teleport-command-to-valid-locations.patch rename to patches/server/0402-Restrict-vanilla-teleport-command-to-valid-locations.patch index bc23f7141..b0ce74823 100644 --- a/patches/server-remapped/0447-Restrict-vanilla-teleport-command-to-valid-locations.patch +++ b/patches/server/0402-Restrict-vanilla-teleport-command-to-valid-locations.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Restrict vanilla teleport command to valid locations Fixes GH-3165, GH-3575 diff --git a/src/main/java/net/minecraft/server/commands/TeleportCommand.java b/src/main/java/net/minecraft/server/commands/TeleportCommand.java -index 774180d9e450199309fee65b1d10e1592f84548a..d04ce9a323b079b4556b8c341fb11186e8d3e05d 100644 +index 85ae18b7f8a26f83ea0cf1ae17cfa88b796fcc77..d0109df7fad51fc0444459f5d367254c8f4c355e 100644 --- a/src/main/java/net/minecraft/server/commands/TeleportCommand.java +++ b/src/main/java/net/minecraft/server/commands/TeleportCommand.java -@@ -141,6 +141,12 @@ public class TeleportCommand { +@@ -148,6 +148,12 @@ public class TeleportCommand { private static void performTeleport(CommandSourceStack source, Entity target, ServerLevel world, double x, double y, double z, Set movementFlags, float yaw, float pitch, @Nullable TeleportCommand.LookAt facingLocation) throws CommandSyntaxException { BlockPos blockposition = new BlockPos(x, y, z); diff --git a/patches/server-remapped/0448-Implement-Player-Client-Options-API.patch b/patches/server/0403-Implement-Player-Client-Options-API.patch similarity index 50% rename from patches/server-remapped/0448-Implement-Player-Client-Options-API.patch rename to patches/server/0403-Implement-Player-Client-Options-API.patch index dcdbea549..0f8578078 100644 --- a/patches/server-remapped/0448-Implement-Player-Client-Options-API.patch +++ b/patches/server/0403-Implement-Player-Client-Options-API.patch @@ -84,105 +84,57 @@ index 0000000000000000000000000000000000000000..b6f4400df3d8ec7e06a996de54f8cabb + .toString(); + } +} -diff --git a/src/main/java/net/minecraft/network/protocol/game/ServerboundClientInformationPacket.java b/src/main/java/net/minecraft/network/protocol/game/ServerboundClientInformationPacket.java -index 1f486cfd77b49568540398b1b3fa6127b17ba6aa..4b43740f9ff4feab4f1cd2f8e91d55be3cf8eb50 100644 ---- a/src/main/java/net/minecraft/network/protocol/game/ServerboundClientInformationPacket.java -+++ b/src/main/java/net/minecraft/network/protocol/game/ServerboundClientInformationPacket.java -@@ -41,14 +41,17 @@ public class ServerboundClientInformationPacket implements Packet POSES = ImmutableMap.builder().put(Pose.STANDING, Player.STANDING_DIMENSIONS).put(Pose.SLEEPING, Player.SLEEPING_DIMENSIONS).put(Pose.FALL_FLYING, EntityDimensions.scalable(0.6F, 0.6F)).put(Pose.SWIMMING, EntityDimensions.scalable(0.6F, 0.6F)).put(Pose.SPIN_ATTACK, EntityDimensions.scalable(0.6F, 0.6F)).put(Pose.CROUCHING, EntityDimensions.scalable(0.6F, 1.5F)).put(Pose.DYING, EntityDimensions.fixed(0.2F, 0.2F)).build(); +@@ -144,7 +144,7 @@ public abstract class Player extends LivingEntity { + private static final int FLY_ACHIEVEMENT_SPEED = 25; private static final EntityDataAccessor DATA_PLAYER_ABSORPTION_ID = SynchedEntityData.defineId(Player.class, EntityDataSerializers.FLOAT); private static final EntityDataAccessor DATA_SCORE_ID = SynchedEntityData.defineId(Player.class, EntityDataSerializers.INT); - protected static final EntityDataAccessor DATA_PLAYER_MODE_CUSTOMISATION = SynchedEntityData.defineId(Player.class, EntityDataSerializers.BYTE); -+ protected static final EntityDataAccessor DATA_PLAYER_MODE_CUSTOMISATION = SynchedEntityData.defineId(Player.class, EntityDataSerializers.BYTE); public static EntityDataAccessor getSkinPartsWatcher() { return DATA_PLAYER_MODE_CUSTOMISATION; } // Paper - OBFHELPER ++ public static final EntityDataAccessor DATA_PLAYER_MODE_CUSTOMISATION = SynchedEntityData.defineId(Player.class, EntityDataSerializers.BYTE); // Paper - protected -> public protected static final EntityDataAccessor DATA_PLAYER_MAIN_HAND = SynchedEntityData.defineId(Player.class, EntityDataSerializers.BYTE); protected static final EntityDataAccessor DATA_SHOULDER_LEFT = SynchedEntityData.defineId(Player.class, EntityDataSerializers.COMPOUND_TAG); protected static final EntityDataAccessor DATA_SHOULDER_RIGHT = SynchedEntityData.defineId(Player.class, EntityDataSerializers.COMPOUND_TAG); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 20de8e358789d05bb5ac15e4cdd7dda85b61b7f8..eb366396820c9b6731469df4198e0884a431a77c 100644 +index 2ed7920b0e046bc9d581878a10b04ad784bb8655..0a6d6ea67eaf8b2a59ec45fb3ffb85096f509997 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1,5 +1,8 @@ - package org.bukkit.craftbukkit.entity; - -+import com.destroystokyo.paper.ClientOption.ChatVisibility; -+import com.destroystokyo.paper.PaperSkinParts; -+import com.destroystokyo.paper.ClientOption; - import com.destroystokyo.paper.Title; - import com.google.common.base.Preconditions; - import com.google.common.collect.ImmutableSet; -@@ -2250,6 +2253,24 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -516,6 +516,24 @@ public class CraftPlayer extends CraftHumanEntity implements Player { public void setViewDistance(int viewDistance) { throw new NotImplementedException("Per-Player View Distance APIs need further understanding to properly implement (There are per world view distances though!)"); // TODO } + + @Override -+ public T getClientOption(ClientOption type) { -+ if(ClientOption.SKIN_PARTS.equals(type)) { -+ return type.getType().cast(new PaperSkinParts(getHandle().getEntityData().get(net.minecraft.world.entity.player.Player.getSkinPartsWatcher()))); -+ } else if(ClientOption.CHAT_COLORS_ENABLED.equals(type)) { -+ return type.getType().cast(getHandle().hasChatColorsEnabled()); -+ } else if(ClientOption.CHAT_VISIBILITY.equals(type)) { -+ return type.getType().cast(getHandle().getChatVisibility() == null ? ChatVisibility.UNKNOWN : ChatVisibility.valueOf(getHandle().getChatVisibility().name())); -+ } else if(ClientOption.LOCALE.equals(type)) { ++ public T getClientOption(com.destroystokyo.paper.ClientOption type) { ++ if(com.destroystokyo.paper.ClientOption.SKIN_PARTS.equals(type)) { ++ return type.getType().cast(new com.destroystokyo.paper.PaperSkinParts(getHandle().getEntityData().get(net.minecraft.world.entity.player.Player.DATA_PLAYER_MODE_CUSTOMISATION))); ++ } else if(com.destroystokyo.paper.ClientOption.CHAT_COLORS_ENABLED.equals(type)) { ++ return type.getType().cast(getHandle().canChatInColor()); ++ } else if(com.destroystokyo.paper.ClientOption.CHAT_VISIBILITY.equals(type)) { ++ return type.getType().cast(getHandle().getChatVisibility() == null ? com.destroystokyo.paper.ClientOption.ChatVisibility.UNKNOWN : com.destroystokyo.paper.ClientOption.ChatVisibility.valueOf(getHandle().getChatVisibility().name())); ++ } else if(com.destroystokyo.paper.ClientOption.LOCALE.equals(type)) { + return type.getType().cast(getLocale()); -+ } else if(ClientOption.MAIN_HAND.equals(type)) { ++ } else if(com.destroystokyo.paper.ClientOption.MAIN_HAND.equals(type)) { + return type.getType().cast(getMainHand()); -+ } else if(ClientOption.VIEW_DISTANCE.equals(type)) { ++ } else if(com.destroystokyo.paper.ClientOption.VIEW_DISTANCE.equals(type)) { + return type.getType().cast(getClientViewDistance()); + } + throw new RuntimeException("Unknown settings type"); + } // Paper end - // Spigot start + @Override diff --git a/patches/server-remapped/0449-Fix-Chunk-Post-Processing-deadlock-risk.patch b/patches/server/0404-Fix-Chunk-Post-Processing-deadlock-risk.patch similarity index 87% rename from patches/server-remapped/0449-Fix-Chunk-Post-Processing-deadlock-risk.patch rename to patches/server/0404-Fix-Chunk-Post-Processing-deadlock-risk.patch index 1d32694a1..eff3a5534 100644 --- a/patches/server-remapped/0449-Fix-Chunk-Post-Processing-deadlock-risk.patch +++ b/patches/server/0404-Fix-Chunk-Post-Processing-deadlock-risk.patch @@ -25,19 +25,18 @@ This successfully fixed a reoccurring and highly reproduceable crash for heightmaps. diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 49728aab7512ea8486d277d34e80d3c6a4727aac..dbe60f5d24fb39be52c3cb8f933371b1626951df 100644 +index c82345c74e0e6246f304283c2e06e2d1fcfe53ca..d3094c8a6a906737d4ca56a76ff40b3586961680 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -181,6 +181,8 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -189,6 +189,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider }; // CraftBukkit end + final CallbackExecutor chunkLoadConversionCallbackExecutor = new CallbackExecutor(); // Paper -+ // Paper start - distance maps private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>(); - -@@ -1054,7 +1056,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + // Paper start - no-tick view distance +@@ -1028,7 +1029,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider return Either.left(chunk); }); }, (runnable) -> { @@ -47,10 +46,10 @@ index 49728aab7512ea8486d277d34e80d3c6a4727aac..dbe60f5d24fb39be52c3cb8f933371b1 completablefuture1.thenAcceptAsync((either) -> { diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 531fe1259a1d60ff69321c3fefbf97f7141e6475..b45fe750c8ca838e1beebff4077e5819eec2836c 100644 +index 751454ad5a2c374c01ff360535428db36c0aa1b3..e4f5f564892836a2e925f419e8fcb60c70b21a47 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -1021,6 +1021,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -985,6 +985,7 @@ public class ServerChunkCache extends ChunkSource { return super.pollTask() || execChunkTask; // Paper } } finally { diff --git a/patches/server-remapped/0450-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch b/patches/server/0405-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch similarity index 88% rename from patches/server-remapped/0450-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch rename to patches/server/0405-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch index 1469edc10..324693d28 100644 --- a/patches/server-remapped/0450-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch +++ b/patches/server/0405-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch @@ -7,10 +7,10 @@ Subject: [PATCH] Don't crash if player is attempted to be removed from I suspect it deals with teleporting as it uses players current x/y/z diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java -index 71a51cc99e26579e765f88340588e23956888929..90429d3f5c5b725098cfb001d54c70608f3df7bb 100644 +index 38eebda226e007c8910e04f502ce218cdfe1d456..b49d380ef088aed3204ec71abc437c348ef004fa 100644 --- a/src/main/java/net/minecraft/server/level/DistanceManager.java +++ b/src/main/java/net/minecraft/server/level/DistanceManager.java -@@ -245,8 +245,8 @@ public abstract class DistanceManager { +@@ -253,8 +253,8 @@ public abstract class DistanceManager { ObjectSet objectset = (ObjectSet) this.playersPerChunk.get(i); if (objectset == null) return; // CraftBukkit - SPIGOT-6208 diff --git a/patches/server-remapped/0451-Broadcast-join-message-to-console.patch b/patches/server/0406-Broadcast-join-message-to-console.patch similarity index 65% rename from patches/server-remapped/0451-Broadcast-join-message-to-console.patch rename to patches/server/0406-Broadcast-join-message-to-console.patch index de365413d..255cb8162 100644 --- a/patches/server-remapped/0451-Broadcast-join-message-to-console.patch +++ b/patches/server/0406-Broadcast-join-message-to-console.patch @@ -5,16 +5,16 @@ Subject: [PATCH] Broadcast join message to console diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 984ac19dcab446531c816e365c7c149e2c49d567..e043722436492140162940770c22be47690fb47f 100644 +index 3431d28fd69c634ee0a941796308b88bb51bdaac..5432ce5b86b7731fe5d06d334e4e191f2eb2f429 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -284,7 +284,9 @@ public abstract class PlayerList { +@@ -286,7 +286,9 @@ public abstract class PlayerList { if (jm != null && !jm.equals(net.kyori.adventure.text.Component.empty())) { // Paper - Adventure joinMessage = PaperAdventure.asVanilla(jm); // Paper - Adventure -- server.getPlayerList().broadcastAll(new ClientboundChatPacket(joinMessage, ChatType.SYSTEM, Util.NIL_UUID)); // Paper - Adventure +- this.server.getPlayerList().broadcastAll(new ClientboundChatPacket(joinMessage, ChatType.SYSTEM, Util.NIL_UUID)); // Paper - Adventure + // Paper start - Removed sendAll for loop and broadcasted to console also -+ server.getPlayerList().sendMessage(joinMessage); // Paper - Adventure ++ this.server.getPlayerList().broadcastMessage(joinMessage, ChatType.SYSTEM, Util.NIL_UUID); // Paper - Adventure + // Paper end } // CraftBukkit end diff --git a/patches/server-remapped/0452-Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch b/patches/server/0407-Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch similarity index 61% rename from patches/server-remapped/0452-Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch rename to patches/server/0407-Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch index e4ac02eb9..c85247b41 100644 --- a/patches/server-remapped/0452-Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch +++ b/patches/server/0407-Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch @@ -28,11 +28,11 @@ receives a deterministic result, and should no longer require 1 tick delays anymore. diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index dbe60f5d24fb39be52c3cb8f933371b1626951df..b3ca4300b280a24f3ed2acaffdd6ae2cdffd140d 100644 +index d3094c8a6a906737d4ca56a76ff40b3586961680..2cb807f7095648948527b5b9151770193970cc00 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1584,7 +1584,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - }); +@@ -1529,7 +1529,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + // Paper end - per player view distance } - protected void addEntity(Entity entity) { @@ -40,7 +40,7 @@ index dbe60f5d24fb39be52c3cb8f933371b1626951df..b3ca4300b280a24f3ed2acaffdd6ae2c org.spigotmc.AsyncCatcher.catchOp("entity track"); // Spigot // Paper start - ignore and warn about illegal addEntity calls instead of crashing server if (!entity.valid || entity.level != this.level || this.entityMap.containsKey(entity.getId())) { -@@ -1593,6 +1593,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1538,6 +1538,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider .printStackTrace(); return; } @@ -49,10 +49,10 @@ index dbe60f5d24fb39be52c3cb8f933371b1626951df..b3ca4300b280a24f3ed2acaffdd6ae2c if (!(entity instanceof EnderDragonPart)) { EntityType entitytypes = entity.getType(); diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index aa979d17c264840ebd528708df3d6118e69fec68..75a095e0c2177dc1b46b080597ff8f12f1480acc 100644 +index aec3ded7f65e4a97796afc01b71eeb89c2b3fb70..a30840b74bc2574725c42735f633630d9b471d54 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -237,6 +237,7 @@ public class ServerPlayer extends Player implements ContainerListener { +@@ -237,6 +237,7 @@ public class ServerPlayer extends Player { public double maxHealthCache; public boolean joining = true; public boolean sentListPacket = false; @@ -61,10 +61,10 @@ index aa979d17c264840ebd528708df3d6118e69fec68..75a095e0c2177dc1b46b080597ff8f12 // CraftBukkit end public PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index e043722436492140162940770c22be47690fb47f..454d60566743e02e7e55868c7bb45e30583dfa8f 100644 +index 5432ce5b86b7731fe5d06d334e4e191f2eb2f429..3a13c151066c8784fdc844e1d6310f77ff32e7f1 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -272,6 +272,12 @@ public abstract class PlayerList { +@@ -274,6 +274,12 @@ public abstract class PlayerList { this.playersByUUID.put(player.getUUID(), player); // this.sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, new EntityPlayer[]{entityplayer})); // CraftBukkit - replaced with loop below @@ -75,9 +75,9 @@ index e043722436492140162940770c22be47690fb47f..454d60566743e02e7e55868c7bb45e30 + mountSavedVehicle(player, worldserver1, nbttagcompound); + // Paper end // CraftBukkit start - PlayerJoinEvent playerJoinEvent = new org.bukkit.event.player.PlayerJoinEvent(cserver.getPlayer(player), PaperAdventure.asAdventure(chatmessage)); // Paper - Adventure - cserver.getPluginManager().callEvent(playerJoinEvent); -@@ -307,6 +313,8 @@ public abstract class PlayerList { + PlayerJoinEvent playerJoinEvent = new org.bukkit.event.player.PlayerJoinEvent(this.cserver.getPlayer(player), PaperAdventure.asAdventure(chatmessage)); // Paper - Adventure + this.cserver.getPluginManager().callEvent(playerJoinEvent); +@@ -309,6 +315,8 @@ public abstract class PlayerList { player.connection.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, new ServerPlayer[] { entityplayer1})); } player.sentListPacket = true; @@ -86,64 +86,34 @@ index e043722436492140162940770c22be47690fb47f..454d60566743e02e7e55868c7bb45e30 // CraftBukkit end player.connection.send(new ClientboundSetEntityDataPacket(player.getId(), player.getEntityData(), true)); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn -@@ -332,6 +340,11 @@ public abstract class PlayerList { +@@ -334,6 +342,11 @@ public abstract class PlayerList { playerconnection.send(new ClientboundUpdateMobEffectPacket(player.getId(), mobeffect)); } + // Paper start - move vehicle into method so it can be called above - short circuit around that code + onPlayerJoinFinish(player, worldserver1, s1); + } -+ private void mountSavedVehicle(ServerPlayer entityplayer, ServerLevel worldserver1, CompoundTag nbttagcompound) { ++ private void mountSavedVehicle(ServerPlayer player, ServerLevel worldserver1, CompoundTag nbttagcompound) { + // Paper end if (nbttagcompound != null && nbttagcompound.contains("RootVehicle", 10)) { CompoundTag nbttagcompound1 = nbttagcompound.getCompound("RootVehicle"); // CraftBukkit start -@@ -354,20 +367,20 @@ public abstract class PlayerList { - Entity entity1; - - if (entity.getUUID().equals(uuid)) { -- player.startRiding(entity, true); -+ entityplayer.startRiding(entity, true); - } else { - iterator1 = entity.getIndirectPassengers().iterator(); - - while (iterator1.hasNext()) { - entity1 = (Entity) iterator1.next(); - if (entity1.getUUID().equals(uuid)) { -- player.startRiding(entity1, true); -+ entityplayer.startRiding(entity1, true); - break; - } - } - } - -- if (!player.isPassenger()) { -+ if (!entityplayer.isPassenger()) { - PlayerList.LOGGER.warn("Couldn't reattach entity to player"); - worldserver1.despawn(entity); - iterator1 = entity.getIndirectPassengers().iterator(); -@@ -380,16 +393,20 @@ public abstract class PlayerList { +@@ -382,6 +395,10 @@ public abstract class PlayerList { } } -- player.initMenu(); + // Paper start + } -+ public void onPlayerJoinFinish(ServerPlayer entityplayer, ServerLevel worldserver1, String s1) { ++ public void onPlayerJoinFinish(ServerPlayer player, ServerLevel worldserver1, String s1) { + // Paper end -+ entityplayer.initMenu(); + player.initInventoryMenu(); + // CraftBukkit - Moved from above, added world // Paper start - Add to collideRule team if needed - final Scoreboard scoreboard = this.getServer().getLevel(Level.OVERWORLD).getScoreboard(); - final PlayerTeam collideRuleTeam = scoreboard.getTeam(collideRuleTeamName); -- if (this.collideRuleTeamName != null && collideRuleTeam != null && player.getTeam() == null) { -- scoreboard.addPlayerToTeam(player.getScoreboardName(), collideRuleTeam); -+ if (this.collideRuleTeamName != null && collideRuleTeam != null && entityplayer.getTeam() == null) { -+ scoreboard.addPlayerToTeam(entityplayer.getScoreboardName(), collideRuleTeam); +@@ -391,6 +408,7 @@ public abstract class PlayerList { + scoreboard.addPlayerToTeam(player.getScoreboardName(), collideRuleTeam); } // Paper end - // CraftBukkit - Moved from above, added world -- PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", player.getName().getString(), s1, player.getId(), worldserver1.worldDataServer.getLevelName(), player.getX(), player.getY(), player.getZ()); -+ PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", entityplayer.getName().getString(), s1, entityplayer.getId(), worldserver1.worldDataServer.getLevelName(), entityplayer.getX(), entityplayer.getY(), entityplayer.getZ()); ++ // CraftBukkit - Moved from above, added world + PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", player.getName().getString(), s1, player.getId(), worldserver1.serverLevelData.getLevelName(), player.getX(), player.getY(), player.getZ()); } - public void updateEntireScoreboard(ServerScoreboard scoreboard, ServerPlayer player) { diff --git a/patches/server/0408-Load-Chunks-for-Login-Asynchronously.patch b/patches/server/0408-Load-Chunks-for-Login-Asynchronously.patch new file mode 100644 index 000000000..399eeca8a --- /dev/null +++ b/patches/server/0408-Load-Chunks-for-Login-Asynchronously.patch @@ -0,0 +1,277 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Sun, 19 Apr 2020 04:28:29 -0400 +Subject: [PATCH] Load Chunks for Login Asynchronously + + +diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java +index e4f5f564892836a2e925f419e8fcb60c70b21a47..afc9431b61f2953229765ef90005b7968fbed591 100644 +--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java ++++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java +@@ -630,7 +630,7 @@ public class ServerChunkCache extends ChunkSource { + return this.mainThreadProcessor.pollTask(); + } + +- boolean runDistanceManagerUpdates() { ++ public boolean runDistanceManagerUpdates() { // Paper - packate-private -> public + boolean flag = this.distanceManager.runAllUpdates(this.chunkMap); + boolean flag1 = this.chunkMap.promoteChunkMap(); + +diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java +index a30840b74bc2574725c42735f633630d9b471d54..d4ec913a96c5f8f9780d78f6f340d844718a5849 100644 +--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java ++++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java +@@ -177,6 +177,7 @@ public class ServerPlayer extends Player { + private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_XZ = 32; + private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10; + public ServerGamePacketListenerImpl connection; ++ public net.minecraft.network.Connection networkManager; // Paper + public final MinecraftServer server; + public final ServerPlayerGameMode gameMode; + private final PlayerAdvancements advancements; +@@ -238,6 +239,7 @@ public class ServerPlayer extends Player { + public boolean joining = true; + public boolean sentListPacket = false; + public boolean supressTrackerForLogin = false; // Paper ++ public boolean didPlayerJoinEvent = false; // Paper + public Integer clientViewDistance; + // CraftBukkit end + public PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper +diff --git a/src/main/java/net/minecraft/server/level/TicketType.java b/src/main/java/net/minecraft/server/level/TicketType.java +index be677d437d17b74c6188ce1bd5fc6fdc228fd92f..78fbb4c3e52e900956ae0811aaf934c81ee5ea48 100644 +--- a/src/main/java/net/minecraft/server/level/TicketType.java ++++ b/src/main/java/net/minecraft/server/level/TicketType.java +@@ -23,6 +23,7 @@ public class TicketType { + public static final TicketType FORCED = TicketType.create("forced", Comparator.comparingLong(ChunkPos::toLong)); + public static final TicketType LIGHT = TicketType.create("light", Comparator.comparingLong(ChunkPos::toLong)); + public static final TicketType PORTAL = TicketType.create("portal", Vec3i::compareTo, 300); ++ public static final TicketType LOGIN = create("login", Long::compareTo, 100); // Paper + public static final TicketType POST_TELEPORT = TicketType.create("post_teleport", Integer::compareTo, 5); + public static final TicketType UNKNOWN = TicketType.create("unknown", Comparator.comparingLong(ChunkPos::toLong), 1); + public static final TicketType PLUGIN = TicketType.create("plugin", (a, b) -> 0); // CraftBukkit +diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +index fcfd57fd7af655aafb330986e8f6f9cc55819165..1263e845a56e96920c71a7ef636ad3437a70c06f 100644 +--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java ++++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +@@ -221,6 +221,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser + private static final int LATENCY_CHECK_INTERVAL = 15000; + public final Connection connection; + private final MinecraftServer server; ++ public Runnable playerJoinReady; // Paper + public ServerPlayer player; + private int tickCount; + private long keepAliveTime = Util.getMillis(); +@@ -295,6 +296,15 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser + // CraftBukkit end + + public void tick() { ++ // Paper start - login async ++ Runnable playerJoinReady = this.playerJoinReady; ++ if (playerJoinReady != null) { ++ this.playerJoinReady = null; ++ playerJoinReady.run(); ++ } ++ // Don't tick if not valid (dead), otherwise we load chunks below ++ if (this.player.valid) { ++ // Paper end + this.resetPosition(); + this.player.xo = this.player.getX(); + this.player.yo = this.player.getY(); +@@ -336,7 +346,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser + this.lastVehicle = null; + this.clientVehicleIsFloating = false; + this.aboveGroundVehicleTickCount = 0; +- } ++ }} // Paper - end if (valid) + + this.server.getProfiler().push("keepAlive"); + // Paper Start - give clients a longer time to respond to pings as per pre 1.12.2 timings +diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +index 46432534fddbbf78e3bf46385b9638d2f92c951f..49308829885a473906d58fb17797127faabfcf31 100644 +--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java ++++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +@@ -88,7 +88,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener + } + // Paper end + } else if (this.state == ServerLoginPacketListenerImpl.State.DELAY_ACCEPT) { +- ServerPlayer entityplayer = this.server.getPlayerList().getPlayer(this.gameProfile.getId()); ++ ServerPlayer entityplayer = this.server.getPlayerList().getActivePlayer(this.gameProfile.getId()); // Paper + + if (entityplayer == null) { + this.state = ServerLoginPacketListenerImpl.State.READY_TO_ACCEPT; +@@ -194,7 +194,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener + } + + this.connection.send(new ClientboundGameProfilePacket(this.gameProfile)); +- ServerPlayer entityplayer = this.server.getPlayerList().getPlayer(this.gameProfile.getId()); ++ ServerPlayer entityplayer = this.server.getPlayerList().getActivePlayer(this.gameProfile.getId()); // Paper + + try { + ServerPlayer entityplayer1 = this.server.getPlayerList().processLogin(this.gameProfile, s); // CraftBukkit - add player reference +diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java +index 3a13c151066c8784fdc844e1d6310f77ff32e7f1..c4242a1602bbb02541c330bc02016f15c8644358 100644 +--- a/src/main/java/net/minecraft/server/players/PlayerList.java ++++ b/src/main/java/net/minecraft/server/players/PlayerList.java +@@ -38,6 +38,7 @@ import net.minecraft.network.protocol.Packet; + import net.minecraft.network.protocol.game.ClientboundChangeDifficultyPacket; + import net.minecraft.network.protocol.game.ClientboundChatPacket; + import net.minecraft.network.protocol.game.ClientboundCustomPayloadPacket; ++import net.minecraft.network.protocol.game.ClientboundDisconnectPacket; + import net.minecraft.network.protocol.game.ClientboundEntityEventPacket; + import net.minecraft.network.protocol.game.ClientboundGameEventPacket; + import net.minecraft.network.protocol.game.ClientboundInitializeBorderPacket; +@@ -127,11 +128,12 @@ public abstract class PlayerList { + private static final SimpleDateFormat BAN_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z"); + private final MinecraftServer server; + public final List players = new java.util.concurrent.CopyOnWriteArrayList(); // CraftBukkit - ArrayList -> CopyOnWriteArrayList: Iterator safety +- private final Map playersByUUID = Maps.newHashMap(); ++ private final Map playersByUUID = Maps.newHashMap();Map getUUIDMap() { return playersByUUID; } // Paper - OBFHELPER + private final UserBanList bans; + private final IpBanList ipBans; + private final ServerOpList ops; + private final UserWhiteList whitelist; ++ private final Map pendingPlayers = Maps.newHashMap(); // Paper + // CraftBukkit start + // private final Map o; + // private final Map p; +@@ -170,6 +172,11 @@ public abstract class PlayerList { + } + + public void placeNewPlayer(Connection connection, ServerPlayer player) { ++ ServerPlayer prev = pendingPlayers.put(player.getUUID(), player);// Paper ++ if (prev != null) { ++ disconnectPendingPlayer(prev); ++ } ++ player.networkManager = connection; // Paper + player.loginTime = System.currentTimeMillis(); // Paper + GameProfile gameprofile = player.getGameProfile(); + GameProfileCache usercache = this.server.getProfileCache(); +@@ -183,7 +190,7 @@ public abstract class PlayerList { + if (nbttagcompound != null && nbttagcompound.contains("bukkit")) { + CompoundTag bukkit = nbttagcompound.getCompound("bukkit"); + s = bukkit.contains("lastKnownName", 8) ? bukkit.getString("lastKnownName") : s; +- } ++ }String lastKnownName = s; // Paper + // CraftBukkit end + + if (nbttagcompound != null) { +@@ -257,6 +264,52 @@ public abstract class PlayerList { + player.getRecipeBook().sendInitialRecipeBook(player); + this.updateEntireScoreboard(worldserver1.getScoreboard(), player); + this.server.invalidateStatus(); ++ // Paper start - async load spawn in chunk ++ ServerLevel finalWorldserver = worldserver1; ++ int chunkX = loc.getBlockX() >> 4; ++ int chunkZ = loc.getBlockZ() >> 4; ++ final net.minecraft.world.level.ChunkPos pos = new net.minecraft.world.level.ChunkPos(chunkX, chunkZ); ++ net.minecraft.server.level.ChunkMap playerChunkMap = worldserver1.getChunkSource().chunkMap; ++ net.minecraft.server.level.DistanceManager distanceManager = playerChunkMap.distanceManager; ++ distanceManager.addTicketAtLevel(net.minecraft.server.level.TicketType.LOGIN, pos, 31, pos.toLong()); ++ worldserver1.getChunkSource().runDistanceManagerUpdates(); ++ worldserver1.getChunkSource().getChunkAtAsynchronously(chunkX, chunkZ, true, true).thenApply(chunk -> { ++ net.minecraft.server.level.ChunkHolder updatingChunk = playerChunkMap.getUpdatingChunkIfPresent(pos.toLong()); ++ if (updatingChunk != null) { ++ return updatingChunk.getEntityTickingFuture(); ++ } else { ++ return java.util.concurrent.CompletableFuture.completedFuture(chunk); ++ } ++ }).thenAccept(chunk -> { ++ playerconnection.playerJoinReady = () -> { ++ postChunkLoadJoin( ++ player, finalWorldserver, connection, playerconnection, ++ nbttagcompound, connection.getRemoteAddress().toString(), lastKnownName ++ ); ++ }; ++ }); ++ } ++ ++ public ServerPlayer getActivePlayer(UUID uuid) { ++ ServerPlayer player = this.getUUIDMap().get(uuid); ++ return player != null ? player : pendingPlayers.get(uuid); ++ } ++ ++ void disconnectPendingPlayer(ServerPlayer entityplayer) { ++ TranslatableComponent msg = new TranslatableComponent("multiplayer.disconnect.duplicate_login", new Object[0]); ++ entityplayer.networkManager.send(new ClientboundDisconnectPacket(msg), (future) -> { ++ entityplayer.networkManager.disconnect(msg); ++ entityplayer.networkManager = null; ++ }); ++ } ++ ++ private void postChunkLoadJoin(ServerPlayer player, ServerLevel worldserver1, Connection networkmanager, ServerGamePacketListenerImpl playerconnection, CompoundTag nbttagcompound, String s1, String s) { ++ pendingPlayers.remove(player.getUUID(), player); ++ if (!networkmanager.isConnected()) { ++ return; ++ } ++ player.didPlayerJoinEvent = true; ++ // Paper end + TranslatableComponent chatmessage; + + if (player.getGameProfile().getName().equalsIgnoreCase(s)) { +@@ -495,6 +548,7 @@ public abstract class PlayerList { + + protected void save(ServerPlayer player) { + if (!player.getBukkitEntity().isPersistent()) return; // CraftBukkit ++ if (!player.didPlayerJoinEvent) return; // Paper - If we never fired PJE, we disconnected during login. Data has not changed, and additionally, our saved vehicle is not loaded! If we save now, we will lose our vehicle (CraftBukkit bug) + this.playerIo.save(player); + ServerStatsCounter serverstatisticmanager = (ServerStatsCounter) player.getStats(); // CraftBukkit + +@@ -522,7 +576,7 @@ public abstract class PlayerList { + } + + PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(this.cserver.getPlayer(entityplayer), net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, com.destroystokyo.paper.PaperConfig.useDisplayNameInQuit ? entityplayer.getBukkitEntity().displayName() : net.kyori.adventure.text.Component.text(entityplayer.getScoreboardName()))); +- this.cserver.getPluginManager().callEvent(playerQuitEvent); ++ if (entityplayer.didPlayerJoinEvent) this.cserver.getPluginManager().callEvent(playerQuitEvent); // Paper - if we disconnected before join ever fired, don't fire quit + entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage()); + + if (server.isSameThread()) entityplayer.doTick(); // SPIGOT-924 // Paper - don't tick during emergency shutdowns (Watchdog) +@@ -567,6 +621,13 @@ public abstract class PlayerList { + // this.p.remove(uuid); + // CraftBukkit end + } ++ // Paper start ++ entityplayer1 = pendingPlayers.get(uuid); ++ if (entityplayer1 == entityplayer) { ++ pendingPlayers.remove(uuid); ++ } ++ entityplayer.networkManager = null; ++ // Paper end + + // CraftBukkit start + // this.sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, new EntityPlayer[]{entityplayer})); +@@ -584,7 +645,7 @@ public abstract class PlayerList { + this.cserver.getScoreboardManager().removePlayer(entityplayer.getBukkitEntity()); + // CraftBukkit end + +- return playerQuitEvent.quitMessage(); // Paper - Adventure ++ return entityplayer.didPlayerJoinEvent ? playerQuitEvent.quitMessage() : null; // CraftBukkit // Paper - Adventure // Paper - don't print quit if we never printed join + } + + // CraftBukkit start - Whole method, SocketAddress to LoginListener, added hostname to signature, return EntityPlayer +@@ -603,6 +664,13 @@ public abstract class PlayerList { + list.add(entityplayer); + } + } ++ // Paper start - check pending players too ++ entityplayer = pendingPlayers.get(uuid); ++ if (entityplayer != null) { ++ this.pendingPlayers.remove(uuid); ++ disconnectPendingPlayer(entityplayer); ++ } ++ // Paper end + + Iterator iterator = list.iterator(); + +diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java +index 85c0656ee8c91cab1e269daea631977c4284295f..ac5f0bf573cbb5aa19dd3326f412010286de4378 100644 +--- a/src/main/java/net/minecraft/world/entity/Entity.java ++++ b/src/main/java/net/minecraft/world/entity/Entity.java +@@ -1490,7 +1490,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n + this.yo = y; + this.zo = d4; + this.setPos(d3, y, d4); +- this.level.getChunk((int) Math.floor(this.getX()) >> 4, (int) Math.floor(this.getZ()) >> 4); // CraftBukkit ++ if (valid) this.level.getChunk((int) Math.floor(this.getX()) >> 4, (int) Math.floor(this.getZ()) >> 4); // CraftBukkit // Paper + } + + public void moveTo(Vec3 pos) { diff --git a/patches/server-remapped/0454-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch b/patches/server/0409-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch similarity index 79% rename from patches/server-remapped/0454-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch rename to patches/server/0409-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch index eeaa3a49f..ed5d792be 100644 --- a/patches/server-remapped/0454-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch +++ b/patches/server/0409-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch @@ -7,10 +7,10 @@ The code following this has better support for null worlds to move them back to the world spawn. diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 9f0371282f5829d26dc9618c3d466bccaa4cd3af..34226102c50a4353c42e68917d41c44d251e602f 100644 +index ac5f0bf573cbb5aa19dd3326f412010286de4378..1ab073aaacbf6af35f97a7d3b0d8ae078335f9a6 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -1808,9 +1808,11 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s +@@ -1979,9 +1979,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n bworld = server.getWorld(worldName); } @@ -23,5 +23,5 @@ index 9f0371282f5829d26dc9618c3d466bccaa4cd3af..34226102c50a4353c42e68917d41c44d +// } + // Paper end - Move player to spawn point if spawn in unloaded world - setLevel(bworld == null ? null : ((CraftWorld) bworld).getHandle()); + ((ServerPlayer) this).setLevel(bworld == null ? null : ((CraftWorld) bworld).getHandle()); } diff --git a/patches/server-remapped/0455-Add-PlayerAttackEntityCooldownResetEvent.patch b/patches/server/0410-Add-PlayerAttackEntityCooldownResetEvent.patch similarity index 92% rename from patches/server-remapped/0455-Add-PlayerAttackEntityCooldownResetEvent.patch rename to patches/server/0410-Add-PlayerAttackEntityCooldownResetEvent.patch index f1eab97e3..8ef5ac518 100644 --- a/patches/server-remapped/0455-Add-PlayerAttackEntityCooldownResetEvent.patch +++ b/patches/server/0410-Add-PlayerAttackEntityCooldownResetEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add PlayerAttackEntityCooldownResetEvent diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 46b962183e2e27ed93054ad9fb6d8ecbf70bc5f9..cec1e6105b8c2ac3d1482c00482d53d6be0d38d1 100644 +index 0fd79c399e723b5a9db04c8f2fe7b6ec66c0cf44..3a83cbe8fb1a5bfc7e7b699686b92561bf0cdba0 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -1928,7 +1928,16 @@ public abstract class LivingEntity extends Entity { +@@ -2033,7 +2033,16 @@ public abstract class LivingEntity extends Entity { EntityDamageEvent event = CraftEventFactory.handleLivingEntityDamageEvent(this, damagesource, originalDamage, hardHatModifier, blockingModifier, armorModifier, resistanceModifier, magicModifier, absorptionModifier, hardHat, blocking, armor, resistance, magic, absorption); if (damagesource.getEntity() instanceof net.minecraft.world.entity.player.Player) { diff --git a/patches/server-remapped/0456-Allow-multiple-callbacks-to-schedule-for-Callback-Ex.patch b/patches/server/0411-Allow-multiple-callbacks-to-schedule-for-Callback-Ex.patch similarity index 63% rename from patches/server-remapped/0456-Allow-multiple-callbacks-to-schedule-for-Callback-Ex.patch rename to patches/server/0411-Allow-multiple-callbacks-to-schedule-for-Callback-Ex.patch index 025b5a9d8..1ad36331e 100644 --- a/patches/server-remapped/0456-Allow-multiple-callbacks-to-schedule-for-Callback-Ex.patch +++ b/patches/server/0411-Allow-multiple-callbacks-to-schedule-for-Callback-Ex.patch @@ -14,45 +14,35 @@ Use an ArrayDeque to store this Queue We make sure to also implement a pattern that is recursion safe too. diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 97a582614ad28f9fa864ae9be4860658e5979214..6c7af93cead523830d32b007cc69b313e59abef1 100644 +index 2cb807f7095648948527b5b9151770193970cc00..7fa35cba408d036e649e6d63bace88e6047c02b4 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -160,24 +160,32 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -172,15 +172,27 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider public final CallbackExecutor callbackExecutor = new CallbackExecutor(); public static final class CallbackExecutor implements java.util.concurrent.Executor, Runnable { -- private Runnable queued; +- private final java.util.Queue queue = new java.util.ArrayDeque<>(); + // Paper start - replace impl with recursive safe multi entry queue + // it's possible to schedule multiple tasks currently, so it's vital we change this impl + // If we recurse into the executor again, we will append to another queue, ensuring task order consistency -+ private java.util.ArrayDeque queued = new java.util.ArrayDeque<>(); ++ private java.util.Queue queue = new java.util.ArrayDeque<>(); // Paper - remove final @Override public void execute(Runnable runnable) { -- if (queued != null) { -- throw new IllegalStateException("Already queued"); -+ if (queued == null) { -+ queued = new java.util.ArrayDeque<>(); - } -- queued = runnable; -+ queued.add(runnable); ++ if (this.queue == null) { ++ this.queue = new java.util.ArrayDeque<>(); ++ } + this.queue.add(runnable); } @Override public void run() { -- Runnable task = queued; -+ if (queued == null) { ++ if (this.queue == null) { + return; + } -+ java.util.ArrayDeque queue = queued; - queued = null; -- if (task != null) { -+ Runnable task; -+ while ((task = queue.pollFirst()) != null) { ++ java.util.Queue queue = this.queue; ++ this.queue = null; ++ // Paper end + Runnable task; + while ((task = this.queue.poll()) != null) { task.run(); - } - } -+ // Paper end - }; - // CraftBukkit end - diff --git a/patches/server-remapped/0457-Don-t-fire-BlockFade-on-worldgen-threads.patch b/patches/server/0412-Don-t-fire-BlockFade-on-worldgen-threads.patch similarity index 80% rename from patches/server-remapped/0457-Don-t-fire-BlockFade-on-worldgen-threads.patch rename to patches/server/0412-Don-t-fire-BlockFade-on-worldgen-threads.patch index 8997a0897..fe13efc94 100644 --- a/patches/server-remapped/0457-Don-t-fire-BlockFade-on-worldgen-threads.patch +++ b/patches/server/0412-Don-t-fire-BlockFade-on-worldgen-threads.patch @@ -6,18 +6,18 @@ Subject: [PATCH] Don't fire BlockFade on worldgen threads Caused a deadlock diff --git a/src/main/java/net/minecraft/world/level/block/FireBlock.java b/src/main/java/net/minecraft/world/level/block/FireBlock.java -index 31b6c1333c7d0af28385e804e94348cef398748b..ac63c5bef5b35b158e57835d765bbdd15fc60664 100644 +index ad0b485dbc77717f16191d6950a2e91faaede94a..c86bf175853197dceaa91a2287ef51de87b9d5f9 100644 --- a/src/main/java/net/minecraft/world/level/block/FireBlock.java +++ b/src/main/java/net/minecraft/world/level/block/FireBlock.java -@@ -93,6 +93,7 @@ public class FireBlock extends BaseFireBlock { +@@ -100,6 +100,7 @@ public class FireBlock extends BaseFireBlock { @Override - public BlockState updateShape(BlockState state, Direction direction, BlockState newState, LevelAccessor world, BlockPos pos, BlockPos posFrom) { + public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { // CraftBukkit start + if (!(world instanceof ServerLevel)) return this.canSurvive(state, world, pos) ? (BlockState) this.getStateWithAge(world, pos, (Integer) state.getValue(FireBlock.AGE)) : Blocks.AIR.defaultBlockState(); // Paper - don't fire events in world generation if (!this.canSurvive(state, world, pos)) { // Suppress during worldgen if (!(world instanceof Level)) { -@@ -108,7 +109,7 @@ public class FireBlock extends BaseFireBlock { +@@ -115,7 +116,7 @@ public class FireBlock extends BaseFireBlock { return blockState.getHandle(); } } diff --git a/patches/server-remapped/0458-Add-phantom-creative-and-insomniac-controls.patch b/patches/server/0413-Add-phantom-creative-and-insomniac-controls.patch similarity index 68% rename from patches/server-remapped/0458-Add-phantom-creative-and-insomniac-controls.patch rename to patches/server/0413-Add-phantom-creative-and-insomniac-controls.patch index 9a052de40..6b22ec66c 100644 --- a/patches/server-remapped/0458-Add-phantom-creative-and-insomniac-controls.patch +++ b/patches/server/0413-Add-phantom-creative-and-insomniac-controls.patch @@ -5,53 +5,40 @@ Subject: [PATCH] Add phantom creative and insomniac controls diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index cd248eb6be663e8be33f2c3c6b06b77b6d5753a4..46ac6d91422423f1e03b86d3efa3241f2599000d 100644 +index 9664786d471b949880030f5c6271bf9c12529326..45058c715152e3ffa5ec1c79a472e32d63d69e02 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -@@ -625,4 +625,11 @@ public class PaperWorldConfig { - private void lightQueueSize() { +@@ -472,6 +472,13 @@ public class PaperWorldConfig { lightQueueSize = getInt("light-queue-size", lightQueueSize); } -+ + + public boolean phantomIgnoreCreative = true; + public boolean phantomOnlyAttackInsomniacs = true; + private void phantomSettings() { + phantomIgnoreCreative = getBoolean("phantoms-do-not-spawn-on-creative-players", phantomIgnoreCreative); + phantomOnlyAttackInsomniacs = getBoolean("phantoms-only-attack-insomniacs", phantomOnlyAttackInsomniacs); + } - } ++ + public int noTickViewDistance; + private void viewDistance() { + this.noTickViewDistance = this.getInt("viewdistances.no-tick-view-distance", -1); diff --git a/src/main/java/net/minecraft/world/entity/EntitySelector.java b/src/main/java/net/minecraft/world/entity/EntitySelector.java -index e7facd849e3511c64b4ae44b34382f4a4985f2a4..8ce62148ebaeac9988e7c9d4b2f7ee57f58d883e 100644 +index d17b75ad13bbc8a38cdc2f2d77ee5d88438cec31..8fb89326395a7e70982c0d757b506565e98b12a4 100644 --- a/src/main/java/net/minecraft/world/entity/EntitySelector.java +++ b/src/main/java/net/minecraft/world/entity/EntitySelector.java -@@ -3,6 +3,9 @@ package net.minecraft.world.entity; - import com.google.common.base.Predicates; - import java.util.function.Predicate; - import javax.annotation.Nullable; -+import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.stats.Stats; -+import net.minecraft.util.Mth; - import net.minecraft.world.Container; - import net.minecraft.world.Difficulty; - import net.minecraft.world.entity.player.Player; -@@ -31,10 +34,11 @@ public final class EntitySelector { +@@ -26,6 +26,7 @@ public final class EntitySelector { public static final Predicate NO_SPECTATORS = (entity) -> { return !entity.isSpectator(); }; -+ public static Predicate isInsomniac = (player) -> Mth.clamp(((ServerPlayer) player).getStats().getValue(Stats.CUSTOM.get(Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= 72000; // Paper ++ public static Predicate isInsomniac = (player) -> net.minecraft.util.Mth.clamp(((net.minecraft.server.level.ServerPlayer) player).getStats().getValue(net.minecraft.stats.Stats.CUSTOM.get(net.minecraft.stats.Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= 72000; // Paper + private EntitySelector() {} // Paper start - public static final Predicate affectsSpawning = (entity) -> { -- return !entity.isSpectator() && entity.isAlive() && (entity instanceof EntityPlayer) && ((EntityPlayer) entity).affectsSpawning; -+ return !entity.isSpectator() && entity.isAlive() && (entity instanceof ServerPlayer) && ((ServerPlayer) entity).affectsSpawning; - }; - // Paper end - diff --git a/src/main/java/net/minecraft/world/entity/monster/Phantom.java b/src/main/java/net/minecraft/world/entity/monster/Phantom.java -index e37137a2890330b92e05d6f76c46ffc99a527803..a40c23e824652cff59633b7c314e27ec9a515c07 100644 +index 2ddb7b4c0a75c6f41910c84c8b9341f56fcb1116..941f86b04fedaf1e3f5d04c9aa8c1cd74da9b7a2 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java +++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java -@@ -262,6 +262,7 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -547,6 +547,7 @@ public class Phantom extends FlyingMob implements Enemy { Player entityhuman = (Player) iterator.next(); if (Phantom.this.canAttack((LivingEntity) entityhuman, TargetingConditions.DEFAULT)) { diff --git a/patches/server-remapped/0459-Fix-numerous-item-duplication-issues-and-teleport-is.patch b/patches/server/0414-Fix-numerous-item-duplication-issues-and-teleport-is.patch similarity index 85% rename from patches/server-remapped/0459-Fix-numerous-item-duplication-issues-and-teleport-is.patch rename to patches/server/0414-Fix-numerous-item-duplication-issues-and-teleport-is.patch index 9e378d1d3..b1c5df36e 100644 --- a/patches/server-remapped/0459-Fix-numerous-item-duplication-issues-and-teleport-is.patch +++ b/patches/server/0414-Fix-numerous-item-duplication-issues-and-teleport-is.patch @@ -16,10 +16,10 @@ So even if something NEW comes up, it would be impossible to drop the same item twice because the source was destroyed. diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 34226102c50a4353c42e68917d41c44d251e602f..2b48c4a2b512c42bed2c767db90a28898c74286a 100644 +index 1ab073aaacbf6af35f97a7d3b0d8ae078335f9a6..9897a0ac66dd788b0b22a88b20ca86a386e397e4 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -1973,11 +1973,12 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s +@@ -2125,11 +2125,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n } else { // CraftBukkit start - Capture drops for death event if (this instanceof net.minecraft.world.entity.LivingEntity && !((net.minecraft.world.entity.LivingEntity) this).forceDrops) { @@ -34,7 +34,7 @@ index 34226102c50a4353c42e68917d41c44d251e602f..2b48c4a2b512c42bed2c767db90a2889 entityitem.setDefaultPickUpDelay(); // CraftBukkit start -@@ -2625,6 +2626,12 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s +@@ -2873,6 +2874,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n @Nullable public Entity teleportTo(ServerLevel worldserver, BlockPos location) { // CraftBukkit end @@ -44,10 +44,10 @@ index 34226102c50a4353c42e68917d41c44d251e602f..2b48c4a2b512c42bed2c767db90a2889 + return null; + } + // Paper end - if (this.level instanceof ServerLevel && !this.removed) { + if (this.level instanceof ServerLevel && !this.isRemoved()) { this.level.getProfiler().push("changeDimension"); // CraftBukkit start -@@ -2645,6 +2652,11 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s +@@ -2893,6 +2900,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n // CraftBukkit end this.level.getProfiler().popPush("reloading"); @@ -59,7 +59,7 @@ index 34226102c50a4353c42e68917d41c44d251e602f..2b48c4a2b512c42bed2c767db90a2889 Entity entity = this.getType().create((Level) worldserver); if (entity != null) { -@@ -2658,10 +2670,6 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s +@@ -2906,10 +2918,6 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n // CraftBukkit start - Forward the CraftEntity to the new entity this.getBukkitEntity().setHandle(entity); entity.bukkitEntity = this.getBukkitEntity(); @@ -70,7 +70,7 @@ index 34226102c50a4353c42e68917d41c44d251e602f..2b48c4a2b512c42bed2c767db90a2889 // CraftBukkit end } -@@ -2786,7 +2794,7 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s +@@ -3034,7 +3042,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n } public boolean canChangeDimensions() { @@ -80,10 +80,10 @@ index 34226102c50a4353c42e68917d41c44d251e602f..2b48c4a2b512c42bed2c767db90a2889 public float getBlockExplosionResistance(Explosion explosion, BlockGetter world, BlockPos pos, BlockState blockState, FluidState fluidState, float max) { diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -index 33d51852ed6fe3f5adcdecf8f405a23689f4265a..5714aa450ac09788bcf1c2790d4f1581c9a7c28b 100644 +index cb9969d768b13863722aad3dc5daad3c10bb264a..5bfec185e15a54ee5fe6eab1aa59d1963d046262 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -@@ -598,7 +598,7 @@ public class ArmorStand extends LivingEntity { +@@ -611,7 +611,7 @@ public class ArmorStand extends LivingEntity { for (i = 0; i < this.handItems.size(); ++i) { itemstack = (ItemStack) this.handItems.get(i); if (!itemstack.isEmpty()) { @@ -92,7 +92,7 @@ index 33d51852ed6fe3f5adcdecf8f405a23689f4265a..5714aa450ac09788bcf1c2790d4f1581 this.handItems.set(i, ItemStack.EMPTY); } } -@@ -606,7 +606,7 @@ public class ArmorStand extends LivingEntity { +@@ -619,7 +619,7 @@ public class ArmorStand extends LivingEntity { for (i = 0; i < this.armorItems.size(); ++i) { itemstack = (ItemStack) this.armorItems.get(i); if (!itemstack.isEmpty()) { @@ -102,10 +102,10 @@ index 33d51852ed6fe3f5adcdecf8f405a23689f4265a..5714aa450ac09788bcf1c2790d4f1581 } } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 7d9a3b65b2d6b294d3a11414289e64fac88665f0..87fe7f4f5ed70bf1b3dc1e2a392ba42a1f8f568b 100644 +index 98bec353d6dbd85c7b329f75e09f4d0bfcfdaa6c..7d43439a13bd109399691ddec60ee99c818db198 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -815,7 +815,8 @@ public class CraftEventFactory { +@@ -807,7 +807,8 @@ public class CraftEventFactory { for (org.bukkit.inventory.ItemStack stack : event.getDrops()) { if (stack == null || stack.getType() == Material.AIR || stack.getAmount() == 0) continue; diff --git a/patches/server-remapped/0460-Implement-Brigadier-Mojang-API.patch b/patches/server/0415-Implement-Brigadier-Mojang-API.patch similarity index 86% rename from patches/server-remapped/0460-Implement-Brigadier-Mojang-API.patch rename to patches/server/0415-Implement-Brigadier-Mojang-API.patch index 5504aee90..c73a8699b 100644 --- a/patches/server-remapped/0460-Implement-Brigadier-Mojang-API.patch +++ b/patches/server/0415-Implement-Brigadier-Mojang-API.patch @@ -9,8 +9,20 @@ Adds AsyncPlayerSendCommandsEvent Adds CommandRegisteredEvent - Allows manipulating the CommandNode to add more children/metadata for the client +diff --git a/build.gradle.kts b/build.gradle.kts +index f0256fe4aea16c9e0d6f5eee360eeec36cfdeebd..2543a4cf2bb58c2265cfc427c427b683d2ff70ca 100644 +--- a/build.gradle.kts ++++ b/build.gradle.kts +@@ -21,6 +21,7 @@ repositories { + + dependencies { + implementation(project(":Paper-API")) ++ implementation(project(":Paper-MojangAPI")) + // Paper start + implementation("org.jline:jline-terminal-jansi:3.12.1") + implementation("net.minecrell:terminalconsoleappender:1.2.0") diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java -index f74765f31bc7272724ee7fac0cc5a8c852550006..e1f4ffaa36bfffb7741c74b7a094e26a03a9a1e6 100644 +index 60b503dd85706bd2593a5e9d3314540ff1012652..42d97bc67c8f4e5b65a81159179c43dc6edc804c 100644 --- a/src/main/java/net/minecraft/commands/CommandSourceStack.java +++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java @@ -37,7 +37,7 @@ import net.minecraft.world.phys.Vec2; @@ -22,7 +34,7 @@ index f74765f31bc7272724ee7fac0cc5a8c852550006..e1f4ffaa36bfffb7741c74b7a094e26a public static final SimpleCommandExceptionType ERROR_NOT_PLAYER = new SimpleCommandExceptionType(new TranslatableComponent("permissions.requires.player")); public static final SimpleCommandExceptionType ERROR_NOT_ENTITY = new SimpleCommandExceptionType(new TranslatableComponent("permissions.requires.entity")); -@@ -149,6 +149,25 @@ public class CommandSourceStack implements SharedSuggestionProvider { +@@ -153,6 +153,25 @@ public class CommandSourceStack implements SharedSuggestionProvider { return this.textName; } @@ -49,10 +61,10 @@ index f74765f31bc7272724ee7fac0cc5a8c852550006..e1f4ffaa36bfffb7741c74b7a094e26a public boolean hasPermission(int level) { // CraftBukkit start diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java -index 8154d9327c5411bbfea3bfa4d99d57feab764664..c63033e3eb50423a7c32acfc0e705623cc4bec68 100644 +index 13e358e0eac3bfd426d924b6f745e001df76c64a..7156dea53be828acd01734fa1f9f7b9accf30ff6 100644 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java -@@ -355,6 +355,7 @@ public class Commands { +@@ -362,6 +362,7 @@ public class Commands { bukkit.add(node.getName()); } // Paper start - Async command map building @@ -60,7 +72,7 @@ index 8154d9327c5411bbfea3bfa4d99d57feab764664..c63033e3eb50423a7c32acfc0e705623 MinecraftServer.getServer().execute(() -> { runSync(entityplayer, bukkit, rootcommandnode); }); -@@ -362,6 +363,7 @@ public class Commands { +@@ -369,6 +370,7 @@ public class Commands { private void runSync(ServerPlayer entityplayer, Collection bukkit, RootCommandNode rootcommandnode) { // Paper end - Async command map building @@ -69,17 +81,17 @@ index 8154d9327c5411bbfea3bfa4d99d57feab764664..c63033e3eb50423a7c32acfc0e705623 event.getPlayer().getServer().getPluginManager().callEvent(event); diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 1bed6e69bf3cc1ab9b0c1259de4f643bf58371aa..5f12987b93f1578624626c4e911d1757dee3d45f 100644 +index 1263e845a56e96920c71a7ef636ad3437a70c06f..fbb33cfa62723ac1fd6f426969e747e49abc8ea6 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -768,8 +768,12 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener { +@@ -760,8 +760,12 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser ParseResults parseresults = this.server.getCommands().getDispatcher().parse(stringreader, this.player.createCommandSourceStack()); this.server.getCommands().getDispatcher().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> { - if (suggestions.isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [] from showing for plugins with nothing more to offer - this.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), suggestions)); + // Paper start -+ com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getPlayer(), suggestions, buffer); ++ com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getCraftPlayer(), suggestions, buffer); + suggestEvent.setCancelled(suggestions.isEmpty()); + if (!suggestEvent.callEvent()) return; + this.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), (com.mojang.brigadier.suggestion.Suggestions) suggestEvent.getSuggestions())); // CraftBukkit - decompile error // Paper @@ -87,13 +99,13 @@ index 1bed6e69bf3cc1ab9b0c1259de4f643bf58371aa..5f12987b93f1578624626c4e911d1757 }); }); } -@@ -778,7 +782,11 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener { +@@ -770,7 +774,11 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser builder = builder.createOffset(builder.getInput().lastIndexOf(' ') + 1); completions.forEach(builder::suggest); - player.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), builder.buildFuture().join())); + com.mojang.brigadier.suggestion.Suggestions suggestions = builder.buildFuture().join(); -+ com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getPlayer(), suggestions, buffer); ++ com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getCraftPlayer(), suggestions, buffer); + suggestEvent.setCancelled(suggestions.isEmpty()); + if (!suggestEvent.callEvent()) return; + this.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), suggestEvent.getSuggestions())); @@ -101,7 +113,7 @@ index 1bed6e69bf3cc1ab9b0c1259de4f643bf58371aa..5f12987b93f1578624626c4e911d1757 // Paper end - async tab completion } diff --git a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java -index f9a245503c8982d1756503a6179f3715d919d910..b17002abdb43e74da4eb61e65e45c5e0e1dc0f95 100644 +index 21971d52fa8ed92c946c519ba93a39aceae10f5f..0bba36d18d56a4dc2d6c6fb7969e5e6f0e1da404 100644 --- a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java +++ b/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java @@ -17,7 +17,7 @@ import net.minecraft.commands.CommandSourceStack; diff --git a/patches/server-remapped/0461-Villager-Restocks-API.patch b/patches/server/0416-Villager-Restocks-API.patch similarity index 60% rename from patches/server-remapped/0461-Villager-Restocks-API.patch rename to patches/server/0416-Villager-Restocks-API.patch index 49b6ff50f..3f24c8fdf 100644 --- a/patches/server-remapped/0461-Villager-Restocks-API.patch +++ b/patches/server/0416-Villager-Restocks-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Villager Restocks API 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 4aa34320ef7d6c62ccb17734bfa61d406190b919..a83a7d37f3d769535161fda46fca6f71dcc4d515 100644 +index a35ce224b11b44567814207c3821d0cd4cdd9ec1..e99cdbb1d050288b5f1177737b242c331a989471 100644 --- a/src/main/java/net/minecraft/world/entity/npc/Villager.java +++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java -@@ -112,7 +112,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -127,7 +127,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler private long lastGossipDecayTime; private int villagerXp; private long lastRestockGameTime; @@ -16,13 +16,13 @@ index 4aa34320ef7d6c62ccb17734bfa61d406190b919..a83a7d37f3d769535161fda46fca6f71 + private int numberOfRestocksToday; public int getRestocksToday(){ return this.numberOfRestocksToday; } public void setRestocksToday(int restocksToday){ this.numberOfRestocksToday = restocksToday; } // Paper OBFHELPER private long lastRestockCheckDayTime; private boolean assignProfessionWhenSpawned; - private static final ImmutableList> MEMORY_TYPES = ImmutableList.of(MemoryModuleType.HOME, MemoryModuleType.JOB_SITE, MemoryModuleType.POTENTIAL_JOB_SITE, MemoryModuleType.MEETING_POINT, MemoryModuleType.MOBS, MemoryModuleType.VISIBLE_MOBS, MemoryModuleType.VISIBLE_VILLAGER_BABIES, MemoryModuleType.NEAREST_PLAYERS, MemoryModuleType.NEAREST_VISIBLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_TARGETABLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM, MemoryModuleType.WALK_TARGET, new MemoryModuleType[]{MemoryModuleType.LOOK_TARGET, MemoryModuleType.INTERACTION_TARGET, MemoryModuleType.BREED_TARGET, MemoryModuleType.PATH, MemoryModuleType.DOORS_TO_CLOSE, MemoryModuleType.NEAREST_BED, MemoryModuleType.HURT_BY, MemoryModuleType.HURT_BY_ENTITY, MemoryModuleType.NEAREST_HOSTILE, MemoryModuleType.SECONDARY_JOB_SITE, MemoryModuleType.HIDING_PLACE, MemoryModuleType.HEARD_BELL_TIME, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.LAST_SLEPT, MemoryModuleType.LAST_WOKEN, MemoryModuleType.LAST_WORKED_AT_POI, MemoryModuleType.GOLEM_DETECTED_RECENTLY}); + private static final ImmutableList> MEMORY_TYPES = ImmutableList.of(MemoryModuleType.HOME, MemoryModuleType.JOB_SITE, MemoryModuleType.POTENTIAL_JOB_SITE, MemoryModuleType.MEETING_POINT, MemoryModuleType.NEAREST_LIVING_ENTITIES, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.VISIBLE_VILLAGER_BABIES, MemoryModuleType.NEAREST_PLAYERS, MemoryModuleType.NEAREST_VISIBLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM, MemoryModuleType.WALK_TARGET, new MemoryModuleType[]{MemoryModuleType.LOOK_TARGET, MemoryModuleType.INTERACTION_TARGET, MemoryModuleType.BREED_TARGET, MemoryModuleType.PATH, MemoryModuleType.DOORS_TO_CLOSE, MemoryModuleType.NEAREST_BED, MemoryModuleType.HURT_BY, MemoryModuleType.HURT_BY_ENTITY, MemoryModuleType.NEAREST_HOSTILE, MemoryModuleType.SECONDARY_JOB_SITE, MemoryModuleType.HIDING_PLACE, MemoryModuleType.HEARD_BELL_TIME, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.LAST_SLEPT, MemoryModuleType.LAST_WOKEN, MemoryModuleType.LAST_WORKED_AT_POI, MemoryModuleType.GOLEM_DETECTED_RECENTLY}); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java -index 5a21e9447c3e0225b07144eec83c277dd101bfd5..d0b933cfd02b237bfe85011831dab6e8e966496e 100644 +index 40815c2500a1b4946c502b8ae7f80c4e93e556ae..115f107ac100524ef0fcf8de0fc528d164c845f7 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java @@ -83,6 +83,18 @@ public class CraftVillager extends CraftAbstractVillager implements Villager { - getHandle().setVillagerXp(experience); + this.getHandle().setVillagerXp(experience); } + // Paper start diff --git a/patches/server-remapped/0462-Validate-PickItem-Packet-and-kick-for-invalid.patch b/patches/server/0417-Validate-PickItem-Packet-and-kick-for-invalid.patch similarity index 65% rename from patches/server-remapped/0462-Validate-PickItem-Packet-and-kick-for-invalid.patch rename to patches/server/0417-Validate-PickItem-Packet-and-kick-for-invalid.patch index 34909e54c..348bbe236 100644 --- a/patches/server-remapped/0462-Validate-PickItem-Packet-and-kick-for-invalid.patch +++ b/patches/server/0417-Validate-PickItem-Packet-and-kick-for-invalid.patch @@ -5,22 +5,22 @@ Subject: [PATCH] Validate PickItem Packet and kick for invalid diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 5f12987b93f1578624626c4e911d1757dee3d45f..3f416479e23c60ec5b4b779cce9ab62c74865ac8 100644 +index fbb33cfa62723ac1fd6f426969e747e49abc8ea6..b5325f19458467b307db629a00359af41004124a 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -881,7 +881,14 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener { +@@ -877,7 +877,14 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser @Override public void handlePickItem(ServerboundPickItemPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.getLevel()); -- this.player.inventory.pickSlot(packet.getSlot()); +- this.player.getInventory().pickSlot(packet.getSlot()); + // Paper start - validate pick item position -+ if (!(packet.getSlot() >= 0 && packet.getSlot() < this.player.inventory.items.size())) { ++ if (!(packet.getSlot() >= 0 && packet.getSlot() < this.player.getInventory().items.size())) { + ServerGamePacketListenerImpl.LOGGER.warn("{} tried to set an invalid carried item", this.player.getName().getString()); + this.disconnect("Invalid hotbar selection (Hacking?)"); + return; + } -+ this.player.inventory.pickSlot(packet.getSlot()); // Paper - Diff above if changed ++ this.player.getInventory().pickSlot(packet.getSlot()); // Paper - Diff above if changed + // Paper end - this.player.connection.send(new ClientboundContainerSetSlotPacket(-2, this.player.inventory.selected, this.player.inventory.getItem(this.player.inventory.selected))); - this.player.connection.send(new ClientboundContainerSetSlotPacket(-2, packet.getSlot(), this.player.inventory.getItem(packet.getSlot()))); - this.player.connection.send(new ClientboundSetCarriedItemPacket(this.player.inventory.selected)); + this.player.connection.send(new ClientboundContainerSetSlotPacket(-2, this.player.getInventory().selected, this.player.getInventory().getItem(this.player.getInventory().selected))); + this.player.connection.send(new ClientboundContainerSetSlotPacket(-2, packet.getSlot(), this.player.getInventory().getItem(packet.getSlot()))); + this.player.connection.send(new ClientboundSetCarriedItemPacket(this.player.getInventory().selected)); diff --git a/patches/server-remapped/0463-Expose-game-version.patch b/patches/server/0418-Expose-game-version.patch similarity index 78% rename from patches/server-remapped/0463-Expose-game-version.patch rename to patches/server/0418-Expose-game-version.patch index 9e0cf63bd..9c79c20af 100644 --- a/patches/server-remapped/0463-Expose-game-version.patch +++ b/patches/server/0418-Expose-game-version.patch @@ -5,11 +5,11 @@ Subject: [PATCH] Expose game version diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 43c37e660a8a7f9d326ad38e66f9aa7c53c7b87c..1bfe96443877e460d22513d59ebc3b5988e8eb43 100644 +index 4c0b94a56fab161fca92b594f55e1c846524d5e8..479b4eb8efeeca432bcb21925db18d5c0750f001 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -514,6 +514,13 @@ public final class CraftServer implements Server { - return bukkitVersion; +@@ -517,6 +517,13 @@ public final class CraftServer implements Server { + return this.bukkitVersion; } + // Paper start - expose game version diff --git a/patches/server/0419-Optimize-Voxel-Shape-Merging.patch b/patches/server/0419-Optimize-Voxel-Shape-Merging.patch new file mode 100644 index 000000000..4227b67cd --- /dev/null +++ b/patches/server/0419-Optimize-Voxel-Shape-Merging.patch @@ -0,0 +1,121 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Sun, 3 May 2020 22:35:09 -0400 +Subject: [PATCH] Optimize Voxel Shape Merging + +This method shows up as super hot in profiler, and also a high "self" time. + +Upon analyzing, it appears most usages of this method fall down to the final +else statement of the nasty ternary. + +Upon even further analyzation, it appears then the majority of those have a +consistent list 1.... One with Infinity head and Tails. + +First optimization is to detect these infinite states and immediately return that +VoxelShapeMergerList so we can avoid testing the rest for most cases. + +Break the method into 2 to help the JVM promote inlining of this fast path. + +Then it was also noticed that VoxelShapeMergerList constructor is also a hotspot +with a high self time... + +Well, knowing that in most cases our list 1 is actualy the same value, it allows +us to know that with an infinite list1, the result on the merger is essentially +list2 as the final values. + +This let us analyze the 2 potential states (Infinite with 2 sources or 4 sources) +and compute a deterministic result for the MergerList values. + +Additionally, this lets us avoid even allocating new objects for this too, further +reducing memory usage. + +diff --git a/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java b/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java +index 9e0afab2329e560c4b2512548dd4b02dd1a2e69f..06662dbff8180751a8684841aa35f709007078ae 100644 +--- a/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java ++++ b/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java +@@ -10,12 +10,33 @@ public class IndirectMerger implements IndexMerger { + private final int[] firstIndices; + private final int[] secondIndices; + private final int resultLength; ++ // Paper start ++ private static final int[] INFINITE_B_1 = new int[]{1, 1}; ++ private static final int[] INFINITE_B_0 = new int[]{0, 0}; ++ private static final int[] INFINITE_C = new int[]{0, 1}; ++ // Paper end + + public IndirectMerger(DoubleList first, DoubleList second, boolean includeFirstOnly, boolean includeSecondOnly) { + double d = Double.NaN; + int i = first.size(); + int j = second.size(); + int k = i + j; ++ // Paper start - optimize common path of infinity doublelist ++ int size = first.size(); ++ double tail = first.getDouble(size - 1); ++ double head = first.getDouble(0); ++ if (head == Double.NEGATIVE_INFINITY && tail == Double.POSITIVE_INFINITY && !includeFirstOnly && !includeSecondOnly && (size == 2 || size == 4)) { ++ this.result = second.toDoubleArray(); ++ this.resultLength = second.size(); ++ if (size == 2) { ++ this.firstIndices = INFINITE_B_0; ++ } else { ++ this.firstIndices = INFINITE_B_1; ++ } ++ this.secondIndices = INFINITE_C; ++ return; ++ } ++ // Paper end + this.result = new double[k]; + this.firstIndices = new int[k]; + this.secondIndices = new int[k]; +diff --git a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java +index 95428f13dae909bb7de552aa65e4256bd4049c65..94f58332bb1408971fe65e5fd0401457ab986441 100644 +--- a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java ++++ b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java +@@ -337,9 +337,21 @@ public final class Shapes { + } + + @VisibleForTesting +- protected static IndexMerger createIndexMerger(int size, DoubleList first, DoubleList second, boolean includeFirst, boolean includeSecond) { ++ private static IndexMerger createIndexMerger(int size, DoubleList first, DoubleList second, boolean includeFirst, boolean includeSecond) { // Paper - private ++ // Paper start - fast track the most common scenario ++ // doublelist is usually a DoubleArrayList with Infinite head/tails that falls to the final else clause ++ // This is actually the most common path, so jump to it straight away ++ if (first.getDouble(0) == Double.NEGATIVE_INFINITY && first.getDouble(first.size() - 1) == Double.POSITIVE_INFINITY) { ++ return new IndirectMerger(first, second, includeFirst, includeSecond); ++ } ++ // Split out rest to hopefully inline the above ++ return lessCommonMerge(size, first, second, includeFirst, includeSecond); ++ } ++ ++ private static IndexMerger lessCommonMerge(int size, DoubleList first, DoubleList second, boolean includeFirst, boolean includeSecond) { + int i = first.size() - 1; + int j = second.size() - 1; ++ // Paper note - Rewrite below as optimized order if instead of nasty ternary + if (first instanceof CubePointRange && second instanceof CubePointRange) { + long l = lcm(i, j); + if ((long)size * l <= 256L) { +@@ -347,13 +359,22 @@ public final class Shapes { + } + } + +- if (first.getDouble(i) < second.getDouble(0) - 1.0E-7D) { ++ // Paper start - Identical happens more often than Disjoint ++ if (i == j && Objects.equals(first, second)) { ++ if (first instanceof IdenticalMerger) { ++ return (IndexMerger) first; ++ } else if (second instanceof IdenticalMerger) { ++ return (IndexMerger) second; ++ } ++ return new IdenticalMerger(first); ++ } else if (first.getDouble(i) < second.getDouble(0) - 1.0E-7D) { + return new NonOverlappingMerger(first, second, false); + } else if (second.getDouble(j) < first.getDouble(0) - 1.0E-7D) { + return new NonOverlappingMerger(second, first, true); + } else { +- return (IndexMerger)(i == j && Objects.equals(first, second) ? new IdenticalMerger(first) : new IndirectMerger(first, second, includeFirst, includeSecond)); ++ return new IndirectMerger(first, second, includeFirst, includeSecond); + } ++ // Paper end + } + + public interface DoubleLineConsumer { diff --git a/settings.gradle.kts b/settings.gradle.kts index 54bb95749..a9d4e7b2c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -7,4 +7,4 @@ pluginManagement { rootProject.name = "Paper" -include("Paper-API", "Paper-Server") +include("Paper-API", "Paper-Server", "Paper-MojangAPI") diff --git a/work/Bukkit b/work/Bukkit index 8503c3c9e..a791f93de 160000 --- a/work/Bukkit +++ b/work/Bukkit @@ -1 +1 @@ -Subproject commit 8503c3c9e3dca76b2ae10796d8c288b3f3101737 +Subproject commit a791f93de242bf89d116fed843b889e38433e094 diff --git a/work/CraftBukkit b/work/CraftBukkit index 40caacc84..85b8c1fda 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit 40caacc846a6349cd555d9d89cf9cf729c0b75b7 +Subproject commit 85b8c1fda69f6f80e45ddd19590846c249e5b6bc