From ddb72c221da12bfc062eb1d4f754074511ac548a Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Sun, 13 Jun 2021 18:06:38 -0700 Subject: [PATCH] EVEN MOOOOOAAAAAAARRRRRRR patches :) (#5820) --- Paper-MojangAPI/build.gradle.kts | 26 +++ .../api/Add-BlockSoundGroup-interface.patch | 10 +- .../Add-Player-Client-Options-API.patch | 0 ...PlayerAttackEntityCooldownResetEvent.patch | 0 ...Add-Raw-Byte-ItemStack-Serialization.patch | 0 .../Add-tick-times-API.patch | 0 ...nts-firing-Async-errors-during-shutd.patch | 0 .../Expose-MinecraftServer-isRunning.patch | 0 .../Expose-game-version.patch | 0 ...mStack-swapping-the-extended-and-upg.patch | 0 .../Make-JavaPluginLoader-thread-safe.patch | 0 patches/api/RangedEntity-API.patch | 15 +- .../Villager-Restocks-API.patch | 0 ...ions-until-after-entity-ticking-is-d.patch | 45 ---- ...oviderServer-s-chunk-level-checking-.patch | 59 ----- .../Optimize-Voxel-Shape-Merging.patch | 175 -------------- ...PlayerAttackEntityCooldownResetEvent.patch | 0 ...Add-Raw-Byte-ItemStack-Serialization.patch | 50 +--- ...ntom-creative-and-insomniac-controls.patch | 27 +-- .../Add-tick-times-API-and-mspt-command.patch | 9 +- ...allbacks-to-schedule-for-Callback-Ex.patch | 34 +-- .../Async-command-map-building.patch | 0 .../Broadcast-join-message-to-console.patch | 4 +- ...layer-is-attempted-to-be-removed-fro.patch | 0 ...t-fire-BlockFade-on-worldgen-threads.patch | 2 +- ...-entity-collision-code-if-not-needed.patch | 4 +- .../Expose-MinecraftServer-isRunning.patch | 0 .../Expose-game-version.patch | 2 +- ...-Chunk-Post-Processing-deadlock-risk.patch | 3 +- ...g-Broken-behavior-of-PlayerJoinEvent.patch | 54 +---- ...m-duplication-issues-and-teleport-is.patch | 12 +- .../Implement-Brigadier-Mojang-API.patch | 20 +- .../Implement-CraftBlockSoundGroup.patch | 5 +- .../Implement-Player-Client-Options-API.patch | 80 ++----- .../Improved-Watchdog-Support.patch | 95 +++----- ...Load-Chunks-for-Login-Asynchronously.patch | 217 ++++-------------- ...pawn-point-if-spawn-in-unloaded-worl.patch | 4 +- .../Optimise-ArraySetSorted-removeIf.patch | 26 +-- .../Optimize-Pathfinding.patch | 28 +-- .../server/Optimize-Voxel-Shape-Merging.patch | 121 ++++++++++ ...vent-opening-inventories-when-frozen.patch | 21 +- patches/server/RangedEntity-API.patch | 10 +- .../Reduce-Either-Optional-allocation.patch | 0 ...e-memory-footprint-of-NBTTagCompound.patch | 27 +-- .../Remove-streams-from-Mob-AI-System.patch | 153 +++++------- .../Remove-streams-from-PairedQueue.patch | 45 +--- ...-teleport-command-to-valid-locations.patch | 0 ...PickItem-Packet-and-kick-for-invalid.patch | 14 +- .../Villager-Restocks-API.patch | 4 +- settings.gradle.kts | 2 +- work/Bukkit | 2 +- work/CraftBukkit | 2 +- 52 files changed, 426 insertions(+), 981 deletions(-) create mode 100644 Paper-MojangAPI/build.gradle.kts rename patches/{api-unmapped => api}/Add-Player-Client-Options-API.patch (100%) rename patches/{api-unmapped => api}/Add-PlayerAttackEntityCooldownResetEvent.patch (100%) rename patches/{api-unmapped => api}/Add-Raw-Byte-ItemStack-Serialization.patch (100%) rename patches/{api-unmapped => api}/Add-tick-times-API.patch (100%) rename patches/{api-unmapped => api}/Disable-Sync-Events-firing-Async-errors-during-shutd.patch (100%) rename patches/{api-unmapped => api}/Expose-MinecraftServer-isRunning.patch (100%) rename patches/{api-unmapped => api}/Expose-game-version.patch (100%) rename patches/{api-unmapped => api}/Fix-Potion-toItemStack-swapping-the-extended-and-upg.patch (100%) rename patches/{api-unmapped => api}/Make-JavaPluginLoader-thread-safe.patch (100%) rename patches/{api-unmapped => api}/Villager-Restocks-API.patch (100%) delete mode 100644 patches/server-remapped/Delay-unsafe-actions-until-after-entity-ticking-is-d.patch delete mode 100644 patches/server-remapped/Optimize-ChunkProviderServer-s-chunk-level-checking-.patch delete mode 100644 patches/server-remapped/Optimize-Voxel-Shape-Merging.patch rename patches/{server-remapped => server}/Add-PlayerAttackEntityCooldownResetEvent.patch (100%) rename patches/{server-remapped => server}/Add-Raw-Byte-ItemStack-Serialization.patch (50%) rename patches/{server-remapped => server}/Add-phantom-creative-and-insomniac-controls.patch (78%) rename patches/{server-remapped => server}/Add-tick-times-API-and-mspt-command.patch (96%) rename patches/{server-remapped => server}/Allow-multiple-callbacks-to-schedule-for-Callback-Ex.patch (69%) rename patches/{server-remapped => server}/Async-command-map-building.patch (100%) rename patches/{server-remapped => server}/Broadcast-join-message-to-console.patch (77%) rename patches/{server-remapped => server}/Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch (100%) rename patches/{server-remapped => server}/Don-t-fire-BlockFade-on-worldgen-threads.patch (94%) rename patches/{server-remapped => server}/Don-t-run-entity-collision-code-if-not-needed.patch (91%) rename patches/{server-remapped => server}/Expose-MinecraftServer-isRunning.patch (100%) rename patches/{server-remapped => server}/Expose-game-version.patch (96%) rename patches/{server-remapped => server}/Fix-Chunk-Post-Processing-deadlock-risk.patch (98%) rename patches/{server-remapped => server}/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch (69%) rename patches/{server-remapped => server}/Fix-numerous-item-duplication-issues-and-teleport-is.patch (96%) rename patches/{server-remapped => server}/Implement-Brigadier-Mojang-API.patch (92%) rename patches/{server-remapped => server}/Implement-Player-Client-Options-API.patch (54%) rename patches/{server-remapped => server}/Improved-Watchdog-Support.patch (89%) rename patches/{server-remapped => server}/Load-Chunks-for-Login-Asynchronously.patch (50%) rename patches/{server-remapped => server}/Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch (90%) rename patches/{server-remapped => server}/Optimise-ArraySetSorted-removeIf.patch (66%) rename patches/{server-remapped => server}/Optimize-Pathfinding.patch (56%) create mode 100644 patches/server/Optimize-Voxel-Shape-Merging.patch rename patches/{server-remapped => server}/Prevent-opening-inventories-when-frozen.patch (84%) rename patches/{server-remapped => server}/Reduce-Either-Optional-allocation.patch (100%) rename patches/{server-remapped => server}/Reduce-memory-footprint-of-NBTTagCompound.patch (60%) rename patches/{server-remapped => server}/Remove-streams-from-Mob-AI-System.patch (62%) rename patches/{server-remapped => server}/Remove-streams-from-PairedQueue.patch (52%) rename patches/{server-remapped => server}/Restrict-vanilla-teleport-command-to-valid-locations.patch (100%) rename patches/{server-remapped => server}/Validate-PickItem-Packet-and-kick-for-invalid.patch (74%) rename patches/{server-remapped => server}/Villager-Restocks-API.patch (68%) 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/Add-BlockSoundGroup-interface.patch b/patches/api/Add-BlockSoundGroup-interface.patch index faaab62a92..8387646011 100644 --- a/patches/api/Add-BlockSoundGroup-interface.patch +++ b/patches/api/Add-BlockSoundGroup-interface.patch @@ -67,18 +67,10 @@ diff --git a/src/main/java/org/bukkit/block/Block.java b/src/main/java/org/bukki index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/block/Block.java +++ b/src/main/java/org/bukkit/block/Block.java -@@ -0,0 +0,0 @@ - package org.bukkit.block; - - import java.util.Collection; -+ - import org.bukkit.Chunk; - import org.bukkit.FluidCollisionMode; - import org.bukkit.Location; @@ -0,0 +0,0 @@ public interface Block extends Metadatable { */ @NotNull - BoundingBox getBoundingBox(); + VoxelShape getCollisionShape(); + + // Paper start + /** diff --git a/patches/api-unmapped/Add-Player-Client-Options-API.patch b/patches/api/Add-Player-Client-Options-API.patch similarity index 100% rename from patches/api-unmapped/Add-Player-Client-Options-API.patch rename to patches/api/Add-Player-Client-Options-API.patch diff --git a/patches/api-unmapped/Add-PlayerAttackEntityCooldownResetEvent.patch b/patches/api/Add-PlayerAttackEntityCooldownResetEvent.patch similarity index 100% rename from patches/api-unmapped/Add-PlayerAttackEntityCooldownResetEvent.patch rename to patches/api/Add-PlayerAttackEntityCooldownResetEvent.patch diff --git a/patches/api-unmapped/Add-Raw-Byte-ItemStack-Serialization.patch b/patches/api/Add-Raw-Byte-ItemStack-Serialization.patch similarity index 100% rename from patches/api-unmapped/Add-Raw-Byte-ItemStack-Serialization.patch rename to patches/api/Add-Raw-Byte-ItemStack-Serialization.patch diff --git a/patches/api-unmapped/Add-tick-times-API.patch b/patches/api/Add-tick-times-API.patch similarity index 100% rename from patches/api-unmapped/Add-tick-times-API.patch rename to patches/api/Add-tick-times-API.patch diff --git a/patches/api-unmapped/Disable-Sync-Events-firing-Async-errors-during-shutd.patch b/patches/api/Disable-Sync-Events-firing-Async-errors-during-shutd.patch similarity index 100% rename from patches/api-unmapped/Disable-Sync-Events-firing-Async-errors-during-shutd.patch rename to patches/api/Disable-Sync-Events-firing-Async-errors-during-shutd.patch diff --git a/patches/api-unmapped/Expose-MinecraftServer-isRunning.patch b/patches/api/Expose-MinecraftServer-isRunning.patch similarity index 100% rename from patches/api-unmapped/Expose-MinecraftServer-isRunning.patch rename to patches/api/Expose-MinecraftServer-isRunning.patch diff --git a/patches/api-unmapped/Expose-game-version.patch b/patches/api/Expose-game-version.patch similarity index 100% rename from patches/api-unmapped/Expose-game-version.patch rename to patches/api/Expose-game-version.patch diff --git a/patches/api-unmapped/Fix-Potion-toItemStack-swapping-the-extended-and-upg.patch b/patches/api/Fix-Potion-toItemStack-swapping-the-extended-and-upg.patch similarity index 100% rename from patches/api-unmapped/Fix-Potion-toItemStack-swapping-the-extended-and-upg.patch rename to patches/api/Fix-Potion-toItemStack-swapping-the-extended-and-upg.patch diff --git a/patches/api-unmapped/Make-JavaPluginLoader-thread-safe.patch b/patches/api/Make-JavaPluginLoader-thread-safe.patch similarity index 100% rename from patches/api-unmapped/Make-JavaPluginLoader-thread-safe.patch rename to patches/api/Make-JavaPluginLoader-thread-safe.patch diff --git a/patches/api/RangedEntity-API.patch b/patches/api/RangedEntity-API.patch index 333c8810a5..1f1222a73f 100644 --- a/patches/api/RangedEntity-API.patch +++ b/patches/api/RangedEntity-API.patch @@ -126,19 +126,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/bukkit/entity/Skeleton.java +++ b/src/main/java/org/bukkit/entity/Skeleton.java @@ -0,0 +0,0 @@ package org.bukkit.entity; - - import org.jetbrains.annotations.Contract; - import org.jetbrains.annotations.NotNull; -+import com.destroystokyo.paper.entity.RangedEntity; - - /** - * Represents a Skeleton. + * 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/entity/Snowman.java diff --git a/patches/api-unmapped/Villager-Restocks-API.patch b/patches/api/Villager-Restocks-API.patch similarity index 100% rename from patches/api-unmapped/Villager-Restocks-API.patch rename to patches/api/Villager-Restocks-API.patch diff --git a/patches/server-remapped/Delay-unsafe-actions-until-after-entity-ticking-is-d.patch b/patches/server-remapped/Delay-unsafe-actions-until-after-entity-ticking-is-d.patch deleted file mode 100644 index 415b4257b7..0000000000 --- a/patches/server-remapped/Delay-unsafe-actions-until-after-entity-ticking-is-d.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Sat, 11 Apr 2020 21:23:42 -0400 -Subject: [PATCH] Delay unsafe actions until after entity ticking is done - -This will help prevent many cases of unregistering entities during entity ticking - -diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/level/ServerLevel.java -+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl - public final List players = Lists.newArrayList(); // Paper - private -> public - public final ServerChunkCache chunkSource; // Paper - public - boolean tickingEntities; -+ // Paper start -+ List afterEntityTickingTasks = Lists.newArrayList(); -+ public void doIfNotEntityTicking(java.lang.Runnable run) { -+ if (tickingEntities) { -+ afterEntityTickingTasks.add(run); -+ } else { -+ run.run(); -+ } -+ } -+ // Paper end - private final MinecraftServer server; - public final PrimaryLevelData worldDataServer; // CraftBukkit - type - public boolean noSave; -@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl - timings.entityTick.stopTiming(); // Spigot - - this.tickingEntities = false; -+ // Paper start -+ for (java.lang.Runnable run : this.afterEntityTickingTasks) { -+ try { -+ run.run(); -+ } catch (Exception e) { -+ LOGGER.error("Error in After Entity Ticking Task", e); -+ } -+ } -+ this.afterEntityTickingTasks.clear(); -+ // Paper end - this.getServer().midTickLoadChunks(); // Paper - - Entity entity2; diff --git a/patches/server-remapped/Optimize-ChunkProviderServer-s-chunk-level-checking-.patch b/patches/server-remapped/Optimize-ChunkProviderServer-s-chunk-level-checking-.patch deleted file mode 100644 index 129a63f004..0000000000 --- a/patches/server-remapped/Optimize-ChunkProviderServer-s-chunk-level-checking-.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Thu, 16 Apr 2020 16:13:59 -0700 -Subject: [PATCH] Optimize ChunkProviderServer's chunk level checking helper - methods - -These can be hot functions (i.e entity ticking and block ticking), -so inline where possible, and avoid the abstraction of the -Either class. - -diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java -+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -0,0 +0,0 @@ import net.minecraft.network.protocol.Packet; - import net.minecraft.server.MCUtil; - import net.minecraft.server.MinecraftServer; - import net.minecraft.server.level.progress.ChunkProgressListener; --import net.minecraft.util.Mth; - import net.minecraft.util.profiling.ProfilerFiller; - import net.minecraft.util.thread.BlockableEventLoop; - import net.minecraft.world.entity.Entity; -@@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource { - - public final boolean isInEntityTickingChunk(Entity entity) { return this.isEntityTickingChunk(entity); } // Paper - OBFHELPER - @Override public boolean isEntityTickingChunk(Entity entity) { -- long i = ChunkPos.asLong(Mth.floor(entity.getX()) >> 4, Mth.floor(entity.getZ()) >> 4); -- -- return this.checkChunkFuture(i, (Function>>) ChunkHolder::getEntityTickingChunkFuture); // CraftBukkit - decompile error -+ // Paper start - optimize is ticking ready type functions -+ // entity ticking -+ ChunkHolder playerChunk = this.getVisibleChunkIfPresent(MCUtil.getCoordinateKey(entity)); -+ return playerChunk != null && playerChunk.isEntityTickingReady(); -+ // Paper end - optimize is ticking ready type functions - } - - public final boolean isEntityTickingChunk(ChunkPos chunkcoordintpair) { return this.isEntityTickingChunk(chunkcoordintpair); } // Paper - OBFHELPER - @Override public boolean isEntityTickingChunk(ChunkPos pos) { -- return this.checkChunkFuture(pos.toLong(), (Function>>) ChunkHolder::getEntityTickingChunkFuture); // CraftBukkit - decompile error -+ // Paper start - optimize is ticking ready type functions -+ // is entity ticking ready -+ ChunkHolder playerChunk = this.getVisibleChunkIfPresent(MCUtil.getCoordinateKey(pos)); -+ return playerChunk != null && playerChunk.isEntityTickingReady(); -+ // Paper end - optimize is ticking ready type functions - } - - @Override - public boolean isTickingChunk(BlockPos pos) { -- long i = ChunkPos.asLong(pos.getX() >> 4, pos.getZ() >> 4); -- -- return this.checkChunkFuture(i, (Function>>) ChunkHolder::getTickingChunkFuture); // CraftBukkit - decompile error -+ // Paper start - optimize is ticking ready type functions -+ // is ticking ready -+ ChunkHolder playerChunk = this.getVisibleChunkIfPresent(MCUtil.getCoordinateKey(pos)); -+ return playerChunk != null && playerChunk.isTickingReady(); -+ // Paper end - optimize is ticking ready type functions - } - - private boolean checkChunkFuture(long pos, Function>> futureFunction) { diff --git a/patches/server-remapped/Optimize-Voxel-Shape-Merging.patch b/patches/server-remapped/Optimize-Voxel-Shape-Merging.patch deleted file mode 100644 index 2096663b39..0000000000 --- a/patches/server-remapped/Optimize-Voxel-Shape-Merging.patch +++ /dev/null @@ -1,175 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Sun, 3 May 2020 22:35:09 -0400 -Subject: [PATCH] Optimize Voxel Shape Merging - -This method shows up as super hot in profiler, and also a high "self" time. - -Upon analyzing, it appears most usages of this method fall down to the final -else statement of the nasty ternary. - -Upon even further analyzation, it appears then the majority of those have a -consistent list 1.... One with Infinity head and Tails. - -First optimization is to detect these infinite states and immediately return that -VoxelShapeMergerList so we can avoid testing the rest for most cases. - -Break the method into 2 to help the JVM promote inlining of this fast path. - -Then it was also noticed that VoxelShapeMergerList constructor is also a hotspot -with a high self time... - -Well, knowing that in most cases our list 1 is actualy the same value, it allows -us to know that with an infinite list1, the result on the merger is essentially -list2 as the final values. - -This let us analyze the 2 potential states (Infinite with 2 sources or 4 sources) -and compute a deterministic result for the MergerList values. - -Additionally, this lets us avoid even allocating new objects for this too, further -reducing memory usage. - -diff --git a/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java b/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java -+++ b/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java -@@ -0,0 +0,0 @@ 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; -@@ -0,0 +0,0 @@ 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); - -@@ -0,0 +0,0 @@ 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; -@@ -0,0 +0,0 @@ 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); - } -@@ -0,0 +0,0 @@ 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; - } -@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java -+++ b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java -@@ -0,0 +0,0 @@ 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-remapped/Add-PlayerAttackEntityCooldownResetEvent.patch b/patches/server/Add-PlayerAttackEntityCooldownResetEvent.patch similarity index 100% rename from patches/server-remapped/Add-PlayerAttackEntityCooldownResetEvent.patch rename to patches/server/Add-PlayerAttackEntityCooldownResetEvent.patch diff --git a/patches/server-remapped/Add-Raw-Byte-ItemStack-Serialization.patch b/patches/server/Add-Raw-Byte-ItemStack-Serialization.patch similarity index 50% rename from patches/server-remapped/Add-Raw-Byte-ItemStack-Serialization.patch rename to patches/server/Add-Raw-Byte-ItemStack-Serialization.patch index 9d323ed9ab..6f285725c8 100644 --- a/patches/server-remapped/Add-Raw-Byte-ItemStack-Serialization.patch +++ b/patches/server/Add-Raw-Byte-ItemStack-Serialization.patch @@ -5,50 +5,6 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/nbt/NbtIo.java -+++ b/src/main/java/net/minecraft/nbt/NbtIo.java -@@ -0,0 +0,0 @@ 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; -@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/util/datafix/DataFixers.java -+++ b/src/main/java/net/minecraft/util/datafix/DataFixers.java -@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/world/item/ItemStack.java -+++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -67,7 +23,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + CompoundTag compound = (item instanceof CraftItemStack ? ((CraftItemStack) item).getHandle() : CraftItemStack.asNMSCopy(item)).save(new CompoundTag()); + compound.putInt("DataVersion", getDataVersion()); + try { -+ net.minecraft.nbt.NbtIo.writeNBT( ++ net.minecraft.nbt.NbtIo.writeCompressed( + compound, + outputStream + ); @@ -84,14 +40,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + Preconditions.checkArgument(data.length > 0, "cannot deserialize nothing"); + + try { -+ CompoundTag compound = net.minecraft.nbt.NbtIo.readNBT( ++ CompoundTag compound = net.minecraft.nbt.NbtIo.readCompressed( + new java.io.ByteArrayInputStream(data) + ); + int dataVersion = compound.getInt("DataVersion"); + + Preconditions.checkArgument(dataVersion <= getDataVersion(), "Newer version! Server downgrades are not supported!"); + Dynamic converted = DataFixers.getDataFixer().update(References.ITEM_STACK, new Dynamic(NbtOps.INSTANCE, compound), dataVersion, getDataVersion()); -+ return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.fromCompound((CompoundTag) converted.getValue())); ++ 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(); diff --git a/patches/server-remapped/Add-phantom-creative-and-insomniac-controls.patch b/patches/server/Add-phantom-creative-and-insomniac-controls.patch similarity index 78% rename from patches/server-remapped/Add-phantom-creative-and-insomniac-controls.patch rename to patches/server/Add-phantom-creative-and-insomniac-controls.patch index dcb6f63129..5a435e25ac 100644 --- a/patches/server-remapped/Add-phantom-creative-and-insomniac-controls.patch +++ b/patches/server/Add-phantom-creative-and-insomniac-controls.patch @@ -9,44 +9,31 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java @@ -0,0 +0,0 @@ public class PaperWorldConfig { - private void lightQueueSize() { 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/EntitySelector.java +++ b/src/main/java/net/minecraft/world/entity/EntitySelector.java -@@ -0,0 +0,0 @@ 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; @@ -0,0 +0,0 @@ public final class EntitySelector { public static final Predicate NO_SPECTATORS = (entity) -> { return !entity.isSpectator(); }; -+ public static Predicate isInsomniac = (player) -> Mth.clamp(((ServerPlayer) player).getStats().getValue(Stats.CUSTOM.get(Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= 72000; // Paper ++ public static Predicate isInsomniac = (player) -> net.minecraft.util.Mth.clamp(((net.minecraft.server.level.ServerPlayer) player).getStats().getValue(net.minecraft.stats.Stats.CUSTOM.get(net.minecraft.stats.Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= 72000; // Paper + private EntitySelector() {} // Paper start - public static final Predicate affectsSpawning = (entity) -> { -- return !entity.isSpectator() && entity.isAlive() && (entity instanceof EntityPlayer) && ((EntityPlayer) entity).affectsSpawning; -+ return !entity.isSpectator() && entity.isAlive() && (entity instanceof ServerPlayer) && ((ServerPlayer) entity).affectsSpawning; - }; - // Paper end - diff --git a/src/main/java/net/minecraft/world/entity/monster/Phantom.java b/src/main/java/net/minecraft/world/entity/monster/Phantom.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java diff --git a/patches/server-remapped/Add-tick-times-API-and-mspt-command.patch b/patches/server/Add-tick-times-API-and-mspt-command.patch similarity index 96% rename from patches/server-remapped/Add-tick-times-API-and-mspt-command.patch rename to patches/server/Add-tick-times-API-and-mspt-command.patch index ff61b5673e..7ec40a9845 100644 --- a/patches/server-remapped/Add-tick-times-API-and-mspt-command.patch +++ b/patches/server/Add-tick-times-API-and-mspt-command.patch @@ -91,9 +91,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop queue = new java.util.ArrayDeque<>(); + // Paper start - replace impl with recursive safe multi entry queue + // it's possible to schedule multiple tasks currently, so it's vital we change this impl + // If we recurse into the executor again, we will append to another queue, ensuring task order consistency -+ private java.util.ArrayDeque queued = new java.util.ArrayDeque<>(); ++ private java.util.Queue queue = new java.util.ArrayDeque<>(); // Paper - remove final @Override public void execute(Runnable runnable) { -- if (queued != null) { -- throw new IllegalStateException("Already queued"); -+ if (queued == null) { -+ queued = new java.util.ArrayDeque<>(); - } -- queued = runnable; -+ queued.add(runnable); ++ if (this.queue == null) { ++ this.queue = new java.util.ArrayDeque<>(); ++ } + this.queue.add(runnable); } @Override public void run() { -- Runnable task = queued; -+ if (queued == null) { ++ if (this.queue == null) { + return; + } -+ java.util.ArrayDeque queue = queued; - queued = null; -- if (task != null) { -+ Runnable task; -+ while ((task = queue.pollFirst()) != null) { ++ java.util.Queue queue = this.queue; ++ this.queue = null; ++ // Paper end + Runnable task; + while ((task = this.queue.poll()) != null) { task.run(); - } - } -+ // Paper end - }; - // CraftBukkit end - diff --git a/patches/server-remapped/Async-command-map-building.patch b/patches/server/Async-command-map-building.patch similarity index 100% rename from patches/server-remapped/Async-command-map-building.patch rename to patches/server/Async-command-map-building.patch diff --git a/patches/server-remapped/Broadcast-join-message-to-console.patch b/patches/server/Broadcast-join-message-to-console.patch similarity index 77% rename from patches/server-remapped/Broadcast-join-message-to-console.patch rename to patches/server/Broadcast-join-message-to-console.patch index ba4e35c99a..64ff11a0b7 100644 --- a/patches/server-remapped/Broadcast-join-message-to-console.patch +++ b/patches/server/Broadcast-join-message-to-console.patch @@ -12,9 +12,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 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/Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch b/patches/server/Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch similarity index 100% rename from patches/server-remapped/Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch rename to patches/server/Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch diff --git a/patches/server-remapped/Don-t-fire-BlockFade-on-worldgen-threads.patch b/patches/server/Don-t-fire-BlockFade-on-worldgen-threads.patch similarity index 94% rename from patches/server-remapped/Don-t-fire-BlockFade-on-worldgen-threads.patch rename to patches/server/Don-t-fire-BlockFade-on-worldgen-threads.patch index b0d6c018f8..15a2e801cf 100644 --- a/patches/server-remapped/Don-t-fire-BlockFade-on-worldgen-threads.patch +++ b/patches/server/Don-t-fire-BlockFade-on-worldgen-threads.patch @@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/world/level/block/FireBlock.java @@ -0,0 +0,0 @@ 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)) { diff --git a/patches/server-remapped/Don-t-run-entity-collision-code-if-not-needed.patch b/patches/server/Don-t-run-entity-collision-code-if-not-needed.patch similarity index 91% rename from patches/server-remapped/Don-t-run-entity-collision-code-if-not-needed.patch rename to patches/server/Don-t-run-entity-collision-code-if-not-needed.patch index 710cd63503..ac2b692c1a 100644 --- a/patches/server-remapped/Don-t-run-entity-collision-code-if-not-needed.patch +++ b/patches/server/Don-t-run-entity-collision-code-if-not-needed.patch @@ -14,12 +14,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 protected void serverAiStep() {} protected void pushEntities() { -+ // Paper - start don't run getEntities if we're not going to use its result ++ // Paper start - don't run getEntities if we're not going to use its result + int i = this.level.getGameRules().getInt(GameRules.RULE_MAX_ENTITY_CRAMMING); + if (i <= 0 && level.paperConfig.maxCollisionsPerEntity <= 0) { + return; + } -+ // Paper - end don't run getEntities if we're not going to use its result ++ // Paper end - don't run getEntities if we're not going to use its result List list = this.level.getEntities(this, this.getBoundingBox(), EntitySelector.pushableBy(this)); if (!list.isEmpty()) { diff --git a/patches/server-remapped/Expose-MinecraftServer-isRunning.patch b/patches/server/Expose-MinecraftServer-isRunning.patch similarity index 100% rename from patches/server-remapped/Expose-MinecraftServer-isRunning.patch rename to patches/server/Expose-MinecraftServer-isRunning.patch diff --git a/patches/server-remapped/Expose-game-version.patch b/patches/server/Expose-game-version.patch similarity index 96% rename from patches/server-remapped/Expose-game-version.patch rename to patches/server/Expose-game-version.patch index 8c944311ac..4203a49b18 100644 --- a/patches/server-remapped/Expose-game-version.patch +++ b/patches/server/Expose-game-version.patch @@ -9,7 +9,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -0,0 +0,0 @@ public final class CraftServer implements Server { - return bukkitVersion; + return this.bukkitVersion; } + // Paper start - expose game version diff --git a/patches/server-remapped/Fix-Chunk-Post-Processing-deadlock-risk.patch b/patches/server/Fix-Chunk-Post-Processing-deadlock-risk.patch similarity index 98% rename from patches/server-remapped/Fix-Chunk-Post-Processing-deadlock-risk.patch rename to patches/server/Fix-Chunk-Post-Processing-deadlock-risk.patch index 6a56bf0334..5d0905388f 100644 --- a/patches/server-remapped/Fix-Chunk-Post-Processing-deadlock-risk.patch +++ b/patches/server/Fix-Chunk-Post-Processing-deadlock-risk.patch @@ -33,10 +33,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // CraftBukkit end + final CallbackExecutor chunkLoadConversionCallbackExecutor = new CallbackExecutor(); // Paper -+ // Paper start - distance maps private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>(); - + // Paper start - no-tick view distance @@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider return Either.left(chunk); }); diff --git a/patches/server-remapped/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch b/patches/server/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch similarity index 69% rename from patches/server-remapped/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch rename to patches/server/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch index 4061f7ee3d..bdd7bd5469 100644 --- a/patches/server-remapped/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch +++ b/patches/server/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch @@ -32,7 +32,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - }); + // Paper end - per player view distance } - protected void addEntity(Entity entity) { @@ -52,7 +52,7 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/ma index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener { +@@ -0,0 +0,0 @@ public class ServerPlayer extends Player { public double maxHealthCache; public boolean joining = true; public boolean sentListPacket = false; @@ -75,8 +75,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + 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); + PlayerJoinEvent playerJoinEvent = new org.bukkit.event.player.PlayerJoinEvent(this.cserver.getPlayer(player), PaperAdventure.asAdventure(chatmessage)); // Paper - Adventure + this.cserver.getPluginManager().callEvent(playerJoinEvent); @@ -0,0 +0,0 @@ public abstract class PlayerList { player.connection.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, new ServerPlayer[] { entityplayer1})); } @@ -93,57 +93,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // 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 -@@ -0,0 +0,0 @@ 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(); @@ -0,0 +0,0 @@ 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); +@@ -0,0 +0,0 @@ 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-remapped/Fix-numerous-item-duplication-issues-and-teleport-is.patch b/patches/server/Fix-numerous-item-duplication-issues-and-teleport-is.patch similarity index 96% rename from patches/server-remapped/Fix-numerous-item-duplication-issues-and-teleport-is.patch rename to patches/server/Fix-numerous-item-duplication-issues-and-teleport-is.patch index c667385d32..ec34effcbe 100644 --- a/patches/server-remapped/Fix-numerous-item-duplication-issues-and-teleport-is.patch +++ b/patches/server/Fix-numerous-item-duplication-issues-and-teleport-is.patch @@ -19,7 +19,7 @@ diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/jav index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s +@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..00000000000000000000000000000000 entityitem.setDefaultPickUpDelay(); // CraftBukkit start -@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s +@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n @Nullable public Entity teleportTo(ServerLevel worldserver, BlockPos location) { // CraftBukkit end @@ -44,10 +44,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + 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 -@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s +@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n // CraftBukkit end this.level.getProfiler().popPush("reloading"); @@ -59,7 +59,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 Entity entity = this.getType().create((Level) worldserver); if (entity != null) { -@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s +@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..00000000000000000000000000000000 // CraftBukkit end } -@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s +@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n } public boolean canChangeDimensions() { diff --git a/patches/server-remapped/Implement-Brigadier-Mojang-API.patch b/patches/server/Implement-Brigadier-Mojang-API.patch similarity index 92% rename from patches/server-remapped/Implement-Brigadier-Mojang-API.patch rename to patches/server/Implement-Brigadier-Mojang-API.patch index bfaa0c63a9..42ad6c4c98 100644 --- a/patches/server-remapped/Implement-Brigadier-Mojang-API.patch +++ b/patches/server/Implement-Brigadier-Mojang-API.patch @@ -9,6 +9,18 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/build.gradle.kts ++++ b/build.gradle.kts +@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/commands/CommandSourceStack.java @@ -72,14 +84,14 @@ diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListener index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener { +@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser ParseResults parseresults = this.server.getCommands().getDispatcher().parse(stringreader, this.player.createCommandSourceStack()); this.server.getCommands().getDispatcher().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> { - if (suggestions.isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [] from showing for plugins with nothing more to offer - this.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), suggestions)); + // Paper start -+ com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getPlayer(), suggestions, buffer); ++ com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getCraftPlayer(), suggestions, buffer); + suggestEvent.setCancelled(suggestions.isEmpty()); + if (!suggestEvent.callEvent()) return; + this.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), (com.mojang.brigadier.suggestion.Suggestions) suggestEvent.getSuggestions())); // CraftBukkit - decompile error // Paper @@ -87,13 +99,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 }); }); } -@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener { +@@ -0,0 +0,0 @@ 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())); diff --git a/patches/server/Implement-CraftBlockSoundGroup.patch b/patches/server/Implement-CraftBlockSoundGroup.patch index 8d8af13bb3..2c8884a072 100644 --- a/patches/server/Implement-CraftBlockSoundGroup.patch +++ b/patches/server/Implement-CraftBlockSoundGroup.patch @@ -53,10 +53,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java @@ -0,0 +0,0 @@ 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); + 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-remapped/Implement-Player-Client-Options-API.patch b/patches/server/Implement-Player-Client-Options-API.patch similarity index 54% rename from patches/server-remapped/Implement-Player-Client-Options-API.patch rename to patches/server/Implement-Player-Client-Options-API.patch index a9556ad16f..4b60795440 100644 --- a/patches/server-remapped/Implement-Player-Client-Options-API.patch +++ b/patches/server/Implement-Player-Client-Options-API.patch @@ -84,67 +84,28 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + .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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/network/protocol/game/ServerboundClientInformationPacket.java -+++ b/src/main/java/net/minecraft/network/protocol/game/ServerboundClientInformationPacket.java -@@ -0,0 +0,0 @@ public class ServerboundClientInformationPacket implements Packet POSES = ImmutableMap.builder().put(Pose.STANDING, Player.STANDING_DIMENSIONS).put(Pose.SLEEPING, Player.SLEEPING_DIMENSIONS).put(Pose.FALL_FLYING, EntityDimensions.scalable(0.6F, 0.6F)).put(Pose.SWIMMING, EntityDimensions.scalable(0.6F, 0.6F)).put(Pose.SPIN_ATTACK, EntityDimensions.scalable(0.6F, 0.6F)).put(Pose.CROUCHING, EntityDimensions.scalable(0.6F, 1.5F)).put(Pose.DYING, EntityDimensions.fixed(0.2F, 0.2F)).build(); + private static final int FLY_ACHIEVEMENT_SPEED = 25; private static final EntityDataAccessor DATA_PLAYER_ABSORPTION_ID = SynchedEntityData.defineId(Player.class, EntityDataSerializers.FLOAT); private static final EntityDataAccessor DATA_SCORE_ID = SynchedEntityData.defineId(Player.class, EntityDataSerializers.INT); - protected static final EntityDataAccessor DATA_PLAYER_MODE_CUSTOMISATION = SynchedEntityData.defineId(Player.class, EntityDataSerializers.BYTE); -+ protected static final EntityDataAccessor DATA_PLAYER_MODE_CUSTOMISATION = SynchedEntityData.defineId(Player.class, EntityDataSerializers.BYTE); public static EntityDataAccessor getSkinPartsWatcher() { return DATA_PLAYER_MODE_CUSTOMISATION; } // Paper - OBFHELPER ++ public static final EntityDataAccessor DATA_PLAYER_MODE_CUSTOMISATION = SynchedEntityData.defineId(Player.class, EntityDataSerializers.BYTE); // Paper - protected -> public protected static final EntityDataAccessor DATA_PLAYER_MAIN_HAND = SynchedEntityData.defineId(Player.class, EntityDataSerializers.BYTE); protected static final EntityDataAccessor DATA_SHOULDER_LEFT = SynchedEntityData.defineId(Player.class, EntityDataSerializers.COMPOUND_TAG); protected static final EntityDataAccessor DATA_SHOULDER_RIGHT = SynchedEntityData.defineId(Player.class, EntityDataSerializers.COMPOUND_TAG); @@ -152,37 +113,28 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/ index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -0,0 +0,0 @@ - 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; @@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player { public void setViewDistance(int viewDistance) { throw new NotImplementedException("Per-Player View Distance APIs need further understanding to properly implement (There are per world view distances though!)"); // TODO } + + @Override -+ public T getClientOption(ClientOption type) { -+ if(ClientOption.SKIN_PARTS.equals(type)) { -+ return type.getType().cast(new PaperSkinParts(getHandle().getEntityData().get(net.minecraft.world.entity.player.Player.getSkinPartsWatcher()))); -+ } else if(ClientOption.CHAT_COLORS_ENABLED.equals(type)) { -+ return type.getType().cast(getHandle().hasChatColorsEnabled()); -+ } else if(ClientOption.CHAT_VISIBILITY.equals(type)) { -+ return type.getType().cast(getHandle().getChatVisibility() == null ? ChatVisibility.UNKNOWN : ChatVisibility.valueOf(getHandle().getChatVisibility().name())); -+ } else if(ClientOption.LOCALE.equals(type)) { ++ public T getClientOption(com.destroystokyo.paper.ClientOption type) { ++ if(com.destroystokyo.paper.ClientOption.SKIN_PARTS.equals(type)) { ++ return type.getType().cast(new com.destroystokyo.paper.PaperSkinParts(getHandle().getEntityData().get(net.minecraft.world.entity.player.Player.DATA_PLAYER_MODE_CUSTOMISATION))); ++ } else if(com.destroystokyo.paper.ClientOption.CHAT_COLORS_ENABLED.equals(type)) { ++ return type.getType().cast(getHandle().canChatInColor()); ++ } else if(com.destroystokyo.paper.ClientOption.CHAT_VISIBILITY.equals(type)) { ++ return type.getType().cast(getHandle().getChatVisibility() == null ? com.destroystokyo.paper.ClientOption.ChatVisibility.UNKNOWN : com.destroystokyo.paper.ClientOption.ChatVisibility.valueOf(getHandle().getChatVisibility().name())); ++ } else if(com.destroystokyo.paper.ClientOption.LOCALE.equals(type)) { + return type.getType().cast(getLocale()); -+ } else if(ClientOption.MAIN_HAND.equals(type)) { ++ } else if(com.destroystokyo.paper.ClientOption.MAIN_HAND.equals(type)) { + return type.getType().cast(getMainHand()); -+ } else if(ClientOption.VIEW_DISTANCE.equals(type)) { ++ } else if(com.destroystokyo.paper.ClientOption.VIEW_DISTANCE.equals(type)) { + return type.getType().cast(getClientViewDistance()); + } + throw new RuntimeException("Unknown settings type"); + } // Paper end - // Spigot start + @Override diff --git a/patches/server-remapped/Improved-Watchdog-Support.patch b/patches/server/Improved-Watchdog-Support.patch similarity index 89% rename from patches/server-remapped/Improved-Watchdog-Support.patch rename to patches/server/Improved-Watchdog-Support.patch index fe71dfdfab..d233b0265f 100644 --- a/patches/server-remapped/Improved-Watchdog-Support.patch +++ b/patches/server/Improved-Watchdog-Support.patch @@ -70,25 +70,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/Util.java -+++ b/src/main/java/net/minecraft/Util.java -@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); public int autosavePeriod; - public boolean serverAutoSave = false; // Paper public Commands vanillaCommandDispatcher; - private boolean forceTicks; + public boolean forceTicks; // Paper @@ -112,10 +100,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public volatile boolean hasFullyShutdown = false; // Paper private final Object stopLock = new Object(); public final boolean hasStopped() { - synchronized (stopLock) { + synchronized (this.stopLock) { @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { -+ world.tickingEntities = false; -+ }); + } + // Paper end // CraftBukkit end MinecraftServer.LOGGER.info("Stopping server"); MinecraftTimings.stopServer(); // Paper @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { CompletableFuture completablefuture; -diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/level/ServerLevel.java -+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl - private final Queue toAddAfterTick = Queues.newArrayDeque(); - public final List players = Lists.newArrayList(); // Paper - private -> public - public final ServerChunkCache chunkSource; // Paper - public -- boolean tickingEntities; -+ public boolean tickingEntities; // Paper - expose for watchdog - // Paper start - List afterEntityTickingTasks = Lists.newArrayList(); - public void doIfNotEntityTicking(java.lang.Runnable run) { diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -0,0 +0,0 @@ public abstract class PlayerList { - cserver.getPluginManager().callEvent(playerQuitEvent); + this.cserver.getPluginManager().callEvent(playerQuitEvent); entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage()); - entityplayer.doTick(); // SPIGOT-924 @@ -319,26 +290,18 @@ diff --git a/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java b/s index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java +++ b/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java -@@ -0,0 +0,0 @@ public abstract class BlockableEventLoop implements Processo +@@ -0,0 +0,0 @@ public abstract class BlockableEventLoop implements Profiler try { task.run(); - } catch (Exception exception) { -+ if (exception.getCause() instanceof ThreadDeath) throw exception; // Paper - BlockableEventLoop.LOGGER.fatal("Error executing task on {}", this.name(), exception); + } catch (Exception var3) { ++ if (var3.getCause() instanceof ThreadDeath) throw var3; // Paper + LOGGER.fatal("Error executing task on {}", this.name(), var3); } diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -0,0 +0,0 @@ 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); @@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable { try { tickConsumer.accept(entity); @@ -347,6 +310,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java ++++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -496,7 +471,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 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(); @@ -535,19 +510,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private boolean restart; @@ -0,0 +0,0 @@ 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 @@ -0,0 +0,0 @@ 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,9 +536,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ 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 @@ -571,7 +546,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if ( isLongTimeout ) { -- if ( restart && !MinecraftServer.getServer().hasStopped() ) +- if ( this.restart && !MinecraftServer.getServer().hasStopped() ) + if ( !server.hasStopped() ) { - RestartCommand.restart(); diff --git a/patches/server-remapped/Load-Chunks-for-Login-Asynchronously.patch b/patches/server/Load-Chunks-for-Login-Asynchronously.patch similarity index 50% rename from patches/server-remapped/Load-Chunks-for-Login-Asynchronously.patch rename to patches/server/Load-Chunks-for-Login-Asynchronously.patch index a4f5fdb836..efb3727ce7 100644 --- a/patches/server-remapped/Load-Chunks-for-Login-Asynchronously.patch +++ b/patches/server/Load-Chunks-for-Login-Asynchronously.patch @@ -4,19 +4,6 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/level/ChunkMap.java -+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - private final ProcessorHandle> worldgenMailbox; - private final ProcessorHandle> mainThreadMailbox; - public final ChunkProgressListener progressListener; -- public final ChunkMap.ChunkDistanceManager distanceManager; -+ public final ChunkMap.ChunkDistanceManager distanceManager; public final DistanceManager getChunkDistanceManager() { return this.distanceManager; } // Paper - OBFHELPER - private final AtomicInteger tickingGenerated; - public final StructureManager structureManager; // Paper - private -> public - private final File storageFolder; diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -25,8 +12,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return this.mainThreadProcessor.pollTask(); } -- private boolean runDistanceManagerUpdates() { -+ public boolean runDistanceManagerUpdates() { // Paper - private -> public +- boolean runDistanceManagerUpdates() { ++ public boolean runDistanceManagerUpdates() { // Paper - packate-private -> public boolean flag = this.distanceManager.runAllUpdates(this.chunkMap); boolean flag1 = this.chunkMap.promoteChunkMap(); @@ -34,23 +21,15 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/ma index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -0,0 +0,0 @@ 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; -@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener { - - private static final Logger LOGGER = LogManager.getLogger(); +@@ -0,0 +0,0 @@ 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 Connection networkManager; // Paper ++ public net.minecraft.network.Connection networkManager; // Paper public final MinecraftServer server; public final ServerPlayerGameMode gameMode; - public final Deque removeQueue = new ArrayDeque<>(); // Paper -@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener { + private final PlayerAdvancements advancements; +@@ -0,0 +0,0 @@ public class ServerPlayer extends Player { public boolean joining = true; public boolean sentListPacket = false; public boolean supressTrackerForLogin = false; // Paper @@ -63,26 +42,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/level/TicketType.java +++ b/src/main/java/net/minecraft/server/level/TicketType.java @@ -0,0 +0,0 @@ public class TicketType { - public static final TicketType FORCED = create("forced", Comparator.comparingLong(ChunkPos::toLong)); - public static final TicketType LIGHT = create("light", Comparator.comparingLong(ChunkPos::toLong)); - public static final TicketType PORTAL = create("portal", Vec3i::compareTo, 300); + public static final TicketType FORCED = TicketType.create("forced", Comparator.comparingLong(ChunkPos::toLong)); + public static final TicketType LIGHT = TicketType.create("light", Comparator.comparingLong(ChunkPos::toLong)); + public static final TicketType PORTAL = TicketType.create("portal", Vec3i::compareTo, 300); + public static final TicketType LOGIN = create("login", Long::compareTo, 100); // Paper - public static final TicketType POST_TELEPORT = create("post_teleport", Integer::compareTo, 5); - public static final TicketType UNKNOWN = create("unknown", Comparator.comparingLong(ChunkPos::toLong), 1); - public static final TicketType PLUGIN = create("plugin", (a, b) -> 0); // CraftBukkit + public static final TicketType POST_TELEPORT = TicketType.create("post_teleport", Integer::compareTo, 5); + public static final TicketType UNKNOWN = TicketType.create("unknown", Comparator.comparingLong(ChunkPos::toLong), 1); + public static final TicketType PLUGIN = TicketType.create("plugin", (a, b) -> 0); // CraftBukkit diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener { - private static final Logger LOGGER = LogManager.getLogger(); +@@ -0,0 +0,0 @@ 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(); private void setLastPing(long lastPing) { this.keepAliveTime = lastPing;}; private long getLastPing() { return this.keepAliveTime;}; // Paper - OBFHELPER -@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener { + private long keepAliveTime = Util.getMillis(); +@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser // CraftBukkit end public void tick() { @@ -98,7 +77,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.resetPosition(); this.player.xo = this.player.getX(); this.player.yo = this.player.getY(); -@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener { +@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser this.lastVehicle = null; this.clientVehicleIsFloating = false; this.aboveGroundVehicleTickCount = 0; @@ -127,8 +106,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - 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; + 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java @@ -140,16 +119,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +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; -@@ -0,0 +0,0 @@ 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; + import net.minecraft.network.protocol.game.ClientboundInitializeBorderPacket; @@ -0,0 +0,0 @@ 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; @@ -193,12 +163,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + 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()); ++ 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 -> { -+ ChunkHolder updatingChunk = playerChunkMap.getUpdatingChunkIfPresent(pos.toLong()); ++ net.minecraft.server.level.ChunkHolder updatingChunk = playerChunkMap.getUpdatingChunkIfPresent(pos.toLong()); + if (updatingChunk != null) { + return updatingChunk.getEntityTickingFuture(); + } else { @@ -227,126 +198,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + }); + } + -+ private void postChunkLoadJoin(ServerPlayer entityplayer, ServerLevel worldserver1, Connection networkmanager, ServerGamePacketListenerImpl playerconnection, CompoundTag nbttagcompound, String s1, String s) { -+ pendingPlayers.remove(entityplayer.getUUID(), entityplayer); ++ 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; + } -+ entityplayer.didPlayerJoinEvent = true; ++ player.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; - } - -@@ -0,0 +0,0 @@ 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 + if (player.getGameProfile().getName().equalsIgnoreCase(s)) { @@ -0,0 +0,0 @@ public abstract class PlayerList { protected void save(ServerPlayer player) { @@ -358,9 +219,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ 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 + 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) @@ -379,7 +240,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // CraftBukkit start // this.sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, new EntityPlayer[]{entityplayer})); @@ -0,0 +0,0 @@ public abstract class PlayerList { - cserver.getScoreboardManager().removePlayer(entityplayer.getBukkitEntity()); + this.cserver.getScoreboardManager().removePlayer(entityplayer.getBukkitEntity()); // CraftBukkit end - return playerQuitEvent.quitMessage(); // Paper - Adventure @@ -405,12 +266,12 @@ diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/jav index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s +@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n 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 +- 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 vec3d) { + public void moveTo(Vec3 pos) { diff --git a/patches/server-remapped/Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch b/patches/server/Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch similarity index 90% rename from patches/server-remapped/Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch rename to patches/server/Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch index 3372e5da4a..bda4803387 100644 --- a/patches/server-remapped/Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch +++ b/patches/server/Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch @@ -10,7 +10,7 @@ diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/jav index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s +@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n bworld = server.getWorld(worldName); } @@ -23,5 +23,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +// } + // 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/Optimise-ArraySetSorted-removeIf.patch b/patches/server/Optimise-ArraySetSorted-removeIf.patch similarity index 66% rename from patches/server-remapped/Optimise-ArraySetSorted-removeIf.patch rename to patches/server/Optimise-ArraySetSorted-removeIf.patch index 3b8a8fa69b..1fbcab69d8 100644 --- a/patches/server-remapped/Optimise-ArraySetSorted-removeIf.patch +++ b/patches/server/Optimise-ArraySetSorted-removeIf.patch @@ -9,27 +9,16 @@ diff --git a/src/main/java/net/minecraft/util/SortedArraySet.java b/src/main/jav index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/util/SortedArraySet.java +++ b/src/main/java/net/minecraft/util/SortedArraySet.java -@@ -0,0 +0,0 @@ import java.util.NoSuchElementException; - public class SortedArraySet extends AbstractSet { - - private final Comparator comparator; -- private T[] contents; -- private int size; -+ private T[] contents; private final T[] getBackingArray() { return this.contents; } // Paper - OBFHELPER -+ private int size; private final int getSize() { return this.size; } private final void setSize(int value) { this.size = value; } // Paper - OBFHELPER - - private SortedArraySet(int initialCapacity, Comparator comparator) { - this.comparator = comparator; @@ -0,0 +0,0 @@ public class SortedArraySet extends AbstractSet { + this.contents = (T[])castRawArray(new Object[initialCapacity]); } } - + // Paper start - optimise removeIf + @Override + public boolean removeIf(java.util.function.Predicate filter) { + // prev. impl used an iterator, which could be n^2 and creates garbage -+ int i = 0, len = this.getSize(); -+ T[] backingArray = this.getBackingArray(); ++ int i = 0, len = this.size; ++ T[] backingArray = this.contents; + + for (;;) { + if (i >= len) { @@ -55,11 +44,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + // cleanup end + Arrays.fill(backingArray, lastIndex, len, null); -+ this.setSize(lastIndex); ++ this.size = lastIndex; + return true; + } + // Paper end - optimise removeIf -+ - public static > SortedArraySet create(int initialCapacity) { - return new SortedArraySet<>(initialCapacity, (Comparator)Comparator.naturalOrder()); // Paper - decompile fix - } + + public static > SortedArraySet create() { + return create(10); diff --git a/patches/server-remapped/Optimize-Pathfinding.patch b/patches/server/Optimize-Pathfinding.patch similarity index 56% rename from patches/server-remapped/Optimize-Pathfinding.patch rename to patches/server/Optimize-Pathfinding.patch index 8a84c0048f..b73a05b281 100644 --- a/patches/server-remapped/Optimize-Pathfinding.patch +++ b/patches/server/Optimize-Pathfinding.patch @@ -10,23 +10,6 @@ diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigati index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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 -@@ -0,0 +0,0 @@ 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; -@@ -0,0 +0,0 @@ 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; @@ -0,0 +0,0 @@ public abstract class PathNavigation { return this.moveTo(this.createPath(x, y, z, 1), speed); } @@ -38,21 +21,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + 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/Optimize-Voxel-Shape-Merging.patch b/patches/server/Optimize-Voxel-Shape-Merging.patch new file mode 100644 index 0000000000..4cfb49cc32 --- /dev/null +++ b/patches/server/Optimize-Voxel-Shape-Merging.patch @@ -0,0 +1,121 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Sun, 3 May 2020 22:35:09 -0400 +Subject: [PATCH] Optimize Voxel Shape Merging + +This method shows up as super hot in profiler, and also a high "self" time. + +Upon analyzing, it appears most usages of this method fall down to the final +else statement of the nasty ternary. + +Upon even further analyzation, it appears then the majority of those have a +consistent list 1.... One with Infinity head and Tails. + +First optimization is to detect these infinite states and immediately return that +VoxelShapeMergerList so we can avoid testing the rest for most cases. + +Break the method into 2 to help the JVM promote inlining of this fast path. + +Then it was also noticed that VoxelShapeMergerList constructor is also a hotspot +with a high self time... + +Well, knowing that in most cases our list 1 is actualy the same value, it allows +us to know that with an infinite list1, the result on the merger is essentially +list2 as the final values. + +This let us analyze the 2 potential states (Infinite with 2 sources or 4 sources) +and compute a deterministic result for the MergerList values. + +Additionally, this lets us avoid even allocating new objects for this too, further +reducing memory usage. + +diff --git a/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java b/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java ++++ b/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java +@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java ++++ b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java +@@ -0,0 +0,0 @@ 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) { +@@ -0,0 +0,0 @@ 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/patches/server-remapped/Prevent-opening-inventories-when-frozen.patch b/patches/server/Prevent-opening-inventories-when-frozen.patch similarity index 84% rename from patches/server-remapped/Prevent-opening-inventories-when-frozen.patch rename to patches/server/Prevent-opening-inventories-when-frozen.patch index 2a48a713ce..802dc6eb4c 100644 --- a/patches/server-remapped/Prevent-opening-inventories-when-frozen.patch +++ b/patches/server/Prevent-opening-inventories-when-frozen.patch @@ -8,7 +8,7 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/ma index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener { +@@ -0,0 +0,0 @@ public class ServerPlayer extends Player { containerUpdateDelay = level.paperConfig.containerUpdateTickRate; } // Paper end @@ -17,24 +17,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); // Paper this.containerMenu = this.inventoryMenu; } -@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener { +@@ -0,0 +0,0 @@ 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); -@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java @@ -45,8 +36,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 //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); } @@ -0,0 +0,0 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { net.kyori.adventure.text.Component adventure$title = inventory.title(); // Paper @@ -55,5 +46,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - 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/RangedEntity-API.patch b/patches/server/RangedEntity-API.patch index 3bb292c6af..54eaf1d35b 100644 --- a/patches/server/RangedEntity-API.patch +++ b/patches/server/RangedEntity-API.patch @@ -114,14 +114,14 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java b/sr index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java -@@ -0,0 +0,0 @@ import org.bukkit.entity.EntityType; +@@ -0,0 +0,0 @@ import org.bukkit.craftbukkit.CraftServer; + import org.bukkit.entity.EntityType; import org.bukkit.entity.Skeleton; - import org.bukkit.entity.Skeleton.SkeletonType; --public class CraftSkeleton extends CraftMonster implements Skeleton { -+public class CraftSkeleton extends CraftMonster implements Skeleton, com.destroystokyo.paper.entity.CraftRangedEntity { // Paper +-public class CraftSkeleton extends CraftAbstractSkeleton implements Skeleton { ++public class CraftSkeleton extends CraftAbstractSkeleton implements Skeleton, com.destroystokyo.paper.entity.CraftRangedEntity { // Paper - public CraftSkeleton(CraftServer server, AbstractSkeleton entity) { + public CraftSkeleton(CraftServer server, net.minecraft.world.entity.monster.Skeleton entity) { super(server, entity); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/patches/server-remapped/Reduce-Either-Optional-allocation.patch b/patches/server/Reduce-Either-Optional-allocation.patch similarity index 100% rename from patches/server-remapped/Reduce-Either-Optional-allocation.patch rename to patches/server/Reduce-Either-Optional-allocation.patch diff --git a/patches/server-remapped/Reduce-memory-footprint-of-NBTTagCompound.patch b/patches/server/Reduce-memory-footprint-of-NBTTagCompound.patch similarity index 60% rename from patches/server-remapped/Reduce-memory-footprint-of-NBTTagCompound.patch rename to patches/server/Reduce-memory-footprint-of-NBTTagCompound.patch index 2857b4c372..b96a3a5c84 100644 --- a/patches/server-remapped/Reduce-memory-footprint-of-NBTTagCompound.patch +++ b/patches/server/Reduce-memory-footprint-of-NBTTagCompound.patch @@ -11,29 +11,21 @@ diff --git a/src/main/java/net/minecraft/nbt/CompoundTag.java b/src/main/java/ne index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/nbt/CompoundTag.java +++ b/src/main/java/net/minecraft/nbt/CompoundTag.java -@@ -0,0 +0,0 @@ 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; - @@ -0,0 +0,0 @@ public class CompoundTag implements Tag { if (i > 512) { throw new RuntimeException("Tried to read NBT tag with too high complexity, depth > 512"); } else { -- HashMap hashmap = Maps.newHashMap(); -+ Object2ObjectOpenHashMap hashmap = new Object2ObjectOpenHashMap<>(8, 0.8f); // Paper - reduce memory footprint of NBTTagCompound - - byte b0; +- Map map = Maps.newHashMap(); ++ it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap map = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(8, 0.8f); // Paper - reduce memory footprint of NBTTagCompound + byte b; + while((b = CompoundTag.readNamedTagType(dataInput, nbtAccounter)) != 0) { @@ -0,0 +0,0 @@ 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 @@ -42,11 +34,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public CompoundTag copy() { - Map map = Maps.newHashMap(Maps.transformValues(this.tags, Tag::copy)); -+ // Paper start - reduce memory footprint of NBTTagCompound -+ Object2ObjectOpenHashMap ret = new Object2ObjectOpenHashMap<>(this.tags.size(), 0.8f); - - return new CompoundTag(map); -+ Iterator> iterator = (this.tags instanceof Object2ObjectOpenHashMap) ? ((Object2ObjectOpenHashMap)this.tags).object2ObjectEntrySet().fastIterator() : this.tags.entrySet().iterator(); ++ // Paper start - reduce memory footprint of NBTTagCompound ++ it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(this.tags.size(), 0.8f); ++ java.util.Iterator> iterator = (this.tags instanceof it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap) ? ((it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap)this.tags).object2ObjectEntrySet().fastIterator() : this.tags.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + ret.put(entry.getKey(), entry.getValue().copy()); @@ -56,4 +47,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - reduce memory footprint of NBTTagCompound } - public boolean equals(Object object) { + @Override diff --git a/patches/server-remapped/Remove-streams-from-Mob-AI-System.patch b/patches/server/Remove-streams-from-Mob-AI-System.patch similarity index 62% rename from patches/server-remapped/Remove-streams-from-Mob-AI-System.patch rename to patches/server/Remove-streams-from-Mob-AI-System.patch index 08114174ed..c080fdd0e4 100644 --- a/patches/server-remapped/Remove-streams-from-Mob-AI-System.patch +++ b/patches/server/Remove-streams-from-Mob-AI-System.patch @@ -13,22 +13,18 @@ diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java b/src/ma index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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 -@@ -0,0 +0,0 @@ - package net.minecraft.world.entity.ai.goal; - -+import com.destroystokyo.paper.util.set.OptimizedSmallEnumSet; // Paper - remove streams from pathfindergoalselector +@@ -0,0 +0,0 @@ package net.minecraft.world.entity.ai.goal; import java.util.EnumSet; public abstract class Goal { - - private final EnumSet flags = EnumSet.noneOf(Goal.Flag.class); + private final EnumSet flags = EnumSet.noneOf(Goal.Flag.class); // Paper unused, but dummy to prevent plugins from crashing as hard. Theyll need to support paper in a special case if this is super important, but really doesn't seem like it would be. -+ private final OptimizedSmallEnumSet goalTypes = new OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector ++ private final com.destroystokyo.paper.util.set.OptimizedSmallEnumSet goalTypes = new com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector - public Goal() {} + public abstract boolean canUse(); @@ -0,0 +0,0 @@ public abstract class Goal { - public void tick() {} + } public void setFlags(EnumSet controls) { - this.flags.clear(); @@ -39,7 +35,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - remove streams from pathfindergoalselector } - public String toString() { + @Override +@@ -0,0 +0,0 @@ public abstract class Goal { return this.getClass().getSimpleName(); } @@ -56,39 +53,32 @@ diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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 -@@ -0,0 +0,0 @@ - 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; @@ -0,0 +0,0 @@ public class GoalSelector { - private final Map lockedFlags = new EnumMap(Goal.Flag.class); - private final Set availableGoals = Sets.newLinkedHashSet(); private Set getTasks() { return availableGoals; }// Paper - OBFHELPER + private final Map lockedFlags = new EnumMap<>(Goal.Flag.class); + private final Set availableGoals = Sets.newLinkedHashSet(); private final Supplier profiler; - private final EnumSet disabledFlags = EnumSet.noneOf(Goal.Flag.class); + private final EnumSet disabledFlags = EnumSet.noneOf(Goal.Flag.class); // Paper unused, but dummy to prevent plugins from crashing as hard. Theyll need to support paper in a special case if this is super important, but really doesn't seem like it would be. -+ private final OptimizedSmallEnumSet goalTypes = new OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector - private int newGoalRate = 3;private int getTickRate() { return newGoalRate; } // Paper - OBFHELPER - private int curRate;private int getCurRate() { return curRate; } private void incRate() { this.curRate++; } // Paper TODO ++ private final com.destroystokyo.paper.util.set.OptimizedSmallEnumSet goalTypes = new com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector + private int tickCount; + private int newGoalRate = 3; + private int curRate; ++ private static final Goal.Flag[] PATHFINDER_GOAL_TYPES = Goal.Flag.values(); // Paper - remove streams from pathfindergoalselector + public GoalSelector(Supplier profiler) { + this.profiler = profiler; @@ -0,0 +0,0 @@ public class GoalSelector { + } // Paper end - public void removeGoal(Goal goal) { -- this.availableGoals.stream().filter((pathfindergoalwrapped) -> { -- return pathfindergoalwrapped.getGoal() == goal; +- this.availableGoals.stream().filter((wrappedGoal) -> { +- return wrappedGoal.getGoal() == goal; - }).filter(WrappedGoal::isRunning).forEach(WrappedGoal::stop); -- this.availableGoals.removeIf((pathfindergoalwrapped) -> { -- return pathfindergoalwrapped.getGoal() == goal; +- this.availableGoals.removeIf((wrappedGoal) -> { +- return wrappedGoal.getGoal() == goal; - }); + // Paper start - remove streams from pathfindergoalselector -+ for (Iterator iterator = this.availableGoals.iterator(); iterator.hasNext();) { ++ for (java.util.Iterator iterator = this.availableGoals.iterator(); iterator.hasNext();) { + WrappedGoal goalWrapped = iterator.next(); + if (goalWrapped.getGoal() != goal) { + continue; @@ -101,76 +91,57 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - remove streams from pathfindergoalselector } -+ private static final Goal.Flag[] PATHFINDER_GOAL_TYPES = Goal.Flag.values(); // Paper - remove streams from pathfindergoalselector -+ public void tick() { - ProfilerFiller gameprofilerfiller = (ProfilerFiller) this.profiler.get(); - - gameprofilerfiller.push("goalCleanup"); -- this.getRunningGoals().filter((pathfindergoalwrapped) -> { -- boolean flag; -- -- if (pathfindergoalwrapped.isRunning()) { -- Stream stream = pathfindergoalwrapped.getFlags().stream(); -- EnumSet enumset = this.disabledFlags; -- -- this.disabledFlags.getClass(); -- if (!stream.anyMatch(enumset::contains) && pathfindergoalwrapped.canContinueToUse()) { -- flag = false; -- return flag; -- } -+ // Paper start - remove streams from pathfindergoalselector -+ for (Iterator iterator = this.availableGoals.iterator(); iterator.hasNext();) { -+ WrappedGoal wrappedGoal = iterator.next(); -+ if (!wrappedGoal.isRunning()) { -+ continue; - } -- -- flag = true; -- return flag; + ProfilerFiller profilerFiller = this.profiler.get(); + profilerFiller.push("goalCleanup"); +- this.getRunningGoals().filter((wrappedGoal) -> { +- return !wrappedGoal.isRunning() || wrappedGoal.getFlags().stream().anyMatch(this.disabledFlags::contains) || !wrappedGoal.canContinueToUse(); - }).forEach(Goal::stop); +- this.lockedFlags.forEach((flag, wrappedGoal) -> { ++ // Paper start - remove streams from pathfindergoalselector ++ for (java.util.Iterator iterator = this.availableGoals.iterator(); iterator.hasNext();) { ++ WrappedGoal wrappedGoal = iterator.next(); + if (!wrappedGoal.isRunning()) { +- this.lockedFlags.remove(flag); ++ continue; ++ } + if (!this.goalTypes.hasCommonElements(wrappedGoal.getGoalTypes()) && wrappedGoal.canContinueToUse()) { + continue; + } + wrappedGoal.stop(); + } + // Paper end - remove streams from pathfindergoalselector - this.lockedFlags.forEach((pathfindergoal_type, pathfindergoalwrapped) -> { - if (!pathfindergoalwrapped.isRunning()) { - this.lockedFlags.remove(pathfindergoal_type); -@@ -0,0 +0,0 @@ public class GoalSelector { ++ this.lockedFlags.forEach((pathfindergoal_type, pathfindergoalwrapped) -> { ++ if (!pathfindergoalwrapped.isRunning()) { ++ this.lockedFlags.remove(pathfindergoal_type); + } + }); - gameprofilerfiller.pop(); - gameprofilerfiller.push("goalUpdate"); -- this.availableGoals.stream().filter((pathfindergoalwrapped) -> { -- return !pathfindergoalwrapped.isRunning(); -- }).filter((pathfindergoalwrapped) -> { -- Stream stream = pathfindergoalwrapped.getFlags().stream(); -- EnumSet enumset = this.disabledFlags; -- -- this.disabledFlags.getClass(); -- return stream.noneMatch(enumset::contains); -- }).filter((pathfindergoalwrapped) -> { -- return pathfindergoalwrapped.getFlags().stream().allMatch((pathfindergoal_type) -> { -- return ((WrappedGoal) this.lockedFlags.getOrDefault(pathfindergoal_type, GoalSelector.NO_GOAL)).canBeReplacedBy(pathfindergoalwrapped); + profilerFiller.pop(); + profilerFiller.push("goalUpdate"); +- this.availableGoals.stream().filter((wrappedGoal) -> { +- return !wrappedGoal.isRunning(); +- }).filter((wrappedGoal) -> { +- return wrappedGoal.getFlags().stream().noneMatch(this.disabledFlags::contains); +- }).filter((wrappedGoal) -> { +- return wrappedGoal.getFlags().stream().allMatch((flag) -> { +- return this.lockedFlags.getOrDefault(flag, NO_GOAL).canBeReplacedBy(wrappedGoal); - }); -- }).filter(WrappedGoal::canUse).forEach((pathfindergoalwrapped) -> { -- pathfindergoalwrapped.getFlags().forEach((pathfindergoal_type) -> { -- WrappedGoal pathfindergoalwrapped1 = (WrappedGoal) this.lockedFlags.getOrDefault(pathfindergoal_type, GoalSelector.NO_GOAL); -- -- pathfindergoalwrapped1.stop(); -- this.lockedFlags.put(pathfindergoal_type, pathfindergoalwrapped); +- }).filter(WrappedGoal::canUse).forEach((wrappedGoal) -> { +- wrappedGoal.getFlags().forEach((flag) -> { +- WrappedGoal wrappedGoal2 = this.lockedFlags.getOrDefault(flag, NO_GOAL); +- wrappedGoal2.stop(); +- this.lockedFlags.put(flag, wrappedGoal); - }); -- pathfindergoalwrapped.start(); -- }); ++ + // Paper start - remove streams from pathfindergoalselector -+ goal_update_loop: for (Iterator iterator = this.availableGoals.iterator(); iterator.hasNext();) { ++ goal_update_loop: for (java.util.Iterator iterator = this.availableGoals.iterator(); iterator.hasNext();) { + WrappedGoal wrappedGoal = iterator.next(); + if (wrappedGoal.isRunning()) { + continue; + } + -+ OptimizedSmallEnumSet wrappedGoalSet = wrappedGoal.getGoalTypes(); ++ com.destroystokyo.paper.util.set.OptimizedSmallEnumSet wrappedGoalSet = wrappedGoal.getGoalTypes(); + + if (this.goalTypes.hasCommonElements(wrappedGoalSet)) { + continue; @@ -201,22 +172,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + wrapped.stop(); + this.lockedFlags.put(type, wrappedGoal); + } -+ -+ wrappedGoal.start(); + wrappedGoal.start(); +- }); + } + // Paper end - remove streams from pathfindergoalselector - gameprofilerfiller.pop(); - gameprofilerfiller.push("goalTick"); + profilerFiller.pop(); + profilerFiller.push("goalTick"); - this.getRunningGoals().forEach(WrappedGoal::tick); + // Paper start - remove streams from pathfindergoalselector -+ for (Iterator iterator = this.availableGoals.iterator(); iterator.hasNext();) { ++ for (java.util.Iterator iterator = this.availableGoals.iterator(); iterator.hasNext();) { + WrappedGoal wrappedGoal = iterator.next(); + if (wrappedGoal.isRunning()) { + wrappedGoal.tick(); + } + } + // Paper end - remove streams from pathfindergoalselector - gameprofilerfiller.pop(); + profilerFiller.pop(); } @@ -0,0 +0,0 @@ public class GoalSelector { @@ -250,4 +221,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - remove streams from pathfindergoalselector } - public boolean isRunning() { return this.isRunning(); } // Paper - OBFHELPER + public boolean isRunning() { diff --git a/patches/server-remapped/Remove-streams-from-PairedQueue.patch b/patches/server/Remove-streams-from-PairedQueue.patch similarity index 52% rename from patches/server-remapped/Remove-streams-from-PairedQueue.patch rename to patches/server/Remove-streams-from-PairedQueue.patch index ed168b539f..254a7e495b 100644 --- a/patches/server-remapped/Remove-streams-from-PairedQueue.patch +++ b/patches/server/Remove-streams-from-PairedQueue.patch @@ -11,54 +11,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/util/thread/StrictQueue.java +++ b/src/main/java/net/minecraft/util/thread/StrictQueue.java @@ -0,0 +0,0 @@ public interface StrictQueue { - - public static final class FixedPriorityQueue implements StrictQueue { - -- private final List> queueList; -+ private final List> queueList; private final List> getQueues() { return this.queueList; } // Paper - OBFHELPER + private final List> queueList; public FixedPriorityQueue(int priorityCount) { -- this.queueList = (List) IntStream.range(0, priorityCount).mapToObj((j) -> { +- 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.getQueues().add(Queues.newConcurrentLinkedQueue()); ++ this.queueList.add(Queues.newConcurrentLinkedQueue()); + } + // Paper end - remove streams } @Nullable - @Override - public Runnable pop() { -- Iterator iterator = this.queueList.iterator(); -- -- Runnable runnable; -- -- do { -- if (!iterator.hasNext()) { -- return null; -+ // Paper start - remove iterator creation -+ for (int i = 0, len = this.getQueues().size(); i < len; ++i) { -+ Queue queue = this.getQueues().get(i); -+ Runnable ret = queue.poll(); -+ if (ret != null) { -+ return ret; - } -- -- Queue queue = (Queue) iterator.next(); -- -- runnable = (Runnable) queue.poll(); -- } while (runnable == null); -- -- return runnable; -+ } -+ return null; -+ // Paper end - remove iterator creation - } - - public boolean push(StrictQueue.IntRunnable message) { @@ -0,0 +0,0 @@ public interface StrictQueue { @Override @@ -66,8 +33,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - return this.queueList.stream().allMatch(Collection::isEmpty); + // Paper start - remove streams + // why are we doing streams every time we might want to execute a task? -+ for (int i = 0, len = this.getQueues().size(); i < len; ++i) { -+ Queue queue = this.getQueues().get(i); ++ for (int i = 0, len = this.queueList.size(); i < len; ++i) { ++ Queue queue = this.queueList.get(i); + if (!queue.isEmpty()) { + return false; + } @@ -75,5 +42,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return true; + // Paper end - remove streams } - } + @Override diff --git a/patches/server-remapped/Restrict-vanilla-teleport-command-to-valid-locations.patch b/patches/server/Restrict-vanilla-teleport-command-to-valid-locations.patch similarity index 100% rename from patches/server-remapped/Restrict-vanilla-teleport-command-to-valid-locations.patch rename to patches/server/Restrict-vanilla-teleport-command-to-valid-locations.patch diff --git a/patches/server-remapped/Validate-PickItem-Packet-and-kick-for-invalid.patch b/patches/server/Validate-PickItem-Packet-and-kick-for-invalid.patch similarity index 74% rename from patches/server-remapped/Validate-PickItem-Packet-and-kick-for-invalid.patch rename to patches/server/Validate-PickItem-Packet-and-kick-for-invalid.patch index f044fbadbe..7c700b1639 100644 --- a/patches/server-remapped/Validate-PickItem-Packet-and-kick-for-invalid.patch +++ b/patches/server/Validate-PickItem-Packet-and-kick-for-invalid.patch @@ -8,19 +8,19 @@ diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListener index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener { +@@ -0,0 +0,0 @@ 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/Villager-Restocks-API.patch b/patches/server/Villager-Restocks-API.patch similarity index 68% rename from patches/server-remapped/Villager-Restocks-API.patch rename to patches/server/Villager-Restocks-API.patch index b5038a00df..56bce3f675 100644 --- a/patches/server-remapped/Villager-Restocks-API.patch +++ b/patches/server/Villager-Restocks-API.patch @@ -16,13 +16,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + private int numberOfRestocksToday; public int getRestocksToday(){ return this.numberOfRestocksToday; } public void setRestocksToday(int restocksToday){ this.numberOfRestocksToday = restocksToday; } // Paper OBFHELPER private long lastRestockCheckDayTime; private boolean assignProfessionWhenSpawned; - private static final ImmutableList> MEMORY_TYPES = ImmutableList.of(MemoryModuleType.HOME, MemoryModuleType.JOB_SITE, MemoryModuleType.POTENTIAL_JOB_SITE, MemoryModuleType.MEETING_POINT, MemoryModuleType.MOBS, MemoryModuleType.VISIBLE_MOBS, MemoryModuleType.VISIBLE_VILLAGER_BABIES, MemoryModuleType.NEAREST_PLAYERS, MemoryModuleType.NEAREST_VISIBLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_TARGETABLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM, MemoryModuleType.WALK_TARGET, new MemoryModuleType[]{MemoryModuleType.LOOK_TARGET, MemoryModuleType.INTERACTION_TARGET, MemoryModuleType.BREED_TARGET, MemoryModuleType.PATH, MemoryModuleType.DOORS_TO_CLOSE, MemoryModuleType.NEAREST_BED, MemoryModuleType.HURT_BY, MemoryModuleType.HURT_BY_ENTITY, MemoryModuleType.NEAREST_HOSTILE, MemoryModuleType.SECONDARY_JOB_SITE, MemoryModuleType.HIDING_PLACE, MemoryModuleType.HEARD_BELL_TIME, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.LAST_SLEPT, MemoryModuleType.LAST_WOKEN, MemoryModuleType.LAST_WORKED_AT_POI, MemoryModuleType.GOLEM_DETECTED_RECENTLY}); + private static final ImmutableList> MEMORY_TYPES = ImmutableList.of(MemoryModuleType.HOME, MemoryModuleType.JOB_SITE, MemoryModuleType.POTENTIAL_JOB_SITE, MemoryModuleType.MEETING_POINT, MemoryModuleType.NEAREST_LIVING_ENTITIES, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.VISIBLE_VILLAGER_BABIES, MemoryModuleType.NEAREST_PLAYERS, MemoryModuleType.NEAREST_VISIBLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM, MemoryModuleType.WALK_TARGET, new MemoryModuleType[]{MemoryModuleType.LOOK_TARGET, MemoryModuleType.INTERACTION_TARGET, MemoryModuleType.BREED_TARGET, MemoryModuleType.PATH, MemoryModuleType.DOORS_TO_CLOSE, MemoryModuleType.NEAREST_BED, MemoryModuleType.HURT_BY, MemoryModuleType.HURT_BY_ENTITY, MemoryModuleType.NEAREST_HOSTILE, MemoryModuleType.SECONDARY_JOB_SITE, MemoryModuleType.HIDING_PLACE, MemoryModuleType.HEARD_BELL_TIME, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.LAST_SLEPT, MemoryModuleType.LAST_WOKEN, MemoryModuleType.LAST_WORKED_AT_POI, MemoryModuleType.GOLEM_DETECTED_RECENTLY}); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java @@ -0,0 +0,0 @@ public class CraftVillager extends CraftAbstractVillager implements Villager { - getHandle().setVillagerXp(experience); + this.getHandle().setVillagerXp(experience); } + // Paper start 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 index 8503c3c9e3..a791f93de2 160000 --- a/work/Bukkit +++ b/work/Bukkit @@ -1 +1 @@ -Subproject commit 8503c3c9e3dca76b2ae10796d8c288b3f3101737 +Subproject commit a791f93de242bf89d116fed843b889e38433e094 diff --git a/work/CraftBukkit b/work/CraftBukkit index 40caacc846..85b8c1fda6 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit 40caacc846a6349cd555d9d89cf9cf729c0b75b7 +Subproject commit 85b8c1fda69f6f80e45ddd19590846c249e5b6bc