diff --git a/patches/server/0991-Chunk-System-Starlight-from-Moonrise.patch b/patches/server/0991-Chunk-System-Starlight-from-Moonrise.patch index 6b8f2f460b..3e7b994bed 100644 --- a/patches/server/0991-Chunk-System-Starlight-from-Moonrise.patch +++ b/patches/server/0991-Chunk-System-Starlight-from-Moonrise.patch @@ -5024,10 +5024,10 @@ index 0000000000000000000000000000000000000000..755b08dd32e568d341ceef8a8aef8418 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java new file mode 100644 -index 0000000000000000000000000000000000000000..f85820b959213c9bb566897c173f644fd430d01a +index 0000000000000000000000000000000000000000..19672631d7c69ade16a6f966c72a4a9d57b77c55 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java -@@ -0,0 +1,810 @@ +@@ -0,0 +1,811 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level.entity; + +import ca.spottedleaf.moonrise.common.list.EntityList; @@ -5056,6 +5056,7 @@ index 0000000000000000000000000000000000000000..f85820b959213c9bb566897c173f644f +import java.util.Iterator; +import java.util.List; +import java.util.function.Predicate; ++import org.bukkit.event.entity.EntityRemoveEvent; + +public final class ChunkEntitySlices { + @@ -5176,12 +5177,12 @@ index 0000000000000000000000000000000000000000..f85820b959213c9bb566897c173f644f + continue; + } + if (entity.shouldBeSaved()) { -+ entity.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK); ++ entity.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK, EntityRemoveEvent.Cause.UNLOAD); + if (entity.isVehicle()) { + // we cannot assume that these entities are contained within this chunk, because entities can + // desync - so we need to remove them all + for (final Entity passenger : entity.getIndirectPassengers()) { -+ passenger.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK); ++ passenger.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK, EntityRemoveEvent.Cause.UNLOAD); + } + } + } diff --git a/patches/unapplied/server/1009-Entity-load-save-limit-per-chunk.patch b/patches/server/1009-Entity-load-save-limit-per-chunk.patch similarity index 59% rename from patches/unapplied/server/1009-Entity-load-save-limit-per-chunk.patch rename to patches/server/1009-Entity-load-save-limit-per-chunk.patch index 1dbf729bda..cf71d8747d 100644 --- a/patches/unapplied/server/1009-Entity-load-save-limit-per-chunk.patch +++ b/patches/server/1009-Entity-load-save-limit-per-chunk.patch @@ -8,8 +8,31 @@ to a chunk. The default values of -1 disable the limit. Although defaults are only included for certain entites, this allows setting limits for any entity type. +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java +index 19672631d7c69ade16a6f966c72a4a9d57b77c55..df4aadd40c0033c852af575fd11dce8eb3f2959e 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java +@@ -100,7 +100,18 @@ public final class ChunkEntitySlices { + } + + final ListTag entitiesTag = new ListTag(); ++ final java.util.Map, Integer> savedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk + for (final Entity entity : entities) { ++ // Paper start - Entity load/save limit per chunk ++ final EntityType entityType = entity.getType(); ++ final int saveLimit = world.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1); ++ if (saveLimit > -1) { ++ if (savedEntityCounts.getOrDefault(entityType, 0) >= saveLimit) { ++ break; ++ } ++ savedEntityCounts.merge(entityType, 1, Integer::sum); ++ } ++ // Paper end - Entity load/save limit per chunk + CompoundTag compoundTag = new CompoundTag(); + if (entity.save(compoundTag)) { + entitiesTag.add(compoundTag); diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index 56b51096ca4147363a843accf6ef2510f05e8f1a..a46bf73c608641bf1f00fd55242de71a0f2ee06e 100644 +index 842b0cec0397d7ae5166617627340ffac0e35db1..cb61462d4691a055a4b25f7b953609d8a154fdfe 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/src/main/java/net/minecraft/world/entity/EntityType.java @@ -649,9 +649,20 @@ public class EntityType implements FeatureElement, EntityTypeT @@ -34,25 +57,25 @@ index 56b51096ca4147363a843accf6ef2510f05e8f1a..a46bf73c608641bf1f00fd55242de71a return entity; }); diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java -index 9fdf8f857a5f9b231c6d0633eaba498244214f74..bee39dee1b96023c907407877aedf3aafaf5e1b8 100644 +index 503ac0374e0c9f9993ad37bb8bd8cf1570d3615a..d4a505ef4af9ded02aeb1a817bcbe5b1a912a5b3 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java -@@ -105,7 +105,18 @@ public class EntityStorage implements EntityPersistentStorage { - } - - ListTag listTag = new ListTag(); -+ final java.util.Map, Integer> savedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk - entities.forEach((entity) -> { // diff here: use entities parameter -+ // Paper start - Entity load/save limit per chunk -+ final EntityType entityType = entity.getType(); -+ final int saveLimit = level.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1); -+ if (saveLimit > -1) { -+ if (savedEntityCounts.getOrDefault(entityType, 0) >= saveLimit) { -+ return; +@@ -92,7 +92,18 @@ public class EntityStorage implements EntityPersistentStorage { + } + } else { + ListTag listTag = new ListTag(); ++ final java.util.Map, Integer> savedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk + dataList.getEntities().forEach(entity -> { ++ // Paper start - Entity load/save limit per chunk ++ final EntityType entityType = entity.getType(); ++ final int saveLimit = this.level.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1); ++ if (saveLimit > -1) { ++ if (savedEntityCounts.getOrDefault(entityType, 0) >= saveLimit) { ++ return; ++ } ++ savedEntityCounts.merge(entityType, 1, Integer::sum); + } -+ savedEntityCounts.merge(entityType, 1, Integer::sum); -+ } -+ // Paper end - Entity load/save limit per chunk - CompoundTag compoundTag = new CompoundTag(); - if (entity.save(compoundTag)) { - listTag.add(compoundTag); ++ // Paper end - Entity load/save limit per chunk + CompoundTag compoundTagx = new CompoundTag(); + if (entity.save(compoundTagx)) { + listTag.add(compoundTagx); diff --git a/patches/server/1009-Optimize-Voxel-Shape-Merging.patch b/patches/server/1010-Optimize-Voxel-Shape-Merging.patch similarity index 100% rename from patches/server/1009-Optimize-Voxel-Shape-Merging.patch rename to patches/server/1010-Optimize-Voxel-Shape-Merging.patch diff --git a/patches/server/1010-Optimize-Bit-Operations-by-inlining.patch b/patches/server/1011-Optimize-Bit-Operations-by-inlining.patch similarity index 100% rename from patches/server/1010-Optimize-Bit-Operations-by-inlining.patch rename to patches/server/1011-Optimize-Bit-Operations-by-inlining.patch diff --git a/patches/server/1011-Remove-streams-from-hot-code.patch b/patches/server/1012-Remove-streams-from-hot-code.patch similarity index 100% rename from patches/server/1011-Remove-streams-from-hot-code.patch rename to patches/server/1012-Remove-streams-from-hot-code.patch diff --git a/patches/server/1012-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch b/patches/server/1013-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch similarity index 100% rename from patches/server/1012-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch rename to patches/server/1013-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch diff --git a/patches/server/1013-Custom-table-implementation-for-blockstate-state-loo.patch b/patches/server/1014-Custom-table-implementation-for-blockstate-state-loo.patch similarity index 100% rename from patches/server/1013-Custom-table-implementation-for-blockstate-state-loo.patch rename to patches/server/1014-Custom-table-implementation-for-blockstate-state-loo.patch diff --git a/patches/server/1014-Fix-entity-type-tags-suggestions-in-selectors.patch b/patches/server/1015-Fix-entity-type-tags-suggestions-in-selectors.patch similarity index 100% rename from patches/server/1014-Fix-entity-type-tags-suggestions-in-selectors.patch rename to patches/server/1015-Fix-entity-type-tags-suggestions-in-selectors.patch diff --git a/patches/server/1015-Handle-Oversized-block-entities-in-chunks.patch b/patches/server/1016-Handle-Oversized-block-entities-in-chunks.patch similarity index 100% rename from patches/server/1015-Handle-Oversized-block-entities-in-chunks.patch rename to patches/server/1016-Handle-Oversized-block-entities-in-chunks.patch diff --git a/patches/server/1016-API-for-checking-sent-chunks.patch b/patches/server/1017-API-for-checking-sent-chunks.patch similarity index 100% rename from patches/server/1016-API-for-checking-sent-chunks.patch rename to patches/server/1017-API-for-checking-sent-chunks.patch diff --git a/patches/server/1017-Configurable-Sand-Duping.patch b/patches/server/1018-Configurable-Sand-Duping.patch similarity index 100% rename from patches/server/1017-Configurable-Sand-Duping.patch rename to patches/server/1018-Configurable-Sand-Duping.patch diff --git a/patches/unapplied/server/1030-Properly-resend-entities.patch b/patches/server/1019-Properly-resend-entities.patch similarity index 86% rename from patches/unapplied/server/1030-Properly-resend-entities.patch rename to patches/server/1019-Properly-resend-entities.patch index 8bba132319..104ad37efe 100644 --- a/patches/unapplied/server/1030-Properly-resend-entities.patch +++ b/patches/server/1019-Properly-resend-entities.patch @@ -57,10 +57,10 @@ index 02bf2705ca1c99023a83a22d92e1962181102297..0f99733660f91280e4c6262cf75b3c9c final EntityDataAccessor accessor; diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -index 56de0da254c8f027fa23afc261be3b5e5ffdde93..c7efde4e2b87b14e768429748b01c1bce659682b 100644 +index e9dcdb1e09e84a9b451034ff4bdfa6eae2dd1c04..24b1715397ba8e6f5e9841a030d0e3d964356f89 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -@@ -556,6 +556,7 @@ public class ServerPlayerGameMode { +@@ -561,6 +561,7 @@ public class ServerPlayerGameMode { } // Paper end - extend Player Interact cancellation player.getBukkitEntity().updateInventory(); // SPIGOT-2867 @@ -68,7 +68,7 @@ index 56de0da254c8f027fa23afc261be3b5e5ffdde93..c7efde4e2b87b14e768429748b01c1bc return (event.useItemInHand() != Event.Result.ALLOW) ? InteractionResult.SUCCESS : InteractionResult.PASS; } else if (this.gameModeForPlayer == GameType.SPECTATOR) { MenuProvider itileinventory = iblockdata.getMenuProvider(world, blockposition); -@@ -607,6 +608,11 @@ public class ServerPlayerGameMode { +@@ -612,6 +613,11 @@ public class ServerPlayerGameMode { return enuminteractionresult; } else { @@ -81,10 +81,10 @@ index 56de0da254c8f027fa23afc261be3b5e5ffdde93..c7efde4e2b87b14e768429748b01c1bc } } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 56d32a919cff2a9d4a5775665ed4d1d14b9c708b..3faf80fca51d66480265eaf3cc89149e53ceb215 100644 +index be2e97e4de911ad9570a9b4e9f3c5fafa93f6203..199e2f447ddb319387a15c934da71c27aab6da1e 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2004,6 +2004,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1949,6 +1949,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } if (cancelled) { @@ -92,17 +92,17 @@ index 56d32a919cff2a9d4a5775665ed4d1d14b9c708b..3faf80fca51d66480265eaf3cc89149e this.player.getBukkitEntity().updateInventory(); // SPIGOT-2524 return; } -@@ -2786,7 +2787,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2718,7 +2719,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Entity in bucket - SPIGOT-4048 and SPIGOT-6859a if ((entity instanceof Bucketable && entity instanceof LivingEntity && origItem != null && origItem.asItem() == Items.WATER_BUCKET) && (event.isCancelled() || ServerGamePacketListenerImpl.this.player.getInventory().getSelected() == null || ServerGamePacketListenerImpl.this.player.getInventory().getSelected().getItem() != origItem)) { -- ServerGamePacketListenerImpl.this.send(new ClientboundAddEntityPacket(entity)); -+ entity.resendPossiblyDesyncedEntityData(ServerGamePacketListenerImpl.this.player); // Paper - The entire mob gets deleted, so resend it. +- entity.getBukkitEntity().update(ServerGamePacketListenerImpl.this.player); ++ entity.resendPossiblyDesyncedEntityData(ServerGamePacketListenerImpl.this.player); // Paper - The entire mob gets deleted, so resend it ServerGamePacketListenerImpl.this.player.containerMenu.sendAllDataToRemote(); } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 68446b7532dfbda303293aa9e756644c6fcdffca..a2142930b4d4b05987c90496fb9d733d99040aa0 100644 +index 0d0b07c9199be9ca0d5ac3feb1d44f149ba69283..3d30427e75bdfb9cf453fb5cd2a344227da1641a 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -393,7 +393,7 @@ public abstract class PlayerList { @@ -115,10 +115,10 @@ index 68446b7532dfbda303293aa9e756644c6fcdffca..a2142930b4d4b05987c90496fb9d733d this.sendLevelInfo(player, worldserver1); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 9153c15cd2b8a3811d5f1c16ac2221aea7c3aacd..7ef9f67d27cc240191dd5d07e8dcf5fbdebe1049 100644 +index 14db8510af7465eb663501008ca35f8ec63bfe30..898651b7cfff15fe1afb690c247cdc3936d12fa6 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -703,13 +703,44 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -664,13 +664,44 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess // CraftBukkit start public void refreshEntityData(ServerPlayer to) { @@ -166,10 +166,10 @@ index 9153c15cd2b8a3811d5f1c16ac2221aea7c3aacd..7ef9f67d27cc240191dd5d07e8dcf5fb public boolean equals(Object object) { return object instanceof Entity ? ((Entity) object).id == this.id : false; diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 9601d3def5e4ac0650bae42a1da2a64ab1e5aef7..81a8296e25275639718e0839888ac6a900b54bf3 100644 +index 25a7dfddb44a11f6e20c459141a61270c0c12d4c..e980c8c356b30d25e2fc5a73b91ad2c6edd4fe05 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3818,6 +3818,11 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3840,6 +3840,11 @@ public abstract class LivingEntity extends Entity implements Attackable { return ((Byte) this.entityData.get(LivingEntity.DATA_LIVING_ENTITY_FLAGS) & 2) > 0 ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND; } @@ -182,38 +182,38 @@ index 9601d3def5e4ac0650bae42a1da2a64ab1e5aef7..81a8296e25275639718e0839888ac6a9 if (this.isUsingItem()) { if (ItemStack.isSameItem(this.getItemInHand(this.getUsedItemHand()), this.useItem)) { diff --git a/src/main/java/net/minecraft/world/entity/animal/Bucketable.java b/src/main/java/net/minecraft/world/entity/animal/Bucketable.java -index cb4a6439e9774bbec07e69b13df8dddd395b9ece..cfe37b4f5e33795ee717d824d86e3a0919129cf5 100644 +index b586116d8cca1585f9c9e618ed4d0cb2ef2747be..acf38ef6d8de8b15cf2b09eb7bda390c4e446e9a 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Bucketable.java +++ b/src/main/java/net/minecraft/world/entity/animal/Bucketable.java -@@ -109,8 +109,7 @@ public interface Bucketable { +@@ -108,8 +108,7 @@ public interface Bucketable { itemstack1 = CraftItemStack.asNMSCopy(playerBucketFishEvent.getEntityBucket()); if (playerBucketFishEvent.isCancelled()) { ((ServerPlayer) player).containerMenu.sendAllDataToRemote(); // We need to update inventory to resync client's bucket -- ((ServerPlayer) player).connection.send(new ClientboundAddEntityPacket(entity)); // We need to play out these packets as the client assumes the fish is gone +- entity.getBukkitEntity().update((ServerPlayer) player); // We need to play out these packets as the client assumes the fish is gone - entity.refreshEntityData((ServerPlayer) player); // Need to send data such as the display name to client + entity.resendPossiblyDesyncedEntityData((ServerPlayer) player); // Paper return Optional.of(InteractionResult.FAIL); } entity.playSound(((Bucketable) entity).getPickupSound(), 1.0F, 1.0F); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 3ab04c4bdbe26ff7f6f54eb9cdd58376c592fa05..a2d336ceb52b63db5c03432ee7bc94dc6a742b82 100644 +index b8eb9166e44da8745a056bf68f2f9316ce25d7a7..2cde808bfa797256409879505ba205a71f381981 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -1010,7 +1010,11 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -1012,7 +1012,11 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return; } -- entityTracker.broadcast(this.getHandle().getAddEntityPacket()); -+ // Paper start, resend possibly desynced entity instead of add entity packet -+ for (ServerPlayerConnection playerConnection : entityTracker.seenBy) { -+ this.getHandle().resendPossiblyDesyncedEntityData(playerConnection.getPlayer()); +- entityTracker.broadcast(this.getHandle().getAddEntityPacket(entityTracker.serverEntity)); ++ // Paper start - resend possibly desynced entity instead of add entity packet ++ for (final ServerPlayerConnection connection : entityTracker.seenBy) { ++ this.getHandle().resendPossiblyDesyncedEntityData(connection.getPlayer()); + } -+ // Paper end ++ // Paper end - resend possibly desynced entity instead of add entity packet } - private static PermissibleBase getPermissibleBase() { + public void update(ServerPlayer player) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftItemFrame.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftItemFrame.java -index 0801bcdee8fcff0d388d302387e4f1d587e0a283..2fcd9b836d42e3549a3b6b921c57a4c103146dff 100644 +index f3a9b3380246fb2dd4b60a8d1a94c5dfed98d316..350ad61ab3fe66abd528e353b431a4a6dac17506 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftItemFrame.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftItemFrame.java @@ -39,9 +39,11 @@ public class CraftItemFrame extends CraftHanging implements ItemFrame {