geforkt von Mirrors/Paper
aa52bf9e33
Mojang made some changes to priorities in 1.17 and it seems that these changes conflict with the changes made in this patch, which in some cases appears to cause excessive rescheduling of tasks. This, however, is not confirmed as such but seems to be the behavior that we're seeing to cause this issue, if mojang has adopted the changes we suggested, then a good chunk of this patch may be unneeded, but, this needs a much better look than I'm currently able to do
99 Zeilen
5.7 KiB
Diff
99 Zeilen
5.7 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 acd61a9033fdfb91e29a5fa6a10b8983ed94baa5..3e9f288ee310c7c79664e69b99698fdd179ae77f 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,22 @@ 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);
|
|
+ EntityType.getEntityNameList().forEach(name -> {
|
|
+ final EntityType<?> type = EntityType.byString(name.getPath()).orElseThrow(() -> new IllegalStateException("Unknown Entity Type: " + name.toString()));
|
|
+ final String path = ".entity-per-chunk-save-limit." + name.getPath();
|
|
+ final int value = config.getInt("world-settings." + worldName + path, config.getInt("world-settings.default" + path, -1)); // get without setting defaults
|
|
+ if (value != -1) entityPerChunkSaveLimits.put(type, value);
|
|
+ });
|
|
+ }
|
|
+
|
|
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 b50bf044a3cb05b811fd06796a351e6b15b352ad..ac99265aacd4a28490705e3079ed04023fb1c54a 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
|
|
@@ -560,9 +560,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 9b0b3affdbdf831f0d3d61c59bdb99555bc0bed7..396c34c0866bf395b4d86361d96fe103c5d9ae7e 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
|
|
@@ -90,7 +90,18 @@ public class EntityStorage implements EntityPersistentStorage<Entity> {
|
|
|
|
} else {
|
|
ListTag listTag = 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 compoundTag = new CompoundTag();
|
|
if (entity.save(compoundTag)) {
|
|
listTag.add(compoundTag);
|