ca708a0944
Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: ed7bba95 SPIGOT-6547: Chunk#getEntities() doesn't return all entities immediately after chunk load d99a585c SPIGOT-6719: Add getTileEntities() to LimitedRegion CraftBukkit Changes: 422cec08 Rebuild patch 15f27fc7 SPIGOT-6547: Chunk#getEntities() doesn't return all entities immediately after chunk load cbd747af SPIGOT-6719: Add getTileEntities() to LimitedRegion Spigot Changes: 6c1c1b26 Rebuild patches
115 Zeilen
6.2 KiB
Diff
115 Zeilen
6.2 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
|
|
Date: Wed, 18 Nov 2020 20:52:25 -0800
|
|
Subject: [PATCH] Entity load/save limit per chunk
|
|
|
|
Adds a config option to limit the number of entities saved and loaded
|
|
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/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
index 1da69d56f0b58708d4c85e76307b725221f9caed..5eeb09c7cbc743c4273a6d02d9f0c357c2724ba2 100644
|
|
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
@@ -1,9 +1,12 @@
|
|
package com.destroystokyo.paper;
|
|
|
|
import java.util.Arrays;
|
|
+import java.util.HashMap;
|
|
import java.util.List;
|
|
+import java.util.Map;
|
|
import java.util.stream.Collectors;
|
|
import net.minecraft.world.Difficulty;
|
|
+import net.minecraft.world.entity.EntityType;
|
|
import net.minecraft.world.entity.monster.Vindicator;
|
|
import net.minecraft.world.entity.monster.Zombie;
|
|
import com.destroystokyo.paper.antixray.ChunkPacketBlockControllerAntiXray.EngineMode;
|
|
@@ -123,6 +126,38 @@ public class PaperWorldConfig {
|
|
);
|
|
}
|
|
|
|
+ public Map<EntityType<?>, Integer> entityPerChunkSaveLimits = new HashMap<>();
|
|
+ private void entityPerChunkSaveLimits() {
|
|
+ getInt("entity-per-chunk-save-limit.experience_orb", -1);
|
|
+ getInt("entity-per-chunk-save-limit.snowball", -1);
|
|
+ getInt("entity-per-chunk-save-limit.ender_pearl", -1);
|
|
+ getInt("entity-per-chunk-save-limit.arrow", -1);
|
|
+ getInt("entity-per-chunk-save-limit.fireball", -1);
|
|
+ getInt("entity-per-chunk-save-limit.small_fireball", -1);
|
|
+
|
|
+ addEntityPerChunkSaveLimitsFromSection(config.getConfigurationSection("world-settings.default.entity-per-chunk-save-limit"), entityPerChunkSaveLimits);
|
|
+ addEntityPerChunkSaveLimitsFromSection(config.getConfigurationSection("world-settings." + worldName + ".entity-per-chunk-save-limit"), entityPerChunkSaveLimits);
|
|
+ }
|
|
+
|
|
+ private static void addEntityPerChunkSaveLimitsFromSection(final ConfigurationSection section, final Map<EntityType<?>, Integer> limitMap) {
|
|
+ if (section == null) {
|
|
+ return;
|
|
+ }
|
|
+ for (final String key : section.getKeys(false)) {
|
|
+ final int value = section.getInt(key);
|
|
+ final EntityType<?> type = EntityType.byString(key).orElse(null);
|
|
+ if (type == null) {
|
|
+ logError("Invalid entity-per-chunk-save-limit config, '" + key+ "' is not a valid entity type. Correct this in paper.yml.");
|
|
+ continue;
|
|
+ }
|
|
+ if (value >= 0) {
|
|
+ limitMap.put(type, value);
|
|
+ } else {
|
|
+ limitMap.remove(type);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
public short keepLoadedRange;
|
|
private void keepLoadedRange() {
|
|
keepLoadedRange = (short) (getInt("keep-spawn-loaded-range", Math.min(spigotConfig.viewDistance, 10)) * 16);
|
|
diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java
|
|
index 8c829066939a4069953097fd268f7c214a555779..1c446dba5de89698397041ee38a2e1a00bec8a56 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
|
|
@@ -563,9 +563,20 @@ public class EntityType<T extends Entity> implements EntityTypeTest<Entity, T> {
|
|
final Spliterator<? extends net.minecraft.nbt.Tag> spliterator = entityNbtList.spliterator();
|
|
|
|
return StreamSupport.stream(new Spliterator<Entity>() {
|
|
+ final java.util.Map<EntityType<?>, Integer> loadedEntityCounts = new java.util.HashMap<>(); // Paper
|
|
public boolean tryAdvance(Consumer<? super Entity> consumer) {
|
|
return spliterator.tryAdvance((nbtbase) -> {
|
|
EntityType.loadEntityRecursive((CompoundTag) nbtbase, world, (entity) -> {
|
|
+ // Paper start
|
|
+ final EntityType<?> entityType = entity.getType();
|
|
+ final int saveLimit = world.paperConfig.entityPerChunkSaveLimits.getOrDefault(entityType, -1);
|
|
+ if (saveLimit > -1) {
|
|
+ if (this.loadedEntityCounts.getOrDefault(entityType, 0) >= saveLimit) {
|
|
+ return null;
|
|
+ }
|
|
+ this.loadedEntityCounts.merge(entityType, 1, Integer::sum);
|
|
+ }
|
|
+ // Paper end
|
|
consumer.accept(entity);
|
|
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 50afe31798664b2e0ac7546d775ecea534e351e2..0e13a1f898a793799416056bd468851013f9c5cb 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
|
|
@@ -107,7 +107,18 @@ public class EntityStorage implements EntityPersistentStorage<Entity> {
|
|
} else {
|
|
ListTag nbttaglist = new ListTag();
|
|
|
|
+ final java.util.Map<net.minecraft.world.entity.EntityType<?>, Integer> savedEntityCounts = new java.util.HashMap<>(); // Paper
|
|
dataList.getEntities().forEach((entity) -> {
|
|
+ // Paper start
|
|
+ final EntityType<?> entityType = entity.getType();
|
|
+ final int saveLimit = this.level.paperConfig.entityPerChunkSaveLimits.getOrDefault(entityType, -1);
|
|
+ if (saveLimit > -1) {
|
|
+ if (savedEntityCounts.getOrDefault(entityType, 0) >= saveLimit) {
|
|
+ return;
|
|
+ }
|
|
+ savedEntityCounts.merge(entityType, 1, Integer::sum);
|
|
+ }
|
|
+ // Paper end
|
|
CompoundTag nbttagcompound = new CompoundTag();
|
|
|
|
if (entity.save(nbttagcompound)) {
|