diff --git a/patches/server/Chunk-System-Starlight-from-Moonrise.patch b/patches/server/Chunk-System-Starlight-from-Moonrise.patch index 446e4e7c6f..0a8f68caaa 100644 --- a/patches/server/Chunk-System-Starlight-from-Moonrise.patch +++ b/patches/server/Chunk-System-Starlight-from-Moonrise.patch @@ -5056,6 +5056,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +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..00000000000000000000000000000000 + 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/Entity-load-save-limit-per-chunk.patch b/patches/server/Entity-load-save-limit-per-chunk.patch similarity index 65% rename from patches/unapplied/server/Entity-load-save-limit-per-chunk.patch rename to patches/server/Entity-load-save-limit-per-chunk.patch index f97ae9f887..1c763266a3 100644 --- a/patches/unapplied/server/Entity-load-save-limit-per-chunk.patch +++ b/patches/server/Entity-load-save-limit-per-chunk.patch @@ -8,6 +8,29 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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 +@@ -0,0 +0,0 @@ public final class ChunkEntitySlices { + } + + final ListTag entitiesTag = new ListTag(); ++ final java.util.Map<net.minecraft.world.entity.EntityType<?>, 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/EntityType.java @@ -38,21 +61,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/EntityStorage.java @@ -0,0 +0,0 @@ public class EntityStorage implements EntityPersistentStorage<Entity> { - } - - ListTag listTag = new ListTag(); -+ final java.util.Map<net.minecraft.world.entity.EntityType<?>, 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; + } + } else { + ListTag listTag = new ListTag(); ++ final java.util.Map<net.minecraft.world.entity.EntityType<?>, 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/unapplied/server/Properly-resend-entities.patch b/patches/server/Properly-resend-entities.patch similarity index 94% rename from patches/unapplied/server/Properly-resend-entities.patch rename to patches/server/Properly-resend-entities.patch index 1e9d43cea5..f2a3829e25 100644 --- a/patches/unapplied/server/Properly-resend-entities.patch +++ b/patches/server/Properly-resend-entities.patch @@ -96,8 +96,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // 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(); } @@ -189,7 +189,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 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); @@ -203,15 +203,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftItemFrame.java