diff --git a/patches/server/Add-Alternate-Current-redstone-implementation.patch b/patches/server/Add-Alternate-Current-redstone-implementation.patch index 60be49ca07..1e3a938dae 100644 --- a/patches/server/Add-Alternate-Current-redstone-implementation.patch +++ b/patches/server/Add-Alternate-Current-redstone-implementation.patch @@ -2038,10 +2038,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- 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 { - return range <= 0 ? 64.0 * 64.0 : range * range; // 64 is taken from default in ServerLevel#levelEvent + } } - // Paper end - respect global sound events gamerule -+ + // Paper end - notify observers even if grow failed + // Paper start - optimize redstone (Alternate Current) + public alternate.current.wire.WireHandler getWireHandler() { + // This method is overridden in ServerLevel. diff --git a/patches/server/Add-option-to-disable-block-updates.patch b/patches/server/Add-option-to-disable-block-updates.patch index ea355dd571..81696e2a63 100644 --- a/patches/server/Add-option-to-disable-block-updates.patch +++ b/patches/server/Add-option-to-disable-block-updates.patch @@ -139,7 +139,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean moved) { + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating if (!moved && !state.is(newState.getBlock())) { - this.updateSource(world, pos, (BlockState) state.setValue(TripWireBlock.POWERED, true), true); // Paper - fix tripwire state inconsistency + this.updateSource(world, pos, (BlockState) state.setValue(TripWireBlock.POWERED, true)); } @@ -0,0 +0,0 @@ public class TripWireBlock extends Block { @@ -154,9 +154,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 private void updateSource(Level world, BlockPos pos, BlockState state) { + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating - // Paper start - fix tripwire state inconsistency - this.updateSource(world, pos, state, false); - } + Direction[] aenumdirection = new Direction[]{Direction.SOUTH, Direction.WEST}; + int i = aenumdirection.length; + int j = 0; @@ -0,0 +0,0 @@ public class TripWireBlock extends Block { @Override diff --git a/patches/server/Add-support-for-Proxy-Protocol.patch b/patches/server/Add-support-for-Proxy-Protocol.patch index e0112e3308..4bc15d9cb1 100644 --- a/patches/server/Add-support-for-Proxy-Protocol.patch +++ b/patches/server/Add-support-for-Proxy-Protocol.patch @@ -20,19 +20,6 @@ diff --git a/src/main/java/net/minecraft/server/network/ServerConnectionListener index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java +++ b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java -@@ -0,0 +0,0 @@ public class ServerConnectionListener { - ServerConnectionListener.LOGGER.info("Paper: Using " + com.velocitypowered.natives.util.Natives.cipher.getLoadedVariant() + " cipher from Velocity."); - // Paper end - Use Velocity cipher - -+ // Paper start - Add support for proxy protocol -+ if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.proxyProtocol) { -+ ServerConnectionListener.LOGGER.info("Paper: Using Proxy Protocol"); -+ } -+ // Paper end - Add support for proxy protocol -+ - this.channels.add(((ServerBootstrap) ((ServerBootstrap) (new ServerBootstrap()).channel(oclass)).childHandler(new ChannelInitializer() { - protected void initChannel(Channel channel) { - Connection.setInitialProtocolAttributes(channel); @@ -0,0 +0,0 @@ public class ServerConnectionListener { Connection object = j > 0 ? new RateKickingConnection(j) : new Connection(PacketFlow.SERVERBOUND); // CraftBukkit - decompile error diff --git a/patches/server/Attempt-to-recalculate-regionfile-header-if-it-is-co.patch b/patches/server/Attempt-to-recalculate-regionfile-header-if-it-is-co.patch index 62acc818e8..6274175cc6 100644 --- a/patches/server/Attempt-to-recalculate-regionfile-header-if-it-is-co.patch +++ b/patches/server/Attempt-to-recalculate-regionfile-header-if-it-is-co.patch @@ -448,11 +448,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable { public RegionFile(Path file, Path directory, boolean dsync) throws IOException { - this(file, directory, RegionFileVersion.VERSION_DEFLATE, dsync); + this(file, directory, RegionFileVersion.getCompressionFormat(), dsync); // Paper - Configurable region compression format } + // Paper start - add can recalc flag + public RegionFile(Path file, Path directory, boolean dsync, boolean canRecalcHeader) throws IOException { -+ this(file, directory, RegionFileVersion.VERSION_DEFLATE, dsync, canRecalcHeader); ++ this(file, directory, RegionFileVersion.getCompressionFormat(), dsync, canRecalcHeader); + } + // Paper end - add can recalc flag diff --git a/patches/server/Collision-optimisations.patch b/patches/server/Collision-optimisations.patch index 511b53c285..8e35077639 100644 --- a/patches/server/Collision-optimisations.patch +++ b/patches/server/Collision-optimisations.patch @@ -2185,7 +2185,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class ServerPlayer extends Player { if (blockposition1 != null) { - this.moveTo(blockposition1, 0.0F, 0.0F); + this.moveTo(blockposition1, world.getSharedSpawnAngle(), 0.0F); // Paper - MC-200092 - fix first spawn pos yaw being ignored - if (world.noCollision((Entity) this)) { + if (world.noCollision(this, this.getBoundingBox(), true)) { // Paper - make sure this loads chunks, we default to NOT loading now break; @@ -2193,7 +2193,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } @@ -0,0 +0,0 @@ public class ServerPlayer extends Player { } else { - this.moveTo(blockposition, 0.0F, 0.0F); + this.moveTo(blockposition, world.getSharedSpawnAngle(), 0.0F); // Paper - MC-200092 - fix first spawn pos yaw being ignored - while (!world.noCollision((Entity) this) && this.getY() < (double) (world.getMaxBuildHeight() - 1)) { + while (!world.noCollision(this, this.getBoundingBox(), true) && this.getY() < (double) (world.getMaxBuildHeight() - 1)) { // Paper - make sure this loads chunks, we default to NOT loading now @@ -3172,18 +3172,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } @@ -0,0 +0,0 @@ public class LevelChunkSection { + } } - } -+ // Paper start - optimise collisions -+ if (io.papermc.paper.util.CollisionUtil.isSpecialCollidingBlock(iblockdata)) { -+ ++this.specialCollidingBlocks; -+ } -+ // Paper end - optimise collisions -+ - }); ++ // Paper start - optimise collisions ++ if (io.papermc.paper.util.CollisionUtil.isSpecialCollidingBlock(iblockdata)) { ++ ++this.specialCollidingBlocks; ++ } ++ // Paper end - optimise collisions + }); + } // Paper end - } diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java diff --git a/patches/server/Configurable-Region-Compression-Format.patch b/patches/server/Configurable-Region-Compression-Format.patch index 1b8c685454..4e8a3fa2c2 100644 --- a/patches/server/Configurable-Region-Compression-Format.patch +++ b/patches/server/Configurable-Region-Compression-Format.patch @@ -15,13 +15,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - this(file, directory, RegionFileVersion.VERSION_DEFLATE, dsync); + this(file, directory, RegionFileVersion.getCompressionFormat(), dsync); // Paper - Configurable region compression format } - // Paper start - add can recalc flag - public RegionFile(Path file, Path directory, boolean dsync, boolean canRecalcHeader) throws IOException { -- this(file, directory, RegionFileVersion.VERSION_DEFLATE, dsync, canRecalcHeader); -+ this(file, directory, RegionFileVersion.getCompressionFormat(), dsync, canRecalcHeader); // Paper - Configurable region compression format - } - // Paper end - add can recalc flag + public RegionFile(Path file, Path directory, RegionFileVersion outputChunkStreamVersion, boolean dsync) throws IOException { diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileVersion.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileVersion.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileVersion.java diff --git a/patches/server/Detail-more-information-in-watchdog-dumps.patch b/patches/server/Detail-more-information-in-watchdog-dumps.patch index da711708b8..be6404e2d6 100644 --- a/patches/server/Detail-more-information-in-watchdog-dumps.patch +++ b/patches/server/Detail-more-information-in-watchdog-dumps.patch @@ -56,7 +56,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class PacketUtils { public static void ensureRunningOnSameThread(Packet packet, T listener, BlockableEventLoop engine) throws RunningOnDifferentThreadException { if (!engine.isSameThread()) { - engine.executeIfPossible(() -> { + engine.execute(() -> { // Paper - Fix preemptive player kick on a server shutdown + packetProcessing.push(listener); // Paper - detailed watchdog information + try { // Paper - detailed watchdog information if (MinecraftServer.getServer().hasStopped() || (listener instanceof ServerCommonPacketListenerImpl && ((ServerCommonPacketListenerImpl) listener).processedDisconnect)) return; // CraftBukkit, MC-142590 diff --git a/patches/server/Distance-manager-tick-timings.patch b/patches/server/Distance-manager-tick-timings.patch index 232113d1b4..71bb4f3302 100644 --- a/patches/server/Distance-manager-tick-timings.patch +++ b/patches/server/Distance-manager-tick-timings.patch @@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public static final Timing scoreboardScoreSearch = Timings.ofSafe("Scoreboard score search"); // Paper - add timings for scoreboard search + public static final Timing distanceManagerTick = Timings.ofSafe("Distance Manager Tick"); // Paper - add timings for distance manager - public static final Timing midTickChunkTasks = Timings.ofSafe("Mid Tick Chunk Tasks"); + private static final Map, String> taskNameCache = new MapMaker().weakKeys().makeMap(); diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/patches/server/Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch b/patches/server/Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch index b690942d94..528f738788 100644 --- a/patches/server/Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch +++ b/patches/server/Execute-chunk-tasks-fairly-for-worlds-while-waiting-.patch @@ -13,7 +13,7 @@ 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 { - StringReader stringreader = new StringReader(suggestionsbuilder.getInput()); - - stringreader.setCursor(suggestionsbuilder.getStart()); -- EntitySelectorParser argumentparserselector = new EntitySelectorParser(stringreader, icompletionprovider.hasPermission(2)); -+ EntitySelectorParser argumentparserselector = new EntitySelectorParser(stringreader, icompletionprovider.hasPermission(2), true); // Paper - tell clients to ask server for suggestions for EntityArguments + final boolean permission = object instanceof CommandSourceStack stack + ? stack.bypassSelectorPermissions || stack.hasPermission(2, "minecraft.command.selector") + : icompletionprovider.hasPermission(2); +- EntitySelectorParser argumentparserselector = new EntitySelectorParser(stringreader, permission); ++ EntitySelectorParser argumentparserselector = new EntitySelectorParser(stringreader, permission, true); // Paper - tell clients to ask server for suggestions for EntityArguments + // Paper end - Fix EntityArgument suggestion permissions try { - argumentparserselector.parse(); @@ -0,0 +0,0 @@ public class EntityArgument implements ArgumentType { } diff --git a/patches/server/Fix-player-kick-on-shutdown.patch b/patches/server/Fix-player-kick-on-shutdown.patch index 12bb3a4f13..a07bc946ad 100644 --- a/patches/server/Fix-player-kick-on-shutdown.patch +++ b/patches/server/Fix-player-kick-on-shutdown.patch @@ -18,6 +18,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (!engine.isSameThread()) { - engine.executeIfPossible(() -> { + engine.execute(() -> { // Paper - Fix preemptive player kick on a server shutdown - packetProcessing.push(listener); // Paper - detailed watchdog information - try { // Paper - detailed watchdog information if (MinecraftServer.getServer().hasStopped() || (listener instanceof ServerCommonPacketListenerImpl && ((ServerCommonPacketListenerImpl) listener).processedDisconnect)) return; // CraftBukkit, MC-142590 + if (listener.shouldHandleMessage(packet)) { + co.aikar.timings.Timing timing = co.aikar.timings.MinecraftTimings.getPacketTiming(packet); // Paper - timings diff --git a/patches/server/Fix-tripwire-state-inconsistency.patch b/patches/server/Fix-tripwire-state-inconsistency.patch index e244d24060..ebab9a86d0 100644 --- a/patches/server/Fix-tripwire-state-inconsistency.patch +++ b/patches/server/Fix-tripwire-state-inconsistency.patch @@ -10,8 +10,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/level/block/TripWireBlock.java +++ b/src/main/java/net/minecraft/world/level/block/TripWireBlock.java @@ -0,0 +0,0 @@ public class TripWireBlock extends Block { - @Override public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean moved) { + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating if (!moved && !state.is(newState.getBlock())) { - this.updateSource(world, pos, (BlockState) state.setValue(TripWireBlock.POWERED, true)); + this.updateSource(world, pos, (BlockState) state.setValue(TripWireBlock.POWERED, true), true); // Paper - fix tripwire state inconsistency @@ -19,9 +19,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } @@ -0,0 +0,0 @@ public class TripWireBlock extends Block { - } private void updateSource(Level world, BlockPos pos, BlockState state) { + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates) return; // Paper - prevent adjacent tripwires from updating + // Paper start - fix tripwire state inconsistency + this.updateSource(world, pos, state, false); + } diff --git a/patches/server/Implement-PlayerFailMoveEvent.patch b/patches/server/Implement-PlayerFailMoveEvent.patch index 160794b2e7..a7c20560a0 100644 --- a/patches/server/Implement-PlayerFailMoveEvent.patch +++ b/patches/server/Implement-PlayerFailMoveEvent.patch @@ -57,44 +57,46 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } } @@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - boolean flag2 = false; + + d8 = d2 - this.player.getZ(); + d10 = d6 * d6 + d7 * d7 + d8 * d8; +- boolean flag2 = false; ++ boolean movedWrongly = false; // Paper - Add fail move event; rename if (!this.player.isChangingDimension() && d10 > org.spigotmc.SpigotConfig.movedWronglyThreshold && !this.player.isSleeping() && !this.player.gameMode.isCreative() && this.player.gameMode.getGameModeForPlayer() != GameType.SPECTATOR) { // Spigot +- flag2 = true; + // Paper start - Add fail move event + io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_WRONGLY, + toX, toY, toZ, toYaw, toPitch, true); + if (!event.isAllowed()) { - flag2 = true; // Paper - diff on change, this should be moved wrongly ++ movedWrongly = true; + if (event.getLogWarning()) ServerGamePacketListenerImpl.LOGGER.warn("{} moved wrongly!", this.player.getName().getString()); + } + } + +- if (!this.player.noPhysics && !this.player.isSleeping() && (flag2 && worldserver.noCollision(this.player, axisalignedbb) || this.isPlayerCollidingWithAnythingNew(worldserver, axisalignedbb, d0, d1, d2))) { ++ boolean teleportBack = !this.player.noPhysics && !this.player.isSleeping() && (movedWrongly && worldserver.noCollision(this.player, axisalignedbb) || this.isPlayerCollidingWithAnythingNew(worldserver, axisalignedbb, d0, d1, d2)); ++ 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); ++ if (event.isAllowed()) { ++ teleportBack = false; ++ } ++ } ++ if (teleportBack) { + // Paper end - Add fail move event - } + this.internalTeleport(d3, d4, d5, f, f1, Collections.emptySet()); // CraftBukkit - SPIGOT-1807: Don't call teleport event, when the client thinks the player is falling, because the chunks are not loaded on the client yet. + this.player.doCheckFallDamage(this.player.getX() - d3, this.player.getY() - d4, this.player.getZ() - d5, packet.isOnGround()); + } else { +@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - // Paper start - optimise out extra getCubes -@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - if (didCollide || !axisalignedbb.equals(newBox)) { - // note: only call after setLocation, or else getBoundingBox is wrong - teleportBack = this.hasNewCollision(worldserver, this.player, axisalignedbb, newBox); -+ // Paper start - Add fail move event -+ 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); -+ if (event.isAllowed()) { -+ teleportBack = false; -+ } -+ } -+ // Paper end - Add fail move event - } // else: no collision at all detected, why do we care? - } - if (!this.player.noPhysics && !this.player.isSleeping() && teleportBack) { // Paper end - optimise out extra getCubes -@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - } + InteractionResult run(ServerPlayer player, Entity entity, InteractionHand hand); } - ++ + // Paper start - Add fail move event + private io.papermc.paper.event.player.PlayerFailMoveEvent fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason failReason, -+ double toX, double toY, double toZ, float toYaw, float toPitch, boolean logWarning) { ++ double toX, double toY, double toZ, float toYaw, float toPitch, boolean logWarning) { + Player player = this.getCraftPlayer(); + Location from = new Location(player.getWorld(), this.lastPosX, this.lastPosY, this.lastPosZ, this.lastYaw, this.lastPitch); + Location to = new Location(player.getWorld(), toX, toY, toZ, toYaw, toPitch); @@ -104,6 +106,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return event; + } + // Paper end - Add fail move event - // Paper start - optimise out extra getCubes - private boolean hasNewCollision(final ServerLevel world, final Entity entity, final AABB oldBox, final AABB newBox) { - final List collisionsBB = new java.util.ArrayList<>(); + } diff --git a/patches/server/Only-capture-actual-tree-growth.patch b/patches/server/Only-capture-actual-tree-growth.patch index 2948f2da99..cf47deabea 100644 --- a/patches/server/Only-capture-actual-tree-growth.patch +++ b/patches/server/Only-capture-actual-tree-growth.patch @@ -33,9 +33,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- 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 { - return null; + return range <= 0 ? 64.0 * 64.0 : range * range; // 64 is taken from default in ServerLevel#levelEvent } - // Paper end - optimize redstone (Alternate Current) + // Paper end - respect global sound events gamerule + // Paper start - notify observers even if grow failed + public void checkCapturedTreeStateForObserverNotify(final BlockPos pos, final CraftBlockState craftBlockState) { + // notify observers if the block state is the same and the Y level equals the original y level (for mega trees) diff --git a/patches/server/Optimise-collision-checking-in-player-move-packet-ha.patch b/patches/server/Optimise-collision-checking-in-player-move-packet-ha.patch index a14869f8ef..4891c51adf 100644 --- a/patches/server/Optimise-collision-checking-in-player-move-packet-ha.patch +++ b/patches/server/Optimise-collision-checking-in-player-move-packet-ha.patch @@ -116,20 +116,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (this.awaitingPositionFromClient != null) { return; // ... thanks Mojang for letting move calls teleport across dimensions. @@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl - boolean flag2 = false; - - if (!this.player.isChangingDimension() && d10 > org.spigotmc.SpigotConfig.movedWronglyThreshold && !this.player.isSleeping() && !this.player.gameMode.isCreative() && this.player.gameMode.getGameModeForPlayer() != GameType.SPECTATOR) { // Spigot -- flag2 = true; -+ flag2 = true; // Paper - diff on change, this should be moved wrongly - ServerGamePacketListenerImpl.LOGGER.warn("{} moved wrongly!", this.player.getName().getString()); + } } -- if (!this.player.noPhysics && !this.player.isSleeping() && (flag2 && worldserver.noCollision(this.player, axisalignedbb) || this.isPlayerCollidingWithAnythingNew(worldserver, axisalignedbb, d0, d1, d2))) { +- boolean teleportBack = !this.player.noPhysics && !this.player.isSleeping() && (movedWrongly && worldserver.noCollision(this.player, axisalignedbb) || this.isPlayerCollidingWithAnythingNew(worldserver, axisalignedbb, d0, d1, d2)); + // Paper start - optimise out extra getCubes ++ boolean teleportBack = !this.player.noPhysics && !this.player.isSleeping() && movedWrongly; + this.player.absMoveTo(d0, d1, d2, f, f1); // prevent desync by tping to the set position, dropped for unknown reasons by mojang -+ // Original for reference: -+ // boolean teleportBack = flag2 && worldserver.getCubes(this.player, axisalignedbb) || (didCollide && this.a((IWorldReader) worldserver, axisalignedbb)); -+ boolean teleportBack = flag2; // violating this is always a fail + if (!this.player.noPhysics && !this.player.isSleeping() && !teleportBack) { + AABB newBox = this.player.getBoundingBox(); + if (didCollide || !axisalignedbb.equals(newBox)) { @@ -137,10 +130,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + teleportBack = this.hasNewCollision(worldserver, this.player, axisalignedbb, newBox); + } // else: no collision at all detected, why do we care? + } -+ if (!this.player.noPhysics && !this.player.isSleeping() && teleportBack) { // Paper end - optimise out extra getCubes - this.internalTeleport(d3, d4, d5, f, f1, Collections.emptySet()); // CraftBukkit - SPIGOT-1807: Don't call teleport event, when the client thinks the player is falling, because the chunks are not loaded on the client yet. - this.player.doCheckFallDamage(this.player.getX() - d3, this.player.getY() - d4, this.player.getZ() - d5, packet.isOnGround()); - } else { ++ // Paper end - optimise out extra getCubes + 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); @@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } } diff --git a/patches/server/Optimise-random-block-ticking.patch b/patches/server/Optimise-random-block-ticking.patch index 37db335129..a438e2e9d1 100644 --- a/patches/server/Optimise-random-block-ticking.patch +++ b/patches/server/Optimise-random-block-ticking.patch @@ -392,50 +392,45 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - a() {} - - public void accept(BlockState iblockdata, int i) { -- FluidState fluid = iblockdata.getFluidState(); -- -- if (!iblockdata.isAir()) { -- this.nonEmptyBlockCount += i; -- if (iblockdata.isRandomlyTicking()) { -- this.tickingBlockCount += i; -- } + // Paper start - unfuck this + this.tickingList.clear(); + this.nonEmptyBlockCount = 0; + this.tickingBlockCount = 0; + this.tickingFluidCount = 0; -+ this.states.forEachLocation((BlockState iblockdata, int i) -> { -+ FluidState fluid = iblockdata.getFluidState(); -+ -+ if (!iblockdata.isAir()) { -+ this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1); -+ if (iblockdata.isRandomlyTicking()) { -+ this.tickingBlockCount = (short)(this.tickingBlockCount + 1); -+ this.tickingList.add(i, iblockdata); - } -+ } ++ // Don't run this on clearly empty sections ++ if (this.maybeHas((BlockState state) -> !state.isAir() || !state.getFluidState().isEmpty())) { ++ this.states.forEachLocation((BlockState iblockdata, int i) -> { + FluidState fluid = iblockdata.getFluidState(); -- if (!fluid.isEmpty()) { + if (!iblockdata.isAir()) { - this.nonEmptyBlockCount += i; -- if (fluid.isRandomlyTicking()) { -- this.tickingFluidCount += i; -- } -+ if (!fluid.isEmpty()) { -+ this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1); -+ if (fluid.isRandomlyTicking()) { -+ this.tickingFluidCount = (short) (this.tickingFluidCount + 1); ++ this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1); + if (iblockdata.isRandomlyTicking()) { +- this.tickingBlockCount += i; ++ this.tickingBlockCount = (short)(this.tickingBlockCount + 1); ++ this.tickingList.add(i, iblockdata); + } } -- - } -- } + if (!fluid.isEmpty()) { +- this.nonEmptyBlockCount += i; ++ this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1); + if (fluid.isRandomlyTicking()) { +- this.tickingFluidCount += i; ++ this.tickingFluidCount = (short) (this.tickingFluidCount + 1); + } + } + +- } ++ }); + } +- - a a0 = new a(); - - this.states.count(a0); - this.nonEmptyBlockCount = (short) a0.nonEmptyBlockCount; - this.tickingBlockCount = (short) a0.tickingBlockCount; - this.tickingFluidCount = (short) a0.tickingFluidCount; -+ }); + // Paper end } diff --git a/patches/server/Optimise-recalcBlockCounts-for-empty-sections.patch b/patches/server/Optimise-recalcBlockCounts-for-empty-sections.patch deleted file mode 100644 index b7bc40bb44..0000000000 --- a/patches/server/Optimise-recalcBlockCounts-for-empty-sections.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Mon, 15 May 2023 20:25:26 -0700 -Subject: [PATCH] Optimise recalcBlockCounts() for empty sections - -In 1.18, every chunk section is initialised to a non-null value -and recalcBlockCounts() is invoked for each section. -However, in a standard world, most sections are empty. In such cases, -recalcBlockCounts() would iterate over ever position - even though -the block data would all be air. To avoid this, we skip -searching the section unless the palette indicates there _could_ be -a non-air block state or non-empty fluid state. - -Chunk loading initially showed that recalcBlockCounts() over -sections with a ZeroBitStorage data to to take ~20% of the process, -now it takes <1%. - -diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java -+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java -@@ -0,0 +0,0 @@ public class LevelChunkSection { - this.nonEmptyBlockCount = 0; - this.tickingBlockCount = 0; - this.tickingFluidCount = 0; -+ if (this.maybeHas((BlockState state) -> !state.isAir() || !state.getFluidState().isEmpty())) { // Paper - Perf: do not run forEachLocation on clearly empty sections - this.states.forEachLocation((BlockState iblockdata, int i) -> { - FluidState fluid = iblockdata.getFluidState(); - -@@ -0,0 +0,0 @@ public class LevelChunkSection { - // Paper end - optimise collisions - - }); -+ } // Paper - Perf: do not run forEachLocation on clearly empty sections - // Paper end - } - diff --git a/scripts/moveback.py b/scripts/moveback.py new file mode 100644 index 0000000000..744f101a1e --- /dev/null +++ b/scripts/moveback.py @@ -0,0 +1,44 @@ +import os +import sys + +# Use inside of server patch dir +# py ../../scripts/moveback.py '' +patch_target = 1038 # TODO: Update this + + +def increment_number(filename): + current_number = int(filename[:4]) + new_number = current_number + 1 + return f"{new_number:04d}-{filename[5:]}" + + +if len(sys.argv) != 2: + print("python moveback.py ''") + sys.exit(1) + +input_string = sys.argv[1].replace(' ', '-').lower() +if len(input_string) < 5: + print("Commit title is too short") + sys.exit(1) + +matching_files = [file for file in os.listdir() if input_string in file.lower()] + +if len(matching_files) == 0: + print("No file found matching the given string") + sys.exit(1) + +matching_file = matching_files[0] +print(f"Found: {matching_file}") + +# Move all files after the target one up +for file in os.listdir(): + num = int(file[:4]) + if num >= patch_target: + new_filename = increment_number(file) + os.rename(file, new_filename) + print(f"Renamed {file} to {new_filename}") + +# Rename the file to the target +new_filename = f"{patch_target:04d}-{matching_file[5:]}" +os.rename(matching_file, new_filename) +print(f"Renamed {matching_file} to {new_filename}")