diff --git a/patches/unapplied/server/1030-Incremental-chunk-and-player-saving.patch b/patches/server/1049-Incremental-chunk-and-player-saving.patch similarity index 79% rename from patches/unapplied/server/1030-Incremental-chunk-and-player-saving.patch rename to patches/server/1049-Incremental-chunk-and-player-saving.patch index 92967eb763..9a12860c6a 100644 --- a/patches/unapplied/server/1030-Incremental-chunk-and-player-saving.patch +++ b/patches/server/1049-Incremental-chunk-and-player-saving.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Incremental chunk and player saving diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index b64c3e29e2b8e890073fee0b45c8b8dfc2b642fd..aa38e3b297209cc121e7dc7a6ac9588c18bf9357 100644 +index de80ac827c8ac3630d68b73cb425d4b56f7d2cd7..f422cbcb69d6fda2b4e229cbdbf10abd0d36d6f9 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -992,7 +992,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0 && this.ticksUntilAutosave <= 0) { -- this.ticksUntilAutosave = this.autosavePeriod; -- // CraftBukkit end -- MinecraftServer.LOGGER.debug("Autosave started"); -- this.profiler.push("save"); -- this.saveEverything(true, false, false); -- this.profiler.pop(); -- MinecraftServer.LOGGER.debug("Autosave finished"); +- if (this.autosavePeriod > 0 && this.ticksUntilAutosave <= 0) { // CraftBukkit +- this.autoSave(); + // Paper start - Incremental chunk and player saving ++ final ProfilerFiller profiler = Profiler.get(); + int playerSaveInterval = io.papermc.paper.configuration.GlobalConfiguration.get().playerAutoSave.rate; + if (playerSaveInterval < 0) { + playerSaveInterval = autosavePeriod; + } -+ this.profiler.push("save"); ++ profiler.push("save"); + final boolean fullSave = autosavePeriod > 0 && this.tickCount % autosavePeriod == 0; + try { + this.isSaving = true; + if (playerSaveInterval > 0) { + this.playerList.saveAll(playerSaveInterval); + } -+ for (ServerLevel level : this.getAllLevels()) { ++ for (final ServerLevel level : this.getAllLevels()) { + if (level.paperConfig().chunks.autoSaveInterval.value() > 0) { + level.saveIncrementally(fullSave); + } @@ -50,16 +44,16 @@ index b64c3e29e2b8e890073fee0b45c8b8dfc2b642fd..aa38e3b297209cc121e7dc7a6ac9588c + } finally { + this.isSaving = false; } -+ this.profiler.pop(); ++ profiler.pop(); + // Paper end - Incremental chunk and player saving - // Paper start - move executeAll() into full server tick timing - try (co.aikar.timings.Timing ignored = MinecraftTimings.processTasksTimer.startTiming()) { - this.runAllTasks(); + + ProfilerFiller gameprofilerfiller = Profiler.get(); + diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 202975cf97ae143622a0c19826b0d63ad2afa0ce..f9abf63e12ea930275121b470e4e4906cff0fc12 100644 +index a7420e4522e0dff72ce7f8a791b9cd4bfa270106..fd07824ff6a928ca6e2f56477a63bac7aaeb8c15 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1315,6 +1315,35 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -1371,6 +1371,35 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe return !this.server.isUnderSpawnProtection(this, pos, player) && this.getWorldBorder().isWithinBounds(pos); } @@ -96,10 +90,10 @@ index 202975cf97ae143622a0c19826b0d63ad2afa0ce..f9abf63e12ea930275121b470e4e4906 // Paper start - add close param this.save(progressListener, flush, savingDisabled, false); diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 8dc3ba983fd4c61e463867be8d224aa90424215a..6c280abdef5f80b668d6090f9d35283a33e21e0c 100644 +index 8ceeebb561046933cba0725e15732fa074226884..8c9148426f23cbbdfaf7ae66657d1a620f8bd853 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -203,6 +203,7 @@ import org.bukkit.inventory.MainHand; +@@ -221,6 +221,7 @@ import org.bukkit.inventory.MainHand; public class ServerPlayer extends net.minecraft.world.entity.player.Player implements ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer { // Paper - rewrite chunk system private static final Logger LOGGER = LogUtils.getLogger(); @@ -108,10 +102,10 @@ index 8dc3ba983fd4c61e463867be8d224aa90424215a..6c280abdef5f80b668d6090f9d35283a private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10; private static final int FLY_STAT_RECORDING_SPEED = 25; diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 30b6f5d4af1dc799d5ffee6a345bcf92528df7cd..5e2c4969e77c669acbb4a13c07033cb267c3d586 100644 +index 3642444d45038fd1a07768ff96bfbd8678b02e04..f8f8e8f602f416fe97fc23ef6efeee7af2749292 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -569,6 +569,7 @@ public abstract class PlayerList { +@@ -519,6 +519,7 @@ public abstract class PlayerList { protected void save(ServerPlayer player) { if (!player.getBukkitEntity().isPersistent()) return; // CraftBukkit @@ -119,7 +113,7 @@ index 30b6f5d4af1dc799d5ffee6a345bcf92528df7cd..5e2c4969e77c669acbb4a13c07033cb2 this.playerIo.save(player); ServerStatsCounter serverstatisticmanager = (ServerStatsCounter) player.getStats(); // CraftBukkit -@@ -1193,10 +1194,22 @@ public abstract class PlayerList { +@@ -1153,10 +1154,22 @@ public abstract class PlayerList { } public void saveAll() { diff --git a/patches/unapplied/server/1011-Optimise-general-POI-access.patch b/patches/server/1050-Optimise-general-POI-access.patch similarity index 97% rename from patches/unapplied/server/1011-Optimise-general-POI-access.patch rename to patches/server/1050-Optimise-general-POI-access.patch index b3636fe591..0e3d18cfa4 100644 --- a/patches/unapplied/server/1011-Optimise-general-POI-access.patch +++ b/patches/server/1050-Optimise-general-POI-access.patch @@ -886,10 +886,10 @@ index d5a549f08b98c80a5cf0eef02cb8a389c32dfecb..92731b6b593289e9f583c9b705b219e8 BlockPos blockPos = path.getTarget(); Optional> optional = poiManager.getType(blockPos); diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java -index d7a6eab60bf26916f78f858e224573560e581fef..a908bf1dc5e821dcf6981a8c21076fb0bdc6516d 100644 +index 5930a430983061afddf20e3208ff2462ca1b78cd..63a94b6068fdaef8bb26675c2927cb729ced1dac 100644 --- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java +++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java -@@ -268,36 +268,45 @@ public class PoiManager extends SectionStorage implements ca.spotted +@@ -254,36 +254,45 @@ public class PoiManager extends SectionStorage im public Optional find( Predicate> typePredicate, Predicate posPredicate, BlockPos pos, int radius, PoiManager.Occupancy occupationStatus ) { @@ -903,10 +903,10 @@ index d7a6eab60bf26916f78f858e224573560e581fef..a908bf1dc5e821dcf6981a8c21076fb0 public Optional findClosest(Predicate> typePredicate, BlockPos pos, int radius, PoiManager.Occupancy occupationStatus) { - return this.getInRange(typePredicate, pos, radius, occupationStatus) - .map(PoiRecord::getPos) -- .min(Comparator.comparingDouble(blockPos2 -> blockPos2.distSqr(pos))); +- .min(Comparator.comparingDouble(poiPos -> poiPos.distSqr(pos))); + // Paper start - re-route to faster logic -+ BlockPos ret = io.papermc.paper.util.PoiAccess.findClosestPoiDataPosition(this, typePredicate, null, pos, radius, radius * radius, occupationStatus, false); -+ return Optional.ofNullable(ret); ++ BlockPos closestPos = io.papermc.paper.util.PoiAccess.findClosestPoiDataPosition(this, typePredicate, null, pos, radius, radius * radius, occupationStatus, false); ++ return Optional.ofNullable(closestPos); + // Paper end - re-route to faster logic } @@ -929,27 +929,27 @@ index d7a6eab60bf26916f78f858e224573560e581fef..a908bf1dc5e821dcf6981a8c21076fb0 - return this.getInRange(typePredicate, pos, radius, occupationStatus) - .map(PoiRecord::getPos) - .filter(posPredicate) -- .min(Comparator.comparingDouble(blockPos2 -> blockPos2.distSqr(pos))); +- .min(Comparator.comparingDouble(poiPos -> poiPos.distSqr(pos))); + // Paper start - re-route to faster logic -+ BlockPos ret = io.papermc.paper.util.PoiAccess.findClosestPoiDataPosition(this, typePredicate, posPredicate, pos, radius, radius * radius, occupationStatus, false); -+ return Optional.ofNullable(ret); ++ BlockPos closestPos = io.papermc.paper.util.PoiAccess.findClosestPoiDataPosition(this, typePredicate, posPredicate, pos, radius, radius * radius, occupationStatus, false); ++ return Optional.ofNullable(closestPos); + // Paper end - re-route to faster logic } - public Optional take(Predicate> typePredicate, BiPredicate, BlockPos> biPredicate, BlockPos pos, int radius) { + public Optional take(Predicate> typePredicate, BiPredicate, BlockPos> posPredicate, BlockPos pos, int radius) { - return this.getInRange(typePredicate, pos, radius, PoiManager.Occupancy.HAS_SPACE) -- .filter(poi -> biPredicate.test(poi.getPoiType(), poi.getPos())) +- .filter(poi -> posPredicate.test(poi.getPoiType(), poi.getPos())) - .findFirst() + // Paper start - re-route to faster logic + final @javax.annotation.Nullable PoiRecord closest = io.papermc.paper.util.PoiAccess.findClosestPoiDataRecord( -+ this, typePredicate, biPredicate, pos, radius, radius * radius, Occupancy.HAS_SPACE, false ++ this, typePredicate, posPredicate, pos, radius, radius * radius, Occupancy.HAS_SPACE, false + ); + return Optional.ofNullable(closest) + // Paper end - re-route to faster logic .map(poi -> { poi.acquireTicket(); return poi.getPos(); -@@ -312,8 +321,21 @@ public class PoiManager extends SectionStorage implements ca.spotted +@@ -298,8 +307,21 @@ public class PoiManager extends SectionStorage im int radius, RandomSource random ) { @@ -974,7 +974,7 @@ index d7a6eab60bf26916f78f858e224573560e581fef..a908bf1dc5e821dcf6981a8c21076fb0 public boolean release(BlockPos pos) { diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java -index a6c0e89cb645693034f8e90ac2de8f2da457453c..11e895d837794d79a76303b912092096bd7d07a8 100644 +index 712cbfc100e8aaf612d1d651dae64f57f892a768..827991ee61406bcda3f4794dcc735c0e2e0e09af 100644 --- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java +++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java @@ -26,7 +26,7 @@ import org.slf4j.Logger; @@ -987,10 +987,10 @@ index a6c0e89cb645693034f8e90ac2de8f2da457453c..11e895d837794d79a76303b912092096 private boolean isValid; diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java -index c7ed3eb80f6e8b918434153093644776866aa220..21de1b95f2a5d136149447472e871f675760ba1a 100644 +index c3beb7fcad46a917d2b61bd0a0e98e5106056728..9b97fb2d125df4df715599aab27e074707731466 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java -@@ -81,11 +81,11 @@ public abstract class SectionStorage implements AutoCloseable, ca.spottedleaf +@@ -131,11 +131,11 @@ public class SectionStorage implements AutoCloseable, ca.spottedleaf.moonr } @Nullable @@ -1005,7 +1005,7 @@ index c7ed3eb80f6e8b918434153093644776866aa220..21de1b95f2a5d136149447472e871f67 return Optional.empty(); } else { diff --git a/src/main/java/net/minecraft/world/level/portal/PortalForcer.java b/src/main/java/net/minecraft/world/level/portal/PortalForcer.java -index fd04a50183ccb1f21fc6efa70256e1bb4db2d6d4..49f7ba292b82bac1643cc07aa576f3c37b8e8ab3 100644 +index 83d294f6f48b867d09ea0d339c779011bf4138a5..9204bb0538297f233442a86733a33e6d0eea8114 100644 --- a/src/main/java/net/minecraft/world/level/portal/PortalForcer.java +++ b/src/main/java/net/minecraft/world/level/portal/PortalForcer.java @@ -53,17 +53,39 @@ public class PortalForcer { diff --git a/patches/unapplied/server/1025-Fix-entity-tracker-desync-when-new-players-are-added.patch b/patches/server/1051-Fix-entity-tracker-desync-when-new-players-are-added.patch similarity index 74% rename from patches/unapplied/server/1025-Fix-entity-tracker-desync-when-new-players-are-added.patch rename to patches/server/1051-Fix-entity-tracker-desync-when-new-players-are-added.patch index f767b9ab91..6aecc462a4 100644 --- a/patches/unapplied/server/1025-Fix-entity-tracker-desync-when-new-players-are-added.patch +++ b/patches/server/1051-Fix-entity-tracker-desync-when-new-players-are-added.patch @@ -29,7 +29,7 @@ client will not tick the entity and thus not lerp the entity from its old position to its new position. diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java -index 854baa554da2215a656f976ae2973341c3b2d61c..792b9a72a610cc512a8920d61013b6ba02f71e47 100644 +index f6e1deb2f849d8b01b15cfa69e2f6cd5f2b1512b..f66e40326c510aa3267542b1a24ed75d1ed6d3f1 100644 --- a/src/main/java/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java +++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java @@ -42,9 +42,11 @@ public class ClientboundAddEntityPacket implements Packet= 1 || Math.abs(b1 - this.lastSentXRot) >= 1; +@@ -199,7 +206,7 @@ public class ServerEntity { + long k = this.positionCodec.encodeZ(vec3d); + boolean flag5 = i < -32768L || i > 32767L || j < -32768L || j > 32767L || k < -32768L || k > 32767L; -@@ -185,7 +192,7 @@ public class ServerEntity { - long i1 = this.positionCodec.encodeZ(vec3d); - boolean flag6 = k < -32768L || k > 32767L || l < -32768L || l > 32767L || i1 < -32768L || i1 > 32767L; - -- if (!flag6 && this.teleportDelay <= 400 && !this.wasRiding && this.wasOnGround == this.entity.onGround()) { -+ if (!this.forceStateResync && !flag6 && this.teleportDelay <= 400 && !this.wasRiding && this.wasOnGround == this.entity.onGround()) { // Paper - fix desync when a player is added to the tracker - if ((!flag2 || !flag3) && !(this.entity instanceof AbstractArrow)) { - if (flag2) { - packet1 = new ClientboundMoveEntityPacket.Pos(this.entity.getId(), (short) ((int) k), (short) ((int) l), (short) ((int) i1), this.entity.onGround()); -@@ -249,6 +256,7 @@ public class ServerEntity { +- if (!flag5 && this.teleportDelay <= 400 && !this.wasRiding && this.wasOnGround == this.entity.onGround()) { ++ if (!this.forceStateResync && !flag5 && this.teleportDelay <= 400 && !this.wasRiding && this.wasOnGround == this.entity.onGround()) { // Paper - fix desync when a player is added to the tracker + if ((!flag2 || !flag) && !(this.entity instanceof AbstractArrow)) { + if (flag2) { + packet1 = new ClientboundMoveEntityPacket.Pos(this.entity.getId(), (short) ((int) i), (short) ((int) j), (short) ((int) k), this.entity.onGround()); +@@ -265,6 +272,7 @@ public class ServerEntity { } this.entity.hasImpulse = false; diff --git a/patches/unapplied/server/1026-Lag-compensation-ticks.patch b/patches/server/1052-Lag-compensation-ticks.patch similarity index 81% rename from patches/unapplied/server/1026-Lag-compensation-ticks.patch rename to patches/server/1052-Lag-compensation-ticks.patch index aa8b7f2d46..2643c943aa 100644 --- a/patches/unapplied/server/1026-Lag-compensation-ticks.patch +++ b/patches/server/1052-Lag-compensation-ticks.patch @@ -8,10 +8,10 @@ Areas affected by lag comepnsation: - Eating food items diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index d25d500a2206d4f7e821de3766e8a523df4370e3..b64c3e29e2b8e890073fee0b45c8b8dfc2b642fd 100644 +index f422cbcb69d6fda2b4e229cbdbf10abd0d36d6f9..73855f4555f781741f70267be65dec1ebb98b46a 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -321,6 +321,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); -@@ -1763,6 +1764,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - BlockPhysicsEvent worldserver.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = worldserver.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper - Perf: Optimize Hoppers + worldserver.updateLagCompensationTick(); // Paper - lag compensation - this.profiler.push(() -> { + gameprofilerfiller.push(() -> { String s = String.valueOf(worldserver); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index d223ecfbb0b8986507ce8b6728edbf7c8d818b7d..9e1af229f52a8ac09833901ad53bd154fed34a4f 100644 +index fd07824ff6a928ca6e2f56477a63bac7aaeb8c15..b2bbc9f3efbb7c949cc862eeee5d5f47be5d804f 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -485,6 +485,17 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. - return this.entityTickingChunks; +@@ -577,6 +577,17 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + ); } - // Paper end - rewrite chunk system + // Paper end - chunk tick iteration + // Paper start - lag compensation + private long lagCompensationTick = net.minecraft.server.MinecraftServer.SERVER_INIT; + @@ -50,10 +50,10 @@ index d223ecfbb0b8986507ce8b6728edbf7c8d818b7d..9e1af229f52a8ac09833901ad53bd154 // Add env and gen to constructor, IWorldDataServer -> WorldDataServer public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -index 24b1715397ba8e6f5e9841a030d0e3d964356f89..cc01ead133cc6859ca5d7a1d0ac3c12955e590da 100644 +index 504c996220b278c194c93e001a3b326d549868ec..a96f859a5d0c6ec692d4627a69f3c9ee49199dbc 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -@@ -129,7 +129,7 @@ public class ServerPlayerGameMode { +@@ -127,7 +127,7 @@ public class ServerPlayerGameMode { } public void tick() { @@ -63,10 +63,10 @@ index 24b1715397ba8e6f5e9841a030d0e3d964356f89..cc01ead133cc6859ca5d7a1d0ac3c129 if (this.hasDelayedDestroy) { diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 5079775ce8f86fb061e616190513f56ff086e409..13c93281f6b81e88f2f54befb8e6a3e4bdabf53d 100644 +index 22b3d3d945cbddae25abfca7d900324c79d32293..a68ca22d5f8909d2ad37feded448f777736bf7db 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3900,6 +3900,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4052,6 +4052,10 @@ public abstract class LivingEntity extends Entity implements Attackable { this.resendPossiblyDesyncedDataValues(java.util.List.of(DATA_LIVING_ENTITY_FLAGS), serverPlayer); } // Paper end - Properly cancel usable items @@ -77,21 +77,21 @@ index 5079775ce8f86fb061e616190513f56ff086e409..13c93281f6b81e88f2f54befb8e6a3e4 private void updatingUsingItem() { if (this.isUsingItem()) { if (ItemStack.isSameItem(this.getItemInHand(this.getUsedItemHand()), this.useItem)) { -@@ -3918,7 +3922,12 @@ public abstract class LivingEntity extends Entity implements Attackable { - this.triggerItemUseEffects(stack, 5); - } +@@ -4066,7 +4070,12 @@ public abstract class LivingEntity extends Entity implements Attackable { + protected void updateUsingItem(ItemStack stack) { + stack.onUseTick(this.level(), this, this.getUseItemRemainingTicks()); - if (--this.useItemRemaining == 0 && !this.level().isClientSide && !stack.useOnRelease()) { + // Paper start - lag compensate eating + // we add 1 to the expected time to avoid lag compensating when we should not -+ boolean shouldLagCompensate = this.useItem.has(DataComponents.FOOD) && this.eatStartTime != -1 && (System.nanoTime() - this.eatStartTime) > ((1L + this.totalEatTimeTicks) * 50L * (1000L * 1000L)); ++ final boolean shouldLagCompensate = this.useItem.has(DataComponents.FOOD) && this.eatStartTime != -1 && (System.nanoTime() - this.eatStartTime) > ((1L + this.totalEatTimeTicks) * 50L * (1000L * 1000L)); + if ((--this.useItemRemaining == 0 || shouldLagCompensate) && !this.level().isClientSide && !stack.useOnRelease()) { + this.useItemRemaining = 0; + // Paper end - lag compensate eating this.completeUsingItem(); } -@@ -3964,7 +3973,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4104,7 +4113,10 @@ public abstract class LivingEntity extends Entity implements Attackable { if (!itemstack.isEmpty() && !this.isUsingItem() || forceUpdate) { // Paper - Prevent consuming the wrong itemstack this.useItem = itemstack; @@ -103,7 +103,7 @@ index 5079775ce8f86fb061e616190513f56ff086e409..13c93281f6b81e88f2f54befb8e6a3e4 if (!this.level().isClientSide) { this.setLivingEntityFlag(1, true); this.setLivingEntityFlag(2, hand == InteractionHand.OFF_HAND); -@@ -3989,7 +4001,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4129,7 +4141,10 @@ public abstract class LivingEntity extends Entity implements Attackable { } } else if (!this.isUsingItem() && !this.useItem.isEmpty()) { this.useItem = ItemStack.EMPTY; @@ -115,7 +115,7 @@ index 5079775ce8f86fb061e616190513f56ff086e409..13c93281f6b81e88f2f54befb8e6a3e4 } } -@@ -4132,7 +4147,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -4260,7 +4275,10 @@ public abstract class LivingEntity extends Entity implements Attackable { } this.useItem = ItemStack.EMPTY; diff --git a/patches/unapplied/server/1039-Optimise-collision-checking-in-player-move-packet-ha.patch b/patches/server/1053-Optimise-collision-checking-in-player-move-packet-ha.patch similarity index 93% rename from patches/unapplied/server/1039-Optimise-collision-checking-in-player-move-packet-ha.patch rename to patches/server/1053-Optimise-collision-checking-in-player-move-packet-ha.patch index 2caf83aaca..a75038dc8a 100644 --- a/patches/unapplied/server/1039-Optimise-collision-checking-in-player-move-packet-ha.patch +++ b/patches/server/1053-Optimise-collision-checking-in-player-move-packet-ha.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Optimise collision checking in player move packet handling Move collision logic to just the hasNewCollision call instead of getCubes + hasNewCollision diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 62d5ca25104e10ca16c2005ef9272bf8329ce145..f93edc8a6ed7c51ec6e9335f66ab146d6aeb69a0 100644 +index eef96e946b80064fe211039a65db4192ea7a52d3..c4b016a2fb5c79fb3f191e243712bee7cbe5cd2c 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -572,7 +572,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -577,7 +577,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl return; } @@ -18,7 +18,7 @@ index 62d5ca25104e10ca16c2005ef9272bf8329ce145..f93edc8a6ed7c51ec6e9335f66ab146d d6 = d3 - this.vehicleLastGoodX; // Paper - diff on change, used for checking large move vectors above d7 = d4 - this.vehicleLastGoodY - 1.0E-6D; // Paper - diff on change, used for checking large move vectors above -@@ -588,6 +588,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -593,6 +593,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } entity.move(MoverType.PLAYER, new Vec3(d6, d7, d8)); @@ -26,7 +26,7 @@ index 62d5ca25104e10ca16c2005ef9272bf8329ce145..f93edc8a6ed7c51ec6e9335f66ab146d double d11 = d7; d6 = d3 - entity.getX(); -@@ -601,15 +602,23 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -606,15 +607,23 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl boolean flag2 = false; if (d10 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot @@ -53,7 +53,7 @@ index 62d5ca25104e10ca16c2005ef9272bf8329ce145..f93edc8a6ed7c51ec6e9335f66ab146d entity.absMoveTo(d0, d1, d2, f, f1); this.player.absMoveTo(d0, d1, d2, this.player.getYRot(), this.player.getXRot()); // CraftBukkit this.send(new ClientboundMoveVehiclePacket(entity)); -@@ -691,7 +700,32 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -697,7 +706,32 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } private boolean noBlocksAround(Entity entity) { @@ -87,7 +87,7 @@ index 62d5ca25104e10ca16c2005ef9272bf8329ce145..f93edc8a6ed7c51ec6e9335f66ab146d } @Override -@@ -1386,7 +1420,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1398,7 +1432,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } } @@ -96,7 +96,7 @@ index 62d5ca25104e10ca16c2005ef9272bf8329ce145..f93edc8a6ed7c51ec6e9335f66ab146d d6 = d0 - this.lastGoodX; // Paper - diff on change, used for checking large move vectors above d7 = d1 - this.lastGoodY; // Paper - diff on change, used for checking large move vectors above -@@ -1428,6 +1462,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1440,6 +1474,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.player.move(MoverType.PLAYER, new Vec3(d6, d7, d8)); this.player.onGround = packet.isOnGround(); // CraftBukkit - SPIGOT-5810, SPIGOT-5835, SPIGOT-6828: reset by this.player.move @@ -104,7 +104,7 @@ index 62d5ca25104e10ca16c2005ef9272bf8329ce145..f93edc8a6ed7c51ec6e9335f66ab146d // Paper start - prevent position desync if (this.awaitingPositionFromClient != null) { return; // ... thanks Mojang for letting move calls teleport across dimensions. -@@ -1458,7 +1493,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1470,7 +1505,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } // Paper start - Add fail move event @@ -123,7 +123,7 @@ index 62d5ca25104e10ca16c2005ef9272bf8329ce145..f93edc8a6ed7c51ec6e9335f66ab146d if (teleportBack) { io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.CLIPPED_INTO_BLOCK, toX, toY, toZ, toYaw, toPitch, false); -@@ -1569,7 +1614,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1594,7 +1639,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private boolean updateAwaitingTeleport() { if (this.awaitingPositionFromClient != null) { @@ -132,7 +132,7 @@ index 62d5ca25104e10ca16c2005ef9272bf8329ce145..f93edc8a6ed7c51ec6e9335f66ab146d this.awaitingTeleportTime = this.tickCount; this.teleport(this.awaitingPositionFromClient.x, this.awaitingPositionFromClient.y, this.awaitingPositionFromClient.z, this.player.getYRot(), this.player.getXRot()); } -@@ -1582,6 +1627,33 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1607,6 +1652,33 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } } diff --git a/patches/unapplied/server/1028-Write-SavedData-IO-async.patch b/patches/unapplied/server/1028-Write-SavedData-IO-async.patch deleted file mode 100644 index cceb676e45..0000000000 --- a/patches/unapplied/server/1028-Write-SavedData-IO-async.patch +++ /dev/null @@ -1,164 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Cryptite -Date: Tue, 27 Jun 2023 11:35:52 -0500 -Subject: [PATCH] Write SavedData IO async - -Co-Authored-By: Shane Freeder - -diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 4a5dc7fd4eb1a7ab1ec371f0f107de882f88149c..dcb5651d1d9b10b40430fb2f713beedf68336704 100644 ---- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java -+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -369,6 +369,13 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon - - public void close(boolean save) throws IOException { - ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.close(save, true); // Paper - rewrite chunk system -+ // Paper start - Write SavedData IO async -+ try { -+ this.dataStorage.close(); -+ } catch (final IOException e) { -+ LOGGER.error("Failed to close persistent world data", e); -+ } -+ // Paper end - Write SavedData IO async - } - - // CraftBukkit start - modelled on below -diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index c5698b05cc3ea4cb1bc6789c30f2aab76748d491..2931e1dd0c8ae5ac1c9ec42f90dd5ab57595bf60 100644 ---- a/src/main/java/net/minecraft/server/level/ServerLevel.java -+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1330,7 +1330,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. - progressListener.progressStartNoAbort(Component.translatable("menu.savingLevel")); - } - -- this.saveLevelData(); -+ this.saveLevelData(!close); // Paper - Write SavedData IO async - if (progressListener != null) { - progressListener.progressStage(Component.translatable("menu.savingChunks")); - } -@@ -1361,12 +1361,12 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. - // CraftBukkit end - } - -- private void saveLevelData() { -+ private void saveLevelData(boolean async) { // Paper - Write SavedData IO async - if (this.dragonFight != null) { - this.serverLevelData.setEndDragonFightData(this.dragonFight.saveData()); // CraftBukkit - } - -- this.getChunkSource().getDataStorage().save(); -+ this.getChunkSource().getDataStorage().save(async); // Paper - Write SavedData IO async - } - - public List getEntities(EntityTypeTest filter, Predicate predicate) { -diff --git a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java -index 0382b6597a130d746f8954a93a756a9d1ac81d50..cb39c629af1827078f35904a373d35a63fea17ff 100644 ---- a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java -+++ b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java -@@ -116,7 +116,13 @@ public class WorldUpgrader { - (new WorldUpgrader.PoiUpgrader(this)).upgrade(); - WorldUpgrader.LOGGER.info("Upgrading blocks"); - (new WorldUpgrader.ChunkUpgrader()).upgrade(); -- this.overworldDataStorage.save(); -+ // Paper start - Write SavedData IO async -+ try { -+ this.overworldDataStorage.close(); -+ } catch (final IOException e) { -+ LOGGER.error("Failed to close persistent world data", e); -+ } -+ // Paper end - Write SavedData IO async - i = Util.getMillis() - i; - WorldUpgrader.LOGGER.info("World optimizaton finished after {} seconds", i / 1000L); - this.finished = true; -diff --git a/src/main/java/net/minecraft/world/level/saveddata/SavedData.java b/src/main/java/net/minecraft/world/level/saveddata/SavedData.java -index 9cc3850bb70dfbcf342651360314a19fd9ea3ecc..4cbb943b702baaeb8bfd2b558cc848e719cf095d 100644 ---- a/src/main/java/net/minecraft/world/level/saveddata/SavedData.java -+++ b/src/main/java/net/minecraft/world/level/saveddata/SavedData.java -@@ -30,20 +30,36 @@ public abstract class SavedData { - return this.dirty; - } - -+ // Paper start - Write SavedData IO async - joining is evil, but we assume the old blocking behavior here just for safety -+ @io.papermc.paper.annotation.DoNotUse - public void save(File file, HolderLookup.Provider registryLookup) { -+ save(file, registryLookup, null).join(); -+ } -+ -+ public java.util.concurrent.CompletableFuture save(File file, HolderLookup.Provider registryLookup, @org.jetbrains.annotations.Nullable java.util.concurrent.ExecutorService ioExecutor) { -+ // Paper end - Write SavedData IO async - if (this.isDirty()) { - CompoundTag compoundTag = new CompoundTag(); - compoundTag.put("data", this.save(new CompoundTag(), registryLookup)); - NbtUtils.addCurrentDataVersion(compoundTag); - -+ Runnable writeRunnable = () -> { // Paper - Write SavedData IO async - try { - NbtIo.writeCompressed(compoundTag, file.toPath()); - } catch (IOException var5) { - LOGGER.error("Could not save data {}", this, var5); - } -+ }; // Paper - Write SavedData IO async - - this.setDirty(false); -+ // Paper start - Write SavedData IO async -+ if (ioExecutor == null) { -+ return java.util.concurrent.CompletableFuture.runAsync(writeRunnable); // No executor, just use common pool -+ } -+ return java.util.concurrent.CompletableFuture.runAsync(writeRunnable, ioExecutor); - } -+ return java.util.concurrent.CompletableFuture.completedFuture(null); -+ // Paper end - Write SavedData IO async - } - - public static record Factory( -diff --git a/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java b/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java -index 7d98d2911e9d6ec429ce7df1f1f2650c7ea32325..6e23e69abd56eeda3b52a22019e1b74ae10682e7 100644 ---- a/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java -+++ b/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java -@@ -23,17 +23,19 @@ import net.minecraft.util.datafix.DataFixTypes; - import net.minecraft.world.level.saveddata.SavedData; - import org.slf4j.Logger; - --public class DimensionDataStorage { -+public class DimensionDataStorage implements java.io.Closeable { // Paper - Write SavedData IO async - private static final Logger LOGGER = LogUtils.getLogger(); - public final Map cache = Maps.newHashMap(); - private final DataFixer fixerUpper; - private final HolderLookup.Provider registries; - private final File dataFolder; -+ protected final java.util.concurrent.ExecutorService ioExecutor; // Paper - Write SavedData IO async - - public DimensionDataStorage(File directory, DataFixer dataFixer, HolderLookup.Provider registryLookup) { - this.fixerUpper = dataFixer; - this.dataFolder = directory; - this.registries = registryLookup; -+ this.ioExecutor = java.util.concurrent.Executors.newSingleThreadExecutor(new com.google.common.util.concurrent.ThreadFactoryBuilder().setNameFormat("DimensionDataIO - " + dataFolder.getParent() + " - %d").setDaemon(true).build()); // Paper - Write SavedData IO async - } - - private File getDataFile(String id) { -@@ -123,10 +125,23 @@ public class DimensionDataStorage { - return bl; - } - -- public void save() { -+ // Paper start - Write SavedData IO async -+ @Override -+ public void close() throws IOException { -+ save(false); -+ this.ioExecutor.shutdown(); -+ } -+ // Paper end - Write SavedData IO async -+ -+ public void save(boolean async) { // Paper - Write SavedData IO async - this.cache.forEach((id, state) -> { - if (state != null) { -- state.save(this.getDataFile(id), this.registries); -+ // Paper start - Write SavedData IO async -+ final java.util.concurrent.CompletableFuture save = state.save(this.getDataFile(id), this.registries, this.ioExecutor); -+ if (!async) { -+ save.join(); -+ } -+ // Paper end - Write SavedData IO async - } - }); - }