diff --git a/gradle.properties b/gradle.properties index e55b90010..c173a518c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ group = org.purpurmc.purpur version = 1.21.6-R0.1-SNAPSHOT mcVersion = 1.21.6 -paperCommit = e454fef40e1e1e7a889327d3371fc7b5ff2b68df +paperCommit = 4e1a2555be7ff1e6960714ee7fbabc13fa25d4c2 org.gradle.configuration-cache = true org.gradle.caching = true diff --git a/purpur-server/minecraft-patches/features/0001-Ridables.patch b/purpur-server/minecraft-patches/features/0001-Ridables.patch index 575ef64d1..c0b8f4757 100644 --- a/purpur-server/minecraft-patches/features/0001-Ridables.patch +++ b/purpur-server/minecraft-patches/features/0001-Ridables.patch @@ -18,10 +18,10 @@ index 61ab8b508d2b614d0f05ae4cc23dc214f8e95a1d..d6e8bd3b302f821b286b15db3d66c8b2 public boolean isClientAuthoritative() { return false; diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index 3a07d62d6f00bc261b0ac9edd039cdd4c6e20556..81c5d821ea566b738904ee8005d39f524ff92587 100644 +index ef5c6a760eb6e72beab186a315bd02e804c9ae53..306230339574bc35a309877033fa6012e4596f08 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -1746,6 +1746,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - Add EntityMoveEvent serverLevel.updateLagCompensationTick(); // Paper - lag compensation net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = serverLevel.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper - Perf: Optimize Hoppers @@ -42,10 +42,10 @@ index 83eff33884bffddfafc85eeb4a2900104a396e2e..3c7159d0981c948e71a5612ba4083acc @Override public @Nullable LevelChunk getChunkIfLoaded(int x, int z) { diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index cb8b23e04d9315c733856a2e2956cfbf5860d516..1ac6488820c569e84c5666ce58223b321dab7a39 100644 +index 63ef4690ff76df961fcc51dabd0f4f3d7de09fe9..7adb3d1f75896f1e31747e3356b124948a1c77c0 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -797,6 +797,15 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -861,6 +861,15 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc this.trackEnteredOrExitedLavaOnVehicle(); this.updatePlayerAttributes(); this.advancements.flushDirty(this, true); @@ -62,7 +62,7 @@ index cb8b23e04d9315c733856a2e2956cfbf5860d516..1ac6488820c569e84c5666ce58223b32 private void updatePlayerAttributes() { diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 014557e343d3ede351b3a2b950bb803d7e771490..628b1a5ac93d7cd1be8175aab88d2f5e29b60257 100644 +index 8a04052908fa53028b7d5a4619908d12b1e10766..79c3baf041cb7f10753d8a01ec03e95d5564f21b 100644 --- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -2844,6 +2844,8 @@ public class ServerGamePacketListenerImpl @@ -75,7 +75,7 @@ index 014557e343d3ede351b3a2b950bb803d7e771490..628b1a5ac93d7cd1be8175aab88d2f5e if ((target instanceof net.minecraft.world.entity.animal.Bucketable && target instanceof LivingEntity && origItem != null && origItem == Items.WATER_BUCKET) && (event.isCancelled() || ServerGamePacketListenerImpl.this.player.getInventory().getSelectedItem().isEmpty() || !ServerGamePacketListenerImpl.this.player.getInventory().getSelectedItem().is(origItem))) { target.resendPossiblyDesyncedEntityData(ServerGamePacketListenerImpl.this.player); // Paper - The entire mob gets deleted, so resend it diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 0e1c463d53c02454f0770f7ad547768f5ba0ca02..a2a7b927cb36ef8b1f98f452ea4169b8e2d540e9 100644 +index 1d8ba25d542c49a687414a8b6d1d2fa16ca695d5..34e0fbef06b0c7aededf27fe9dc64f3f6f33e3ae 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -3303,6 +3303,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -107,7 +107,7 @@ index 0e1c463d53c02454f0770f7ad547768f5ba0ca02..a2a7b927cb36ef8b1f98f452ea4169b8 if (this.passengers.size() == 1 && this.passengers.get(0) == passenger) { this.passengers = ImmutableList.of(); } else { -@@ -5403,4 +5418,44 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -5398,4 +5413,44 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return ((ServerLevel) this.level()).isPositionEntityTicking(this.blockPosition()); } // Paper end - Expose entity id counter @@ -3009,7 +3009,7 @@ index c4a2fb6f08e5d6d69571f448c6ac9defaac3fcd3..2c6158de44a8ba95d3c5124ed2827a0a public boolean isPowered() { diff --git a/net/minecraft/world/entity/monster/AbstractSkeleton.java b/net/minecraft/world/entity/monster/AbstractSkeleton.java -index fa124fc779aaf7c1747a2007a2d5826cd4fde13a..caa018d1dd0b6e97ec9d3fa70bbffe9eb3b1edec 100644 +index 4e14f1a9ee22d08065a3e971c2aecc9363ebff13..352d0655374e05da787225c3fce8803fa547c99d 100644 --- a/net/minecraft/world/entity/monster/AbstractSkeleton.java +++ b/net/minecraft/world/entity/monster/AbstractSkeleton.java @@ -73,12 +73,14 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo @@ -3731,7 +3731,7 @@ index 8d6def85583a111841b28f20f58ddb8b8cbd7bc1..0335e85f196363c06597812149e9a93c EntityType entityType, ServerLevelAccessor level, EntitySpawnReason spawnReason, BlockPos pos, RandomSource random ) { diff --git a/net/minecraft/world/entity/monster/Illusioner.java b/net/minecraft/world/entity/monster/Illusioner.java -index ec090d191969983c31950b8376bbb36ee8fce922..304a1ce41071e5597859b1235fa014f966ff5cfb 100644 +index 7441b019f669653e3e738f27c866270c30acffd4..bb2649001f0b31676a51378745818d5c5b15c443 100644 --- a/net/minecraft/world/entity/monster/Illusioner.java +++ b/net/minecraft/world/entity/monster/Illusioner.java @@ -57,10 +57,28 @@ public class Illusioner extends SpellcasterIllager implements RangedAttackMob { diff --git a/purpur-server/minecraft-patches/features/0006-Minecart-settings-and-WASD-controls.patch b/purpur-server/minecraft-patches/features/0006-Minecart-settings-and-WASD-controls.patch index b98b25d8b..e75ec1e8a 100644 --- a/purpur-server/minecraft-patches/features/0006-Minecart-settings-and-WASD-controls.patch +++ b/purpur-server/minecraft-patches/features/0006-Minecart-settings-and-WASD-controls.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Minecart settings and WASD controls diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index 1ac6488820c569e84c5666ce58223b321dab7a39..853d54a28a348492372eb38b50b155a6644129e4 100644 +index 7adb3d1f75896f1e31747e3356b124948a1c77c0..a8d3db032f9a808419b4c3a3790c65a63a31ab9d 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -1206,6 +1206,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -1270,6 +1270,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc } else { // Purpur start - Add boat fall damage config if (damageSource.is(net.minecraft.tags.DamageTypeTags.IS_FALL)) { diff --git a/purpur-server/minecraft-patches/features/0018-API-for-any-mob-to-burn-daylight.patch b/purpur-server/minecraft-patches/features/0018-API-for-any-mob-to-burn-daylight.patch index 85ed6f5d2..82914d436 100644 --- a/purpur-server/minecraft-patches/features/0018-API-for-any-mob-to-burn-daylight.patch +++ b/purpur-server/minecraft-patches/features/0018-API-for-any-mob-to-burn-daylight.patch @@ -6,7 +6,7 @@ Subject: [PATCH] API for any mob to burn daylight Co-authored by: Encode42 diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index d4f9a29cfbb59d557eef790ca07575187c99854b..068ce6f155abf3bda758f2bcdb4377836c610945 100644 +index 34e0fbef06b0c7aededf27fe9dc64f3f6f33e3ae..ce3e5ec505ac37c820436bcf7c7d6452ff015f70 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -542,6 +542,24 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -122,7 +122,7 @@ index e05cf29c630d43c66614012c50b9dd4ece4c44f6..b0a5f79eb2c3ea84fd37eaa653a4f2c8 @Override diff --git a/net/minecraft/world/entity/monster/AbstractSkeleton.java b/net/minecraft/world/entity/monster/AbstractSkeleton.java -index caa018d1dd0b6e97ec9d3fa70bbffe9eb3b1edec..d69d5b575e93b4ae9a0e2b311352fd3790d464c6 100644 +index 352d0655374e05da787225c3fce8803fa547c99d..53ab51ffa5dd7d30a25f17dea0d9106bf30b49ba 100644 --- a/net/minecraft/world/entity/monster/AbstractSkeleton.java +++ b/net/minecraft/world/entity/monster/AbstractSkeleton.java @@ -64,11 +64,12 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo @@ -168,7 +168,7 @@ index caa018d1dd0b6e97ec9d3fa70bbffe9eb3b1edec..d69d5b575e93b4ae9a0e2b311352fd37 super.aiStep(); } -@@ -242,14 +223,14 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo +@@ -245,14 +226,14 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo protected void readAdditionalSaveData(ValueInput input) { super.readAdditionalSaveData(input); this.reassessWeaponGoal(); diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/commands/Commands.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/commands/Commands.java.patch index d1e4a9e22..8824ef4bc 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/commands/Commands.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/commands/Commands.java.patch @@ -24,7 +24,7 @@ } if (selection.includeIntegrated) { -@@ -502,6 +_,7 @@ +@@ -504,6 +_,7 @@ private void runSync(ServerPlayer player, java.util.Collection bukkit, RootCommandNode rootCommandNode) { // Paper end - Perf: Async command map building new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendCommandsEvent(player.getBukkitEntity(), (RootCommandNode) rootCommandNode, true).callEvent(); // Paper - Brigadier API @@ -32,7 +32,7 @@ org.bukkit.event.player.PlayerCommandSendEvent event = new org.bukkit.event.player.PlayerCommandSendEvent(player.getBukkitEntity(), new java.util.LinkedHashSet<>(bukkit)); event.getPlayer().getServer().getPluginManager().callEvent(event); -@@ -512,6 +_,8 @@ +@@ -514,6 +_,8 @@ } } // CraftBukkit end diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/server/MinecraftServer.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/server/MinecraftServer.java.patch index 934c7f900..6cfd1baa6 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/server/MinecraftServer.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/server/MinecraftServer.java.patch @@ -112,7 +112,7 @@ this.startMeasuringTaskExecutionTime(); this.waitUntilNextTick(); this.finishMeasuringTaskExecutionTime(); -@@ -1691,7 +_,7 @@ +@@ -1689,7 +_,7 @@ long worldTime = level.getGameTime(); final ClientboundSetTimePacket worldPacket = new ClientboundSetTimePacket(worldTime, dayTime, doDaylight); for (Player entityhuman : level.players()) { @@ -121,7 +121,7 @@ continue; } ServerPlayer entityplayer = (ServerPlayer) entityhuman; -@@ -1856,7 +_,7 @@ +@@ -1854,7 +_,7 @@ @DontObfuscate public String getServerModName() { diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/server/level/ServerPlayer.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/server/level/ServerPlayer.java.patch index a03daa6d8..14617339c 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/server/level/ServerPlayer.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/server/level/ServerPlayer.java.patch @@ -11,7 +11,7 @@ // Paper start - rewrite chunk system private ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader; -@@ -564,6 +_,10 @@ +@@ -628,6 +_,10 @@ this.respawnConfig = input.read("respawn", ServerPlayer.RespawnConfig.CODEC).orElse(null); this.spawnExtraParticlesOnFall = input.getBooleanOr("spawn_extra_particles_on_fall", false); this.raidOmenPosition = input.read("raid_omen_position", BlockPos.CODEC).orElse(null); @@ -22,7 +22,7 @@ } @Override -@@ -581,6 +_,9 @@ +@@ -645,6 +_,9 @@ output.storeNullable("raid_omen_position", BlockPos.CODEC, this.raidOmenPosition); this.saveEnderPearls(output); this.getBukkitEntity().setExtraData(output); // CraftBukkit @@ -32,7 +32,7 @@ } private void saveParentVehicle(ValueOutput output) { -@@ -1077,6 +_,7 @@ +@@ -1141,6 +_,7 @@ // Paper - moved up to sendClientboundPlayerCombatKillPacket() sendClientboundPlayerCombatKillPacket(event.getShowDeathMessages(), deathScreenMessage); // Paper - Expand PlayerDeathEvent Team team = this.getTeam(); @@ -40,7 +40,7 @@ if (team == null || team.getDeathMessageVisibility() == Team.Visibility.ALWAYS) { this.server.getPlayerList().broadcastSystemMessage(deathMessage, false); } else if (team.getDeathMessageVisibility() == Team.Visibility.HIDE_FOR_OTHER_TEAMS) { -@@ -1183,6 +_,13 @@ +@@ -1247,6 +_,13 @@ if (this.isInvulnerableTo(level, damageSource)) { return false; } else { @@ -54,7 +54,7 @@ Entity entity = damageSource.getEntity(); if (!( // Paper - split the if statement. If below statement is false, hurtServer would not have been evaluated. Return false. !(entity instanceof Player player && !this.canHarmPlayer(player)) -@@ -1427,6 +_,7 @@ +@@ -1491,6 +_,7 @@ serverLevel.removePlayerImmediately(this, Entity.RemovalReason.CHANGED_DIMENSION); this.unsetRemoved(); // CraftBukkit end @@ -62,7 +62,7 @@ this.setServerLevel(level); this.connection.internalTeleport(PositionMoveRotation.of(teleportTransition), teleportTransition.relatives()); // CraftBukkit - use internal teleport without event this.connection.resetPosition(); -@@ -1543,7 +_,7 @@ +@@ -1607,7 +_,7 @@ new AABB(vec3.x() - 8.0, vec3.y() - 5.0, vec3.z() - 8.0, vec3.x() + 8.0, vec3.y() + 5.0, vec3.z() + 8.0), monster -> monster.isPreventingPlayerRest(this.level(), this) ); @@ -71,7 +71,7 @@ return Either.left(Player.BedSleepingProblem.NOT_SAFE); } } -@@ -1580,7 +_,19 @@ +@@ -1644,7 +_,19 @@ CriteriaTriggers.SLEPT_IN_BED.trigger(this); }); if (!this.level().canSleepThroughNights()) { @@ -92,7 +92,7 @@ } this.level().updateSleepingPlayerList(); -@@ -1672,6 +_,7 @@ +@@ -1736,6 +_,7 @@ @Override public void openTextEdit(SignBlockEntity signEntity, boolean isFrontText) { @@ -100,7 +100,7 @@ this.connection.send(new ClientboundBlockUpdatePacket(this.level(), signEntity.getBlockPos())); this.connection.send(new ClientboundOpenSignEditorPacket(signEntity.getBlockPos(), isFrontText)); } -@@ -1981,6 +_,26 @@ +@@ -2045,6 +_,26 @@ this.lastSentExp = -1; // CraftBukkit - Added to reset } @@ -127,7 +127,7 @@ @Override public void displayClientMessage(Component chatComponent, boolean actionBar) { this.sendSystemMessage(chatComponent, actionBar); -@@ -2199,6 +_,20 @@ +@@ -2263,6 +_,20 @@ ); } @@ -148,7 +148,7 @@ public void sendSystemMessage(Component mesage) { this.sendSystemMessage(mesage, false); } -@@ -2337,7 +_,67 @@ +@@ -2401,7 +_,67 @@ public void resetLastActionTime() { this.lastActionTime = Util.getMillis(); @@ -217,7 +217,7 @@ public ServerStatsCounter getStats() { return this.stats; -@@ -2965,4 +_,56 @@ +@@ -3029,4 +_,56 @@ return (org.bukkit.craftbukkit.entity.CraftPlayer) super.getBukkitEntity(); } // CraftBukkit end diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch index 9bc36e40b..18b73dfdc 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch @@ -1,11 +1,16 @@ --- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -@@ -43,6 +_,7 @@ - private long keepAliveChallenge; +@@ -39,10 +_,11 @@ + public final Connection connection; // Paper + private final boolean transferred; + //private long keepAliveTime; // Paper - improve keepalives +- //private boolean keepAlivePending; // Paper - improve keepalives ++ private boolean keepAlivePending; // Paper - improve keepalives // Purpur - Alternative Keepalive Handling + //private long keepAliveChallenge; // Paper - improve keepalives private long closedListenerTime; private boolean closed = false; + private it.unimi.dsi.fastutil.longs.LongList keepAlives = new it.unimi.dsi.fastutil.longs.LongArrayList(); // Purpur - Alternative Keepalive Handling - private int latency; + private volatile int latency; // Paper - improve keepalives - make volatile private volatile boolean suspendFlushingOnServerThread = false; // CraftBukkit start @@ -53,6 +_,7 @@ @@ -16,24 +21,26 @@ public ServerCommonPacketListenerImpl(MinecraftServer server, Connection connection, CommonListenerCookie cookie, net.minecraft.server.level.ServerPlayer player) { // CraftBukkit this.server = server; -@@ -120,6 +_,16 @@ - - @Override - public void handleKeepAlive(ServerboundKeepAlivePacket packet) { +@@ -123,6 +_,18 @@ + // Paper start - improve keepalives + long now = System.nanoTime(); + net.minecraft.server.level.ServerPlayer.PendingKeepAlive pending = this.player.pendingKeepAlives.peek(); + // Purpur start - Alternative Keepalive Handling + if (org.purpurmc.purpur.PurpurConfig.useAlternateKeepAlive) { + if (this.keepAlivePending && !keepAlives.isEmpty() && keepAlives.contains(packet.getId())) { + int ping = (int) (Util.getMillis() - packet.getId()); -+ this.latency = (this.latency * 3 + ping) / 4; ++ int updatedLatency = (this.latency * 3 + ping) / 4; ++ this.latency = updatedLatency; + this.keepAlivePending = false; + keepAlives.clear(); // we got a valid response, lets roll with it and forget the rest + } ++ return; + } else + // Purpur end - Alternative Keepalive Handling - if (this.keepAlivePending && packet.getId() == this.keepAliveChallenge) { - int i = (int)(Util.getMillis() - this.keepAliveTime); - this.latency = (this.latency * 3 + i) / 4; -@@ -171,6 +_,12 @@ + if (pending != null && pending.challengeId() == packet.getId()) { + this.player.pendingKeepAlives.remove(pending); + +@@ -199,6 +_,12 @@ return; } @@ -46,26 +53,27 @@ if (identifier.equals(MINECRAFT_BRAND)) { this.player.clientBrandName = new net.minecraft.network.FriendlyByteBuf(io.netty.buffer.Unpooled.wrappedBuffer(data)).readUtf(256); } -@@ -250,6 +_,22 @@ - // Paper start - give clients a longer time to respond to pings as per pre 1.12.2 timings - // This should effectively place the keepalive handling back to "as it was" before 1.12.2 - final long elapsedTime = millis - this.keepAliveTime; -+ +@@ -276,6 +_,23 @@ + Profiler.get().push("keepAlive"); + long millis = Util.getMillis(); + // Paper start - improve keepalives + // Purpur start - Alternative Keepalive Handling + if (org.purpurmc.purpur.PurpurConfig.useAlternateKeepAlive) { -+ if (elapsedTime >= 1000L) { // 1 second -+ if (this.keepAlivePending && !this.processedDisconnect && keepAlives.size() * 1000L >= KEEPALIVE_LIMIT) { -+ this.disconnect(ServerCommonPacketListenerImpl.TIMEOUT_DISCONNECTION_MESSAGE, org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT); -+ } else if (this.checkIfClosed(millis)) { -+ this.keepAlivePending = true; -+ this.keepAliveTime = millis; // hijack this field for 1 second intervals -+ this.keepAlives.add(millis); // currentTime is ID -+ this.send(new ClientboundKeepAlivePacket(millis)); ++ if (this.checkIfClosed(millis) && !this.processedDisconnect) { ++ long currTime = System.nanoTime(); ++ if ((currTime - this.player.lastKeepAliveTx) >= java.util.concurrent.TimeUnit.SECONDS.toNanos(1L)) { // 1 second ++ this.player.lastKeepAliveTx = currTime; ++ if (this.keepAlivePending && !this.processedDisconnect && keepAlives.size() * 1000L >= KEEPALIVE_LIMIT) { ++ this.disconnect(ServerCommonPacketListenerImpl.TIMEOUT_DISCONNECTION_MESSAGE, org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT); ++ } else if (this.checkIfClosed(millis)) { ++ this.keepAlivePending = true; ++ this.keepAlives.add(millis); // currentTime is ID ++ this.send(new ClientboundKeepAlivePacket(millis)); ++ } + } + } + } else + // Purpur end - Alternative Keepalive Handling -+ - if (!this.isSingleplayerOwner() && elapsedTime >= 15000L) { // use vanilla's 15000L between keep alive packets - if (this.keepAlivePending) { - if (!this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // check keepalive limit, don't fire if already disconnected + if (this.checkIfClosed(millis) && !this.processedDisconnect) { + long currTime = System.nanoTime(); + diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/Entity.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/Entity.java.patch index a65e04502..ef0282cc6 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/Entity.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/Entity.java.patch @@ -158,7 +158,7 @@ // Paper start - optimise collisions public boolean updateFluidHeightAndDoFluidPushing(final TagKey fluid, final double flowScale) { if (this.touchingUnloadedChunk()) { -@@ -5117,7 +_,7 @@ +@@ -5107,7 +_,7 @@ } public float maxUpStep() { diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/item/ItemEntity.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/item/ItemEntity.java.patch index 64ea33eb8..4ed5565e9 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/item/ItemEntity.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/item/ItemEntity.java.patch @@ -13,7 +13,7 @@ public ItemEntity(EntityType entityType, Level level) { super(entityType, level); -@@ -334,7 +_,16 @@ +@@ -342,7 +_,16 @@ @Override public final boolean hurtServer(ServerLevel level, DamageSource damageSource, float amount) { @@ -31,7 +31,7 @@ return false; } else if (!level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && damageSource.getEntity() instanceof Mob) { return false; -@@ -513,6 +_,12 @@ +@@ -521,6 +_,12 @@ public void setItem(ItemStack stack) { this.getEntityData().set(DATA_ITEM, stack); this.despawnRate = this.level().paperConfig().entities.spawning.altItemDespawnRate.enabled ? this.level().paperConfig().entities.spawning.altItemDespawnRate.items.getOrDefault(stack.getItem(), this.level().spigotConfig.itemDespawnRate) : this.level().spigotConfig.itemDespawnRate; // Paper - Alternative item-despawn-rate diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/AbstractSkeleton.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/AbstractSkeleton.java.patch index af806331a..10ddc966a 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/AbstractSkeleton.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/monster/AbstractSkeleton.java.patch @@ -12,12 +12,12 @@ this.setItemSlot(EquipmentSlot.HEAD, new ItemStack(random.nextFloat() < 0.1F ? Blocks.JACK_O_LANTERN : Blocks.CARVED_PUMPKIN)); this.setDropChance(EquipmentSlot.HEAD, 0.0F); } -@@ -217,7 +_,7 @@ - if (event.getProjectile() == arrow.getBukkitEntity()) { - // CraftBukkit end - Projectile.spawnProjectileUsingShoot( +@@ -209,7 +_,7 @@ + double squareRoot = Math.sqrt(d * d + d2 * d2); + if (this.level() instanceof ServerLevel serverLevel) { + Projectile.Delayed delayedEntity = Projectile.spawnProjectileUsingShootDelayed( // Paper - delayed - arrow, serverLevel, projectile, d, d1 + squareRoot * 0.2F, d2, 1.6F, 14 - serverLevel.getDifficulty().getId() * 4 + arrow, serverLevel, projectile, d, d1 + squareRoot * 0.2F, d2, 1.6F, serverLevel.purpurConfig.skeletonBowAccuracyMap.getOrDefault(serverLevel.getDifficulty().getId(), (float) (14 - serverLevel.getDifficulty().getId() * 4)) // Purpur - skeleton bow accuracy option ); - } // CraftBukkit - } + + // Paper start - call EntityShootBowEvent diff --git a/purpur-server/paper-patches/features/0002-Ridables.patch b/purpur-server/paper-patches/features/0002-Ridables.patch index 5022ad19b..6473152ff 100644 --- a/purpur-server/paper-patches/features/0002-Ridables.patch +++ b/purpur-server/paper-patches/features/0002-Ridables.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Ridables diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 5fcfbb42c4491ee0878c87bd1724b9bfab57c128..7aaeafd5ee030d032d6e0574fc991942fac5eaa7 100644 +index af6420cdf988badaf70e8c075d2ab9b6a4935e88..edc1758f12b36555edb7eaba2ea3bd78118dda93 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -1348,4 +1348,26 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1345,4 +1345,26 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return this.entity.get(io.papermc.paper.datacomponent.PaperDataComponentType.bukkitToMinecraft(type)) != null; } @@ -36,7 +36,7 @@ index 5fcfbb42c4491ee0878c87bd1724b9bfab57c128..7aaeafd5ee030d032d6e0574fc991942 + // Purpur end - Ridables } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 5ceb08265f883e6634f3f4189c74aa8395addd12..5d64ce696db99f4cefe2c74357b400e00a4ccf60 100644 +index c5daefa56597bd13fe227fa014ca5225c00a2a2d..98b766d115856dbf3ea11a983c1304591032f1b0 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -515,6 +515,15 @@ public class CraftEventFactory { diff --git a/purpur-server/paper-patches/features/0004-Add-EntityTeleportHinderedEvent.patch b/purpur-server/paper-patches/features/0004-Add-EntityTeleportHinderedEvent.patch index 01db886a8..804dbf710 100644 --- a/purpur-server/paper-patches/features/0004-Add-EntityTeleportHinderedEvent.patch +++ b/purpur-server/paper-patches/features/0004-Add-EntityTeleportHinderedEvent.patch @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 7aaeafd5ee030d032d6e0574fc991942fac5eaa7..df23fbae231eca494131bf7ec78924669cd5e03d 100644 +index edc1758f12b36555edb7eaba2ea3bd78118dda93..7a9e20699a8a5e95910ed15eb6cd1192b2df89cc 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -309,6 +309,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -314,6 +314,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { boolean retainPassengers = flagSet.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_PASSENGERS); // Don't allow teleporting between worlds while keeping passengers if (flagSet.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_PASSENGERS) && this.entity.isVehicle() && location.getWorld() != this.getWorld()) { @@ -29,10 +29,10 @@ index 7aaeafd5ee030d032d6e0574fc991942fac5eaa7..df23fbae231eca494131bf7ec7892466 } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 91f56fffbced0599d77d39c6d1d8de78b960e58c..213afcae6bb02e4e340d5fa477bdddbb9434fc70 100644 +index 5fa91d288bd5bc3990f4416f9d30202d7379ccdd..7f17c5025f25e44a917f5d6a65b8d958a982b301 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1439,6 +1439,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1447,6 +1447,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { // Paper start - Teleport passenger API // Don't allow teleporting between worlds while keeping passengers if (ignorePassengers && entity.isVehicle() && location.getWorld() != this.getWorld()) { @@ -40,7 +40,7 @@ index 91f56fffbced0599d77d39c6d1d8de78b960e58c..213afcae6bb02e4e340d5fa477bdddbb return false; } -@@ -1460,6 +1461,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1468,6 +1469,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } if (entity.isVehicle() && !ignorePassengers) { // Paper - Teleport API diff --git a/purpur-server/paper-patches/features/0005-API-for-any-mob-to-burn-daylight.patch b/purpur-server/paper-patches/features/0005-API-for-any-mob-to-burn-daylight.patch index 17ca1fc7f..566477fb8 100644 --- a/purpur-server/paper-patches/features/0005-API-for-any-mob-to-burn-daylight.patch +++ b/purpur-server/paper-patches/features/0005-API-for-any-mob-to-burn-daylight.patch @@ -6,10 +6,10 @@ Subject: [PATCH] API for any mob to burn daylight Co-authored by: Encode42 diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index d00238a0f39c5b19575cd0463b0b5da1f1db1a2e..55ae7d0a5b36ff10880d4e5fb1bb7f7724a743fd 100644 +index 7a9e20699a8a5e95910ed15eb6cd1192b2df89cc..476eefebace887064b728f08af40c746b6f70787 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -120,6 +120,13 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -125,6 +125,13 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { } // Purpur end - Fire Immunity API diff --git a/purpur-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/CraftWorld.java.patch b/purpur-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/CraftWorld.java.patch index eb9822cce..d71d7b310 100644 --- a/purpur-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/CraftWorld.java.patch +++ b/purpur-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/CraftWorld.java.patch @@ -1,6 +1,6 @@ --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -2370,6 +_,50 @@ +@@ -2374,6 +_,50 @@ return (this.getHandle().getDragonFight() == null) ? null : new CraftDragonBattle(this.getHandle().getDragonFight()); } diff --git a/purpur-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java.patch b/purpur-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java.patch index ad9c0dbd1..b515f8d97 100644 --- a/purpur-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java.patch +++ b/purpur-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java.patch @@ -1,6 +1,6 @@ --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -108,6 +_,18 @@ +@@ -113,6 +_,18 @@ this.entityType = CraftEntityType.minecraftToBukkit(entity.getType()); } diff --git a/purpur-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java.patch b/purpur-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java.patch index f35cdb6ea..9a51d99bc 100644 --- a/purpur-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java.patch +++ b/purpur-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java.patch @@ -1,6 +1,6 @@ --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -617,10 +_,15 @@ +@@ -625,10 +_,15 @@ @Override public void setPlayerListName(String name) { @@ -17,7 +17,7 @@ if (this.getHandle().connection == null) return; // Paper - Updates are possible before the player has fully joined for (ServerPlayer player : (List) this.server.getHandle().players) { if (player.getBukkitEntity().canSee(this)) { -@@ -2718,6 +_,28 @@ +@@ -2726,6 +_,28 @@ return this.getHandle().getAbilities().walkingSpeed * 2f; } @@ -46,7 +46,7 @@ private void validateSpeed(float value) { Preconditions.checkArgument(value <= 1f && value >= -1f, "Speed value (%s) need to be between -1f and 1f", value); } -@@ -3571,4 +_,76 @@ +@@ -3569,4 +_,76 @@ public void setDeathScreenScore(final int score) { getHandle().setScore(score); }