aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJake Potrebic <[email protected]>2021-06-13 18:06:38 -0700
committerGitHub <[email protected]>2021-06-13 18:06:38 -0700
commit2a46c72164697a80f7b257dcc26b980c48b505ff (patch)
tree06ee1b5c5b2a54b7fb2948c02b8f289501eb2bb8
parent9085da6e602fda8de3b03fece8e4d31278274b8c (diff)
downloadPaper-2a46c72164697a80f7b257dcc26b980c48b505ff.tar.gz
Paper-2a46c72164697a80f7b257dcc26b980c48b505ff.zip
EVEN MOOOOOAAAAAAARRRRRRR patches :) (#5820)
-rw-r--r--Paper-MojangAPI/build.gradle.kts26
-rw-r--r--patches/api/0072-API-to-get-a-BlockState-without-a-snapshot.patch4
-rw-r--r--patches/api/0116-RangedEntity-API.patch19
-rw-r--r--patches/api/0139-Allow-Blocks-to-be-accessed-via-a-long-key.patch4
-rw-r--r--patches/api/0181-Add-BlockSoundGroup-interface.patch14
-rw-r--r--patches/api/0186-Add-effect-to-block-break-naturally.patch4
-rw-r--r--patches/api/0191-Add-tick-times-API.patch (renamed from patches/api-unmapped/0190-Add-tick-times-API.patch)4
-rw-r--r--patches/api/0192-Expose-MinecraftServer-isRunning.patch (renamed from patches/api-unmapped/0191-Expose-MinecraftServer-isRunning.patch)4
-rw-r--r--patches/api/0193-Add-Raw-Byte-ItemStack-Serialization.patch (renamed from patches/api-unmapped/0206-Add-Raw-Byte-ItemStack-Serialization.patch)2
-rw-r--r--patches/api/0194-Disable-Sync-Events-firing-Async-errors-during-shutd.patch (renamed from patches/api-unmapped/0192-Disable-Sync-Events-firing-Async-errors-during-shutd.patch)2
-rw-r--r--patches/api/0195-Make-JavaPluginLoader-thread-safe.patch (renamed from patches/api-unmapped/0193-Make-JavaPluginLoader-thread-safe.patch)0
-rw-r--r--patches/api/0196-Add-Player-Client-Options-API.patch (renamed from patches/api-unmapped/0194-Add-Player-Client-Options-API.patch)4
-rw-r--r--patches/api/0197-Add-PlayerAttackEntityCooldownResetEvent.patch (renamed from patches/api-unmapped/0195-Add-PlayerAttackEntityCooldownResetEvent.patch)0
-rw-r--r--patches/api/0198-Fix-Potion-toItemStack-swapping-the-extended-and-upg.patch (renamed from patches/api-unmapped/0196-Fix-Potion-toItemStack-swapping-the-extended-and-upg.patch)0
-rw-r--r--patches/api/0199-Villager-Restocks-API.patch (renamed from patches/api-unmapped/0197-Villager-Restocks-API.patch)0
-rw-r--r--patches/api/0200-Expose-game-version.patch (renamed from patches/api-unmapped/0198-Expose-game-version.patch)4
-rw-r--r--patches/removed/1.17/0436-Delay-unsafe-actions-until-after-entity-ticking-is-d.patch (renamed from patches/server-remapped/0436-Delay-unsafe-actions-until-after-entity-ticking-is-d.patch)2
-rw-r--r--patches/removed/1.17/0446-Optimize-ChunkProviderServer-s-chunk-level-checking-.patch (renamed from patches/server-remapped/0446-Optimize-ChunkProviderServer-s-chunk-level-checking-.patch)2
-rw-r--r--patches/server-remapped/0434-Add-Raw-Byte-ItemStack-Serialization.patch102
-rw-r--r--patches/server-remapped/0441-Remove-streams-from-PairedQueue.patch79
-rw-r--r--patches/server-remapped/0453-Load-Chunks-for-Login-Asynchronously.patch416
-rw-r--r--patches/server-remapped/0464-Optimize-Voxel-Shape-Merging.patch175
-rw-r--r--patches/server/0010-Adventure.patch4
-rw-r--r--patches/server/0025-Entity-Origin-API.patch4
-rw-r--r--patches/server/0051-Add-velocity-warnings.patch4
-rw-r--r--patches/server/0125-Provide-E-TE-Chunk-count-stat-methods.patch4
-rw-r--r--patches/server/0128-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch4
-rw-r--r--patches/server/0147-Entity-fromMobSpawner.patch4
-rw-r--r--patches/server/0167-API-to-get-a-BlockState-without-a-snapshot.patch4
-rw-r--r--patches/server/0196-Expand-World.spawnParticle-API-and-add-Builder.patch4
-rw-r--r--patches/server/0201-Allow-spawning-Item-entities-with-World.spawnEntity.patch4
-rw-r--r--patches/server/0206-Fix-CraftEntity-hashCode.patch4
-rw-r--r--patches/server/0213-Expand-Explosions-API.patch4
-rw-r--r--patches/server/0215-RangedEntity-API.patch12
-rw-r--r--patches/server/0217-Implement-World.getEntity-UUID-API.patch4
-rw-r--r--patches/server/0256-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch4
-rw-r--r--patches/server/0257-Asynchronous-chunk-IO-and-loading.patch8
-rw-r--r--patches/server/0272-Add-sun-related-API.patch4
-rw-r--r--patches/server/0312-Entity-getEntitySpawnReason.patch4
-rw-r--r--patches/server/0320-Add-Heightmap-API.patch4
-rw-r--r--patches/server/0325-improve-CraftWorld-isChunkLoaded.patch4
-rw-r--r--patches/server/0326-Configurable-Keep-Spawn-Loaded-range-per-world.patch4
-rw-r--r--patches/server/0328-Implement-CraftBlockSoundGroup.patch9
-rw-r--r--patches/server/0330-Fix-World-isChunkGenerated-calls.patch6
-rw-r--r--patches/server/0340-Fix-spawning-of-hanging-entities-that-are-not-ItemFr.patch4
-rw-r--r--patches/server/0357-Add-effect-to-block-break-naturally.patch6
-rw-r--r--patches/server/0361-No-Tick-view-distance-implementation.patch4
-rw-r--r--patches/server/0386-Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch12
-rw-r--r--patches/server/0389-Add-tick-times-API-and-mspt-command.patch (renamed from patches/server-remapped/0432-Add-tick-times-API-and-mspt-command.patch)21
-rw-r--r--patches/server/0390-Expose-MinecraftServer-isRunning.patch (renamed from patches/server-remapped/0433-Expose-MinecraftServer-isRunning.patch)4
-rw-r--r--patches/server/0391-Add-Raw-Byte-ItemStack-Serialization.patch58
-rw-r--r--patches/server/0392-Remove-streams-from-Mob-AI-System.patch (renamed from patches/server-remapped/0435-Remove-streams-from-Mob-AI-System.patch)165
-rw-r--r--patches/server/0393-Async-command-map-building.patch (renamed from patches/server-remapped/0437-Async-command-map-building.patch)6
-rw-r--r--patches/server/0394-Improved-Watchdog-Support.patch (renamed from patches/server-remapped/0438-Improved-Watchdog-Support.patch)169
-rw-r--r--patches/server/0395-Optimize-Pathfinding.patch (renamed from patches/server-remapped/0439-Optimize-Pathfinding.patch)32
-rw-r--r--patches/server/0396-Reduce-Either-Optional-allocation.patch (renamed from patches/server-remapped/0440-Reduce-Either-Optional-allocation.patch)2
-rw-r--r--patches/server/0397-Remove-streams-from-PairedQueue.patch46
-rw-r--r--patches/server/0398-Reduce-memory-footprint-of-NBTTagCompound.patch (renamed from patches/server-remapped/0442-Reduce-memory-footprint-of-NBTTagCompound.patch)35
-rw-r--r--patches/server/0399-Prevent-opening-inventories-when-frozen.patch (renamed from patches/server-remapped/0443-Prevent-opening-inventories-when-frozen.patch)29
-rw-r--r--patches/server/0400-Optimise-ArraySetSorted-removeIf.patch (renamed from patches/server-remapped/0444-Optimise-ArraySetSorted-removeIf.patch)30
-rw-r--r--patches/server/0401-Don-t-run-entity-collision-code-if-not-needed.patch (renamed from patches/server-remapped/0445-Don-t-run-entity-collision-code-if-not-needed.patch)8
-rw-r--r--patches/server/0402-Restrict-vanilla-teleport-command-to-valid-locations.patch (renamed from patches/server-remapped/0447-Restrict-vanilla-teleport-command-to-valid-locations.patch)4
-rw-r--r--patches/server/0403-Implement-Player-Client-Options-API.patch (renamed from patches/server-remapped/0448-Implement-Player-Client-Options-API.patch)90
-rw-r--r--patches/server/0404-Fix-Chunk-Post-Processing-deadlock-risk.patch (renamed from patches/server-remapped/0449-Fix-Chunk-Post-Processing-deadlock-risk.patch)13
-rw-r--r--patches/server/0405-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch (renamed from patches/server-remapped/0450-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch)4
-rw-r--r--patches/server/0406-Broadcast-join-message-to-console.patch (renamed from patches/server-remapped/0451-Broadcast-join-message-to-console.patch)8
-rw-r--r--patches/server/0407-Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch (renamed from patches/server-remapped/0452-Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch)72
-rw-r--r--patches/server/0408-Load-Chunks-for-Login-Asynchronously.patch277
-rw-r--r--patches/server/0409-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch (renamed from patches/server-remapped/0454-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch)6
-rw-r--r--patches/server/0410-Add-PlayerAttackEntityCooldownResetEvent.patch (renamed from patches/server-remapped/0455-Add-PlayerAttackEntityCooldownResetEvent.patch)4
-rw-r--r--patches/server/0411-Allow-multiple-callbacks-to-schedule-for-Callback-Ex.patch (renamed from patches/server-remapped/0456-Allow-multiple-callbacks-to-schedule-for-Callback-Ex.patch)38
-rw-r--r--patches/server/0412-Don-t-fire-BlockFade-on-worldgen-threads.patch (renamed from patches/server-remapped/0457-Don-t-fire-BlockFade-on-worldgen-threads.patch)8
-rw-r--r--patches/server/0413-Add-phantom-creative-and-insomniac-controls.patch (renamed from patches/server-remapped/0458-Add-phantom-creative-and-insomniac-controls.patch)39
-rw-r--r--patches/server/0414-Fix-numerous-item-duplication-issues-and-teleport-is.patch (renamed from patches/server-remapped/0459-Fix-numerous-item-duplication-issues-and-teleport-is.patch)24
-rw-r--r--patches/server/0415-Implement-Brigadier-Mojang-API.patch (renamed from patches/server-remapped/0460-Implement-Brigadier-Mojang-API.patch)34
-rw-r--r--patches/server/0416-Villager-Restocks-API.patch (renamed from patches/server-remapped/0461-Villager-Restocks-API.patch)10
-rw-r--r--patches/server/0417-Validate-PickItem-Packet-and-kick-for-invalid.patch (renamed from patches/server-remapped/0462-Validate-PickItem-Packet-and-kick-for-invalid.patch)16
-rw-r--r--patches/server/0418-Expose-game-version.patch (renamed from patches/server-remapped/0463-Expose-game-version.patch)6
-rw-r--r--patches/server/0419-Optimize-Voxel-Shape-Merging.patch121
-rw-r--r--settings.gradle.kts2
m---------work/Bukkit0
m---------work/CraftBukkit0
82 files changed, 967 insertions, 1414 deletions
diff --git a/Paper-MojangAPI/build.gradle.kts b/Paper-MojangAPI/build.gradle.kts
new file mode 100644
index 0000000000..e0ef6532b9
--- /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 17364528bc..26c4c4cc18 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 f609bc2f0e..c86139036d 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 7014671c66..6591a86aed 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 428810f1d8..566c91565a 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 5ccd8c2548..ce1785047a 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
index a4ae8d485c..b4d7379b4b 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
index 33f2570121..4a5c20868f 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
index 8ffb283fa6..e88adb86e7 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
index 5ca0264ed8..32392efc4e 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
index be66a6a695..be66a6a695 100644
--- a/patches/api-unmapped/0193-Make-JavaPluginLoader-thread-safe.patch
+++ b/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
index c156119b15..a271a07324 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
index 15fa2db392..15fa2db392 100644
--- a/patches/api-unmapped/0195-Add-PlayerAttackEntityCooldownResetEvent.patch
+++ b/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
index 800d5364e2..800d5364e2 100644
--- 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
diff --git a/patches/api-unmapped/0197-Villager-Restocks-API.patch b/patches/api/0199-Villager-Restocks-API.patch
index e2dcfc3144..e2dcfc3144 100644
--- a/patches/api-unmapped/0197-Villager-Restocks-API.patch
+++ b/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
index 560d2370a1..987427e030 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
index 9fb51d1e35..2c856fd185 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
index e6f6255656..083f25a75d 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 4f867cd88c..0000000000
--- 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 <[email protected]>
-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<Tag> converted = DataFixers.getDataFixer().update(References.ITEM_STACK, new Dynamic<Tag>(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 935abedc0d..0000000000
--- 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 <[email protected]>
-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<T, F> {
-
- public static final class FixedPriorityQueue implements StrictQueue<StrictQueue.IntRunnable, Runnable> {
-
-- private final List<Queue<Runnable>> queueList;
-+ private final List<Queue<Runnable>> queueList; private final List<Queue<Runnable>> 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<Runnable> queue = this.getQueues().get(i);
-+ Runnable ret = queue.poll();
-+ if (ret != null) {
-+ return ret;
- }
--
-- Queue<Runnable> 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<T, F> {
-
- @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<Runnable> 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 f02494b2a2..0000000000
--- 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 <[email protected]>
-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<ChunkTaskPriorityQueueSorter.Message<Runnable>> worldgenMailbox;
- private final ProcessorHandle<ChunkTaskPriorityQueueSorter.Message<Runnable>> 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<Integer> 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<T> {
- public static final TicketType<ChunkPos> FORCED = create("forced", Comparator.comparingLong(ChunkPos::toLong));
- public static final TicketType<ChunkPos> LIGHT = create("light", Comparator.comparingLong(ChunkPos::toLong));
- public static final TicketType<BlockPos> PORTAL = create("portal", Vec3i::compareTo, 300);
-+ public static final TicketType<Long> LOGIN = create("login", Long::compareTo, 100); // Paper
- public static final TicketType<Integer> POST_TELEPORT = create("post_teleport", Integer::compareTo, 5);
- public static final TicketType<ChunkPos> UNKNOWN = create("unknown", Comparator.comparingLong(ChunkPos::toLong), 1);
- public static final TicketType<Unit> 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<ServerPlayer> players = new java.util.concurrent.CopyOnWriteArrayList(); // CraftBukkit - ArrayList -> CopyOnWriteArrayList: Iterator safety
-- private final Map<UUID, ServerPlayer> playersByUUID = Maps.newHashMap();
-+ private final Map<UUID, ServerPlayer> playersByUUID = Maps.newHashMap();Map<UUID, ServerPlayer> getUUIDMap() { return playersByUUID; } // Paper - OBFHELPER
- private final UserBanList bans;
- private final IpBanList ipBans;
- private final ServerOpList ops;
- private final UserWhiteList whitelist;
-+ private final Map<UUID, ServerPlayer> pendingPlayers = Maps.newHashMap(); // Paper
- // CraftBukkit start
- // private final Map<UUID, ServerStatisticManager> o;
- // private final Map<UUID, AdvancementDataPlayer> 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 935b12df1e..0000000000
--- 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 <[email protected]>
-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 4f747860da..1da3dba942 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 cdae1bf4b3..1029b368c6 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 2a5b77ca91..0039fad826 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 84141dee36..b2f4bbed01 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 443029cb4a..26eef0feb7 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 34ebf1b310..c8b928e2bd 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 c5483d657a..0ad07b41da 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 719bc3db58..c403b862a0 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 <T> 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 5f114f6efd..110d6d75ee 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 9c66bc30b3..b260b94401 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 211ac6f053..b9c8b6499f 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 96a8f6424a..1cfaceeec1 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<AbstractSkeleton> { // Paper
+-public class CraftSkeleton extends CraftAbstractSkeleton implements Skeleton {
++public class CraftSkeleton extends CraftAbstractSkeleton implements Skeleton, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.AbstractSkeleton> { // 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 db3675e02f..0e8d1dd597 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 a54b182f75..d3469898d1 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 dda7a3dcd0..ea7e8e8faa 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 f3352dd107..52e76a976f 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 90d47b684f..fbcb73d40c 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 4c7380555f..59f0009d95 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 cb95e90f06..4eb97bfd19 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 9d6f848e88..82b32a8df4 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 76559b8fc1..6cb5b06325 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 953566fa39..8cfc74e92c 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 8a4a109b18..019515ccee 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 f0c758d801..1f77985ef9 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 6fdb3036eb..3087bd1eca 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 71138d1089..8118c956ed 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<ChunkHolder> 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
index 0f2cf4005e..81685ed79c 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<TickTa
- private int maxBuildHeight;
+@@ -249,6 +249,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+ private String motd;
private int playerIdleTimeout;
- public final long[] tickTimes; public long[] getTickTimes() { return tickTimes; } // Paper - OBFHELPER
+ public final long[] tickTimes;
+ // Paper start
+ public final TickTimes tickTimes5s = new TickTimes(100);
+ public final TickTimes tickTimes10s = new TickTimes(200);
@@ -102,7 +102,7 @@ index 087f31ac0cc7816b1cbeffc45be6927b174dee62..99ee9de92264381a064066bc22bb66b4
@Nullable
private KeyPair keyPair;
@Nullable
-@@ -1329,6 +1334,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -1390,6 +1395,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.averageTickTime = this.averageTickTime * 0.8F + (float) l / 1000000.0F * 0.19999999F;
long i1 = Util.getNanos();
@@ -115,11 +115,10 @@ index 087f31ac0cc7816b1cbeffc45be6927b174dee62..99ee9de92264381a064066bc22bb66b4
this.frameTimer.logFrameDuration(i1 - i);
this.profiler.pop();
org.spigotmc.WatchdogThread.tick(); // Spigot
-@@ -2301,4 +2312,30 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
- public TextFilter createTextFilterForPlayer(ServerPlayer player) {
- return null;
+@@ -2461,4 +2472,29 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+ };
+ }
}
-+
+ // Paper start
+ public static class TickTimes {
+ private final long[] times;
@@ -147,10 +146,10 @@ index 087f31ac0cc7816b1cbeffc45be6927b174dee62..99ee9de92264381a064066bc22bb66b4
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 3c0ba80bbba19f3725013e118cecdbac5612deec..4fa49b6bb26456d485f7f9193af560cb379e36f0 100644
+index 9730c701b734eb3491bc1fa5d9bb81ddfefc910a..6eebbe2d7948a164f9562801b727768d199fa228 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-@@ -2201,6 +2201,16 @@ public final class CraftServer implements Server {
+@@ -2202,6 +2202,16 @@ public final class CraftServer implements Server {
net.minecraft.server.MinecraftServer.getServer().tps15.getAverage()
};
}
diff --git a/patches/server-remapped/0433-Expose-MinecraftServer-isRunning.patch b/patches/server/0390-Expose-MinecraftServer-isRunning.patch
index d493c8573e..eee93a6749 100644
--- a/patches/server-remapped/0433-Expose-MinecraftServer-isRunning.patch
+++ b/patches/server/0390-Expose-MinecraftServer-isRunning.patch
@@ -6,10 +6,10 @@ 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/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 4fa49b6bb26456d485f7f9193af560cb379e36f0..3f35e93b42efd03ff1002f09962fe3da51fb4c3f 100644
+index 6eebbe2d7948a164f9562801b727768d199fa228..3423de396e0fadfa29714f5fcac4b579a8ff0967 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-@@ -2378,5 +2378,10 @@ public final class CraftServer implements Server {
+@@ -2379,5 +2379,10 @@ public final class CraftServer implements Server {
public int getCurrentTick() {
return net.minecraft.server.MinecraftServer.currentTick;
}
diff --git a/patches/server/0391-Add-Raw-Byte-ItemStack-Serialization.patch b/patches/server/0391-Add-Raw-Byte-ItemStack-Serialization.patch
new file mode 100644
index 0000000000..761655bfd4
--- /dev/null
+++ b/patches/server/0391-Add-Raw-Byte-ItemStack-Serialization.patch
@@ -0,0 +1,58 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Mariell Hoversholm <[email protected]>
+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<Tag> converted = DataFixers.getDataFixer().update(References.ITEM_STACK, new Dynamic<Tag>(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
index 019eef698e..12d3a671c6 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<Goal.Flag> flags = EnumSet.noneOf(Goal.Flag.class);
+ private final EnumSet<Goal.Flag> 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<Flag> goalTypes = new OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector
++ private final com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<net.minecraft.world.entity.ai.goal.Goal.Flag> 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<Goal.Flag> 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<Goal.Flag, WrappedGoal> lockedFlags = new EnumMap(Goal.Flag.class);
- private final Set<WrappedGoal> availableGoals = Sets.newLinkedHashSet(); private Set<WrappedGoal> getTasks() { return availableGoals; }// Paper - OBFHELPER
+@@ -28,10 +28,12 @@ public class GoalSelector {
+ private final Map<Goal.Flag, WrappedGoal> lockedFlags = new EnumMap<>(Goal.Flag.class);
+ private final Set<WrappedGoal> availableGoals = Sets.newLinkedHashSet();
private final Supplier<ProfilerFiller> profiler;
- private final EnumSet<Goal.Flag> disabledFlags = EnumSet.noneOf(Goal.Flag.class);
+ private final EnumSet<Goal.Flag> 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<Goal.Flag> 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<net.minecraft.world.entity.ai.goal.Goal.Flag> 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<ProfilerFiller> 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<WrappedGoal> iterator = this.availableGoals.iterator(); iterator.hasNext();) {
++ for (java.util.Iterator<WrappedGoal> 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;
-- }
+ 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 (Iterator<WrappedGoal> iterator = this.availableGoals.iterator(); iterator.hasNext();) {
++ for (java.util.Iterator<WrappedGoal> iterator = this.availableGoals.iterator(); iterator.hasNext();) {
+ WrappedGoal wrappedGoal = iterator.next();
-+ if (!wrappedGoal.isRunning()) {
+ if (!wrappedGoal.isRunning()) {
+- this.lockedFlags.remove(flag);
+ continue;
- }
--
-- flag = true;
-- return flag;
-- }).forEach(Goal::stop);
++ }
+ 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<WrappedGoal> iterator = this.availableGoals.iterator(); iterator.hasNext();) {
++ goal_update_loop: for (java.util.Iterator<WrappedGoal> iterator = this.availableGoals.iterator(); iterator.hasNext();) {
+ WrappedGoal wrappedGoal = iterator.next();
+ if (wrappedGoal.isRunning()) {
+ continue;
+ }
+
-+ OptimizedSmallEnumSet<Goal.Flag> wrappedGoalSet = wrappedGoal.getGoalTypes();
++ com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<net.minecraft.world.entity.ai.goal.Goal.Flag> 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<WrappedGoal> iterator = this.availableGoals.iterator(); iterator.hasNext();) {
++ for (java.util.Iterator<WrappedGoal> 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
index 87f32eb782..12df4c5c75 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
index 928b62d524..be6786aadf 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<TickTa
+@@ -301,7 +301,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+ public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>();
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<TickTa
+@@ -311,6 +311,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public final SlackActivityAccountant slackActivityAccountant = new SlackActivityAccountant();
// Spigot end
@@ -105,17 +93,17 @@ index 99ee9de92264381a064066bc22bb66b4b2852a2e..e5ad635a480d32e7a10ee92c65cfc18a
public static <S extends MinecraftServer> S spin(Function<Thread, S> serverFactory) {
AtomicReference<S> atomicreference = new AtomicReference();
Thread thread = new Thread(() -> {
-@@ -851,6 +854,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -908,6 +911,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// CraftBukkit start
private boolean hasStopped = false;
+ public volatile boolean hasFullyShutdown = false; // Paper
private final Object stopLock = new Object();
public final boolean hasStopped() {
- synchronized (stopLock) {
-@@ -865,6 +869,23 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
- if (hasStopped) return;
- hasStopped = true;
+ synchronized (this.stopLock) {
+@@ -922,6 +926,19 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+ if (this.hasStopped) return;
+ this.hasStopped = true;
}
+ // Paper start - kill main thread, and kill it hard
+ shutdownThread = Thread.currentThread();
@@ -128,24 +116,20 @@ index 99ee9de92264381a064066bc22bb66b4b2852a2e..e5ad635a480d32e7a10ee92c65cfc18a
+ Thread.sleep(1);
+ } catch (InterruptedException e) {}
+ }
-+ // We've just obliterated the main thread, this will prevent stop from dying when removing players
-+ MinecraftServer.getServer().getAllLevels().forEach(world -> {
-+ 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<TickTa
- this.getProfileCache().b(false); // Paper
+@@ -987,7 +1004,18 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+ this.getProfileCache().save(false); // Paper
}
// Spigot end
+ // Paper start - move final shutdown items here
+ LOGGER.info("Flushing Chunk IO");
com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.close(true, true); // Paper
+ LOGGER.info("Closing Thread Pool");
-+ Util.shutdownServerThreadPool(); // Paper
++ Util.shutdownExecutors(); // Paper
+ LOGGER.info("Closing Server");
+ try {
+ net.minecrell.terminalconsole.TerminalConsoleAppender.close(); // Paper - Use TerminalConsoleAppender
@@ -156,7 +140,7 @@ index 99ee9de92264381a064066bc22bb66b4b2852a2e..e5ad635a480d32e7a10ee92c65cfc18a
}
public String getLocalIp() {
-@@ -1023,6 +1055,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -1080,6 +1108,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
protected void runServer() {
try {
@@ -164,7 +148,7 @@ index 99ee9de92264381a064066bc22bb66b4b2852a2e..e5ad635a480d32e7a10ee92c65cfc18a
if (this.initServer()) {
this.nextTickTime = Util.getMillis();
this.status.setDescription(new TextComponent(this.motd));
-@@ -1030,6 +1063,18 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -1087,6 +1116,18 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.updateStatusIcon(this.status);
// Spigot start
@@ -183,7 +167,7 @@ index 99ee9de92264381a064066bc22bb66b4b2852a2e..e5ad635a480d32e7a10ee92c65cfc18a
org.spigotmc.WatchdogThread.hasStarted = true; // Paper
Arrays.fill( recentTps, 20 );
long start = System.nanoTime(), curTime, tickSection = start; // Paper - Further improve server tick loop
-@@ -1085,6 +1130,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -1143,6 +1184,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.onServerCrash((CrashReport) null);
}
} catch (Throwable throwable) {
@@ -196,7 +180,7 @@ index 99ee9de92264381a064066bc22bb66b4b2852a2e..e5ad635a480d32e7a10ee92c65cfc18a
MinecraftServer.LOGGER.error("Encountered an unexpected exception", throwable);
// Spigot Start
if ( throwable.getCause() != null )
-@@ -1116,14 +1167,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -1178,14 +1225,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
} catch (Throwable throwable1) {
MinecraftServer.LOGGER.error("Exception stopping the server", throwable1);
} finally {
@@ -214,7 +198,7 @@ index 99ee9de92264381a064066bc22bb66b4b2852a2e..e5ad635a480d32e7a10ee92c65cfc18a
}
}
-@@ -1179,6 +1230,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -1241,6 +1288,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@Override
public TickTask wrapRunnable(Runnable runnable) {
@@ -227,7 +211,7 @@ index 99ee9de92264381a064066bc22bb66b4b2852a2e..e5ad635a480d32e7a10ee92c65cfc18a
return new TickTask(this.tickCount, runnable);
}
-@@ -1421,6 +1478,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -1482,6 +1535,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
try {
crashreport = CrashReport.forThrowable(throwable, "Exception ticking world");
} catch (Throwable t) {
@@ -235,9 +219,9 @@ index 99ee9de92264381a064066bc22bb66b4b2852a2e..e5ad635a480d32e7a10ee92c65cfc18a
throw new RuntimeException("Error generating crash report", t);
}
// Spigot End
-@@ -1878,7 +1936,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -1959,7 +2013,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.packRepository.setSelected(datapacks);
- this.worldData.setDataPackConfig(getSelectedPacks(this.packRepository));
+ this.worldData.setDataPackConfig(MinecraftServer.getSelectedPacks(this.packRepository));
datapackresources.updateGlobals();
- this.getPlayerList().saveAll();
+ if (Thread.currentThread() != this.serverThread) return; // Paper
@@ -246,10 +230,10 @@ index 99ee9de92264381a064066bc22bb66b4b2852a2e..e5ad635a480d32e7a10ee92c65cfc18a
this.functionManager.replaceLibrary(this.resources.getFunctionLibrary());
this.structureManager.onResourceManagerReload(this.resources.getResourceManager());
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
-index f8ddc0aa98874c7879a51e76d1a629cbdaf58812..6477ba1f31d977f8199fb4c7532938920b385ae7 100644
+index 0511f1921193b78cbf4d8426136bf1f79746f955..e5f7f043cbdb28d85b8aa0eea7cbaeb584e5fb85 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
-@@ -276,7 +276,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
+@@ -283,7 +283,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
long j = Util.getNanos() - i;
String s = String.format(Locale.ROOT, "%.3fs", (double) j / 1.0E9D);
@@ -258,7 +242,7 @@ index f8ddc0aa98874c7879a51e76d1a629cbdaf58812..6477ba1f31d977f8199fb4c753293892
if (dedicatedserverproperties.announcePlayerAchievements != null) {
((GameRules.BooleanValue) this.getGameRules().getRule(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)).set(dedicatedserverproperties.announcePlayerAchievements, (MinecraftServer) this);
}
-@@ -404,7 +404,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
+@@ -446,7 +446,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
//this.remoteStatusListener.b(); // Paper - don't wait for remote connections
}
@@ -268,7 +252,7 @@ index f8ddc0aa98874c7879a51e76d1a629cbdaf58812..6477ba1f31d977f8199fb4c753293892
}
@Override
-@@ -737,7 +738,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
+@@ -779,7 +780,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@Override
public void stopServer() {
super.stopServer();
@@ -278,10 +262,10 @@ index f8ddc0aa98874c7879a51e76d1a629cbdaf58812..6477ba1f31d977f8199fb4c753293892
@Override
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 99eee56d6e66b79dd48ecbd1eeebc08174003f4a..49728aab7512ea8486d277d34e80d3c6a4727aac 100644
+index c304c57a572b7e154362b39065ab8cb30a7e112e..c82345c74e0e6246f304283c2e06e2d1fcfe53ca 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -534,6 +534,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -585,6 +585,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
MutableBoolean mutableboolean = new MutableBoolean();
do {
@@ -289,25 +273,12 @@ index 99eee56d6e66b79dd48ecbd1eeebc08174003f4a..49728aab7512ea8486d277d34e80d3c6
mutableboolean.setFalse();
list.stream().map((playerchunk) -> {
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<Entity> toAddAfterTick = Queues.newArrayDeque();
- public final List<ServerPlayer> players = Lists.newArrayList(); // Paper - private -> public
- public final ServerChunkCache chunkSource; // Paper - public
-- boolean tickingEntities;
-+ public boolean tickingEntities; // Paper - expose for watchdog
- // Paper start
- List<java.lang.Runnable> 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<R extends Runnable> implements Processo
+@@ -148,6 +148,7 @@ public abstract class BlockableEventLoop<R extends Runnable> 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<String> 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
index 9f2777798e..4e073805ba 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
index 991b0f903b..0f4641263b 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<L, R> implements App<Either.Mu<R>, 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 0000000000..91f6f25ab6
--- /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 <[email protected]>
+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<T, F> {
+ private final List<Queue<Runnable>> 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<T, F> {
+
+ @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<Runnable> 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
index dcba632a31..cea824d101 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<String, Tag> hashmap = new Object2ObjectOpenHashMap<>(8, 0.8f); // Paper - reduce memory footprint of NBTTagCompound
-
- byte b0;
+- Map<String, Tag> map = Maps.newHashMap();
++ it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<String, Tag> map = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(8, 0.8f); // Paper - reduce memory footprint of NBTTagCompound
-@@ -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<String, Tag> map = Maps.newHashMap(Maps.transformValues(this.tags, Tag::copy));
-+ // Paper start - reduce memory footprint of NBTTagCompound
-+ Object2ObjectOpenHashMap<String, Tag> ret = new Object2ObjectOpenHashMap<>(this.tags.size(), 0.8f);
-
- return new CompoundTag(map);
-+ Iterator<Map.Entry<String, Tag>> 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<String, Tag> ret = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(this.tags.size(), 0.8f);
++ java.util.Iterator<java.util.Map.Entry<String, Tag>> 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<String, Tag> 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
index 7b2a22a56b..29b12f74db 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
index dad03aa170..1f9f1e2e4e 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<T> extends AbstractSet<T> {
-
- private final Comparator<T> 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<T> comparator) {
- this.comparator = comparator;
-@@ -22,6 +22,42 @@ public class SortedArraySet<T> extends AbstractSet<T> {
+@@ -22,6 +22,41 @@ public class SortedArraySet<T> extends AbstractSet<T> {
+ this.contents = (T[])castRawArray(new Object[initialCapacity]);
}
}
-
+ // Paper start - optimise removeIf
+ @Override
+ public boolean removeIf(java.util.function.Predicate<? super T> 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 <T extends Comparable<T>> SortedArraySet<T> create(int initialCapacity) {
- return new SortedArraySet<>(initialCapacity, (Comparator)Comparator.naturalOrder()); // Paper - decompile fix
- }
+
+ public static <T extends Comparable<T>> SortedArraySet<T> 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
index 474688a9b3..ce4b9003ba 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<Entity> 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
index bc23f71417..b0ce748234 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<ClientboundPlayerPositionPacket.RelativeArgument> 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
index dcdbea5496..0f85780783 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<ServerGamePack
- listener.handleClientInformation(this);
- }
-
-+ public ChatVisiblity getChatVisibility() { return getChatVisibility(); } // Paper - OBFHELPER
- public ChatVisiblity getChatVisibility() {
- return this.chatVisibility;
- }
-
-+ public boolean hasChatColorsEnabled() { return getChatColors(); } // Paper - OBFHELPER
- public boolean getChatColors() {
- return this.chatColors;
- }
-
-+ public int getSkinParts() { return getModelCustomisation(); } // Paper - OBFHELPER
- public int getModelCustomisation() {
- return this.modelCustomisation;
- }
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index efacfcaab444270b985f3a7fe0ef97e33c18a9de..aa979d17c264840ebd528708df3d6118e69fec68 100644
+index 42c2862530cff79a9b09850faccb683df1f2a5c8..aec3ded7f65e4a97796afc01b71eeb89c2b3fb70 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -2,6 +2,7 @@ package net.minecraft.server.level;
-
- import com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent;
- import com.google.common.collect.Lists;
-+import com.destroystokyo.paper.event.player.PlayerClientOptionsChangeEvent; // Paper
- import com.mojang.authlib.GameProfile;
- import com.mojang.datafixers.util.Either;
- import com.mojang.serialization.DataResult;
-@@ -188,7 +189,7 @@ public class ServerPlayer extends Player implements ContainerListener {
- public int lastSentExp = -99999999;
- public int spawnInvulnerableTime = 60;
- private ChatVisiblity chatVisibility;
-- private boolean canChatColor = true;
-+ private boolean canChatColor = true; public boolean hasChatColorsEnabled() { return this.canChatColor; } // Paper - OBFHELPER
- private long lastActionTime = Util.getMillis();
- private Entity camera;
- public boolean isChangingDimension;
-@@ -1807,6 +1808,7 @@ public class ServerPlayer extends Player implements ContainerListener {
+@@ -1801,6 +1801,7 @@ public class ServerPlayer extends Player {
public String locale = null; // CraftBukkit - add, lowercase // Paper - default to null
public java.util.Locale adventure$locale = java.util.Locale.US; // Paper
public void updateOptions(ServerboundClientInformationPacket packet) {
-+ new PlayerClientOptionsChangeEvent(getBukkitEntity(), packet.language, packet.viewDistance, com.destroystokyo.paper.ClientOption.ChatVisibility.valueOf(packet.getChatVisibility().name()), packet.hasChatColorsEnabled(), new com.destroystokyo.paper.PaperSkinParts(packet.getSkinParts()), packet.getMainHand() == HumanoidArm.LEFT ? MainHand.LEFT : MainHand.RIGHT).callEvent(); // Paper - settings event
++ new com.destroystokyo.paper.event.player.PlayerClientOptionsChangeEvent(getBukkitEntity(), packet.language, packet.viewDistance, com.destroystokyo.paper.ClientOption.ChatVisibility.valueOf(packet.getChatVisibility().name()), packet.getChatColors(), new com.destroystokyo.paper.PaperSkinParts(packet.getModelCustomisation()), packet.getMainHand() == HumanoidArm.LEFT ? MainHand.LEFT : MainHand.RIGHT).callEvent(); // Paper - settings event
// CraftBukkit start
if (getMainArm() != packet.getMainHand()) {
- PlayerChangedMainHandEvent event = new PlayerChangedMainHandEvent(getBukkitEntity(), getMainArm() == HumanoidArm.LEFT ? MainHand.LEFT : MainHand.RIGHT);
+ PlayerChangedMainHandEvent event = new PlayerChangedMainHandEvent(this.getBukkitEntity(), getMainArm() == HumanoidArm.LEFT ? MainHand.LEFT : MainHand.RIGHT);
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
-index 32f1b180e82f41f3ce1b49ea7d67b7d55d2b9ca7..525cd44411b344bc4b5d43c087094fea88fa41a6 100644
+index a3d31cec6d1b8de700b6cd2f7f51398debef5b6d..b916f629c2a0fb018cba19aaa612cbbcbb597dc1 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
-@@ -130,7 +130,7 @@ public abstract class Player extends LivingEntity {
- private static final Map<Pose, EntityDimensions> POSES = ImmutableMap.<Pose, EntityDimensions>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<Float> DATA_PLAYER_ABSORPTION_ID = SynchedEntityData.defineId(Player.class, EntityDataSerializers.FLOAT);
private static final EntityDataAccessor<Integer> DATA_SCORE_ID = SynchedEntityData.defineId(Player.class, EntityDataSerializers.INT);
- protected static final EntityDataAccessor<Byte> DATA_PLAYER_MODE_CUSTOMISATION = SynchedEntityData.defineId(Player.class, EntityDataSerializers.BYTE);
-+ protected static final EntityDataAccessor<Byte> DATA_PLAYER_MODE_CUSTOMISATION = SynchedEntityData.defineId(Player.class, EntityDataSerializers.BYTE); public static EntityDataAccessor<Byte> getSkinPartsWatcher() { return DATA_PLAYER_MODE_CUSTOMISATION; } // Paper - OBFHELPER
++ public static final EntityDataAccessor<Byte> DATA_PLAYER_MODE_CUSTOMISATION = SynchedEntityData.defineId(Player.class, EntityDataSerializers.BYTE); // Paper - protected -> public
protected static final EntityDataAccessor<Byte> DATA_PLAYER_MAIN_HAND = SynchedEntityData.defineId(Player.class, EntityDataSerializers.BYTE);
protected static final EntityDataAccessor<CompoundTag> DATA_SHOULDER_LEFT = SynchedEntityData.defineId(Player.class, EntityDataSerializers.COMPOUND_TAG);
protected static final EntityDataAccessor<CompoundTag> 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> T getClientOption(ClientOption<T> 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> T getClientOption(com.destroystokyo.paper.ClientOption<T> 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
index 1d32694a1d..eff3a55349 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<ServerPlayer> 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
index 1469edc105..324693d286 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<ServerPlayer> 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
index de365413d4..255cb81628 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
index e4ac02eb91..c85247b418 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 0000000000..399eeca8a3
--- /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 <[email protected]>
+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<T> {
+ public static final TicketType<ChunkPos> FORCED = TicketType.create("forced", Comparator.comparingLong(ChunkPos::toLong));
+ public static final TicketType<ChunkPos> LIGHT = TicketType.create("light", Comparator.comparingLong(ChunkPos::toLong));
+ public static final TicketType<BlockPos> PORTAL = TicketType.create("portal", Vec3i::compareTo, 300);
++ public static final TicketType<Long> LOGIN = create("login", Long::compareTo, 100); // Paper
+ public static final TicketType<Integer> POST_TELEPORT = TicketType.create("post_teleport", Integer::compareTo, 5);
+ public static final TicketType<ChunkPos> UNKNOWN = TicketType.create("unknown", Comparator.comparingLong(ChunkPos::toLong), 1);
+ public static final TicketType<Unit> 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<ServerPlayer> players = new java.util.concurrent.CopyOnWriteArrayList(); // CraftBukkit - ArrayList -> CopyOnWriteArrayList: Iterator safety
+- private final Map<UUID, ServerPlayer> playersByUUID = Maps.newHashMap();
++ private final Map<UUID, ServerPlayer> playersByUUID = Maps.newHashMap();Map<UUID, ServerPlayer> getUUIDMap() { return playersByUUID; } // Paper - OBFHELPER
+ private final UserBanList bans;
+ private final IpBanList ipBans;
+ private final ServerOpList ops;
+ private final UserWhiteList whitelist;
++ private final Map<UUID, ServerPlayer> pendingPlayers = Maps.newHashMap(); // Paper
+ // CraftBukkit start
+ // private final Map<UUID, ServerStatisticManager> o;
+ // private final Map<UUID, AdvancementDataPlayer> 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
index eeaa3a49f4..ed5d792bee 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
index f1eab97e33..8ef5ac518f 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
index 025b5a9d8e..1ad36331ec 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<Runnable> 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<Runnable> queued = new java.util.ArrayDeque<>();
++ private java.util.Queue<Runnable> 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<Runnable> queue = queued;
- queued = null;
-- if (task != null) {
-+ Runnable task;
-+ while ((task = queue.pollFirst()) != null) {
++ java.util.Queue<Runnable> 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
index 8997a0897d..fe13efc946 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
index 9a052de409..6b22ec66cb 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<Entity> NO_SPECTATORS = (entity) -> {
return !entity.isSpectator();
};
-+ public static Predicate<Player> isInsomniac = (player) -> Mth.clamp(((ServerPlayer) player).getStats().getValue(Stats.CUSTOM.get(Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= 72000; // Paper
++ public static Predicate<Player> 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<Entity> 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
index 9e378d1d32..b1c5df36ef 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
index 5504aee900..c73a8699ba 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<String> bukkit, RootCommandNode<SharedSuggestionProvider> 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<CommandSourceStack> 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 [<args>] 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
index 49b6ff50fa..3f24c8fdfe 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<MemoryModuleType<?>> 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<MemoryModuleType<?>> 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
index 34909e54c5..348bbe236c 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
index 9e0cf63bd9..9c79c20af1 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 0000000000..4227b67cdc
--- /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 <[email protected]>
+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 54bb957497..a9d4e7b2c7 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
-Subproject 8503c3c9e3dca76b2ae10796d8c288b3f310173
+Subproject a791f93de242bf89d116fed843b889e38433e09
diff --git a/work/CraftBukkit b/work/CraftBukkit
-Subproject 40caacc846a6349cd555d9d89cf9cf729c0b75b
+Subproject 85b8c1fda69f6f80e45ddd19590846c249e5b6b