diff --git a/build-data/paper.at b/build-data/paper.at index 51c7de20a0..5f1aa5b282 100644 --- a/build-data/paper.at +++ b/build-data/paper.at @@ -252,3 +252,6 @@ public net.minecraft.world.entity.monster.Zombie supportsBreakDoorGoal()Z # Add Material#hasCollision public net.minecraft.world.level.block.state.BlockBehaviour hasCollision + +# add per world spawn limits +public net.minecraft.world.level.NaturalSpawner SPAWNING_CATEGORIES diff --git a/patches/server/Add-configurable-despawn-distances-for-living-entiti.patch b/patches/server/Add-configurable-despawn-distances-for-living-entiti.patch index 6548ecac98..8a8c7d27d8 100644 --- a/patches/server/Add-configurable-despawn-distances-for-living-entiti.patch +++ b/patches/server/Add-configurable-despawn-distances-for-living-entiti.patch @@ -8,25 +8,60 @@ diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/m index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +@@ -0,0 +0,0 @@ package com.destroystokyo.paper; + + import java.util.List; + ++import it.unimi.dsi.fastutil.objects.Reference2IntMap; ++import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; ++import net.minecraft.world.entity.MobCategory; + import org.bukkit.Bukkit; + import org.bukkit.configuration.file.YamlConfiguration; + import org.spigotmc.SpigotWorldConfig; +@@ -0,0 +0,0 @@ public class PaperWorldConfig { + public void removeOldValues() { + boolean needsSave = false; + ++ if (PaperConfig.version < 24) { ++ needsSave = true; ++ ++ set("despawn-ranges.soft", null); ++ set("despawn-ranges.hard", null); ++ } ++ + if (needsSave) { + saveConfig(); + } @@ -0,0 +0,0 @@ public class PaperWorldConfig { private void nerfedMobsShouldJump() { nerfedMobsShouldJump = getBoolean("spawner-nerfed-mobs-should-jump", false); } + -+ public int softDespawnDistance; -+ public int hardDespawnDistance; ++ public final Reference2IntMap softDespawnDistances = new Reference2IntOpenHashMap<>(MobCategory.values().length); ++ public final Reference2IntMap hardDespawnDistances = new Reference2IntOpenHashMap<>(MobCategory.values().length); + private void despawnDistances() { -+ softDespawnDistance = getInt("despawn-ranges.soft", 32); // 32^2 = 1024, Minecraft Default -+ hardDespawnDistance = getInt("despawn-ranges.hard", 128); // 128^2 = 16384, Minecraft Default -+ -+ if (softDespawnDistance > hardDespawnDistance) { -+ softDespawnDistance = hardDespawnDistance; ++ if (PaperConfig.version < 24) { ++ int softDistance = getInt("despawn-ranges.soft", 32, false); // 32^2 = 1024, Minecraft Default ++ int hardDistance = getInt("despawn-ranges.hard", 128, false); // 128^2 = 16384, Minecraft Default ++ for (MobCategory value : MobCategory.values()) { ++ if (softDistance != 32) { ++ softDespawnDistances.put(value, softDistance); ++ } ++ if (hardDistance != 128) { ++ hardDespawnDistances.put(value, hardDistance); ++ } ++ } ++ } ++ for (MobCategory category : MobCategory.values()) { ++ int softDistance = getInt("despawn-ranges." + category.getName() + ".soft", softDespawnDistances.getOrDefault(category, category.getNoDespawnDistance())); ++ int hardDistance = getInt("despawn-ranges." + category.getName() + ".hard", hardDespawnDistances.getOrDefault(category, category.getDespawnDistance())); ++ if (softDistance > hardDistance) { ++ softDistance = hardDistance; ++ } ++ log("Mobs in " + category.getName() + " Despawn Ranges: Soft" + softDistance + " Hard: " + hardDistance); ++ softDespawnDistances.put(category, softDistance); ++ hardDespawnDistances.put(category, hardDistance); + } -+ -+ log("Living Entity Despawn Ranges: Soft: " + softDespawnDistance + " Hard: " + hardDespawnDistance); -+ -+ softDespawnDistance = softDespawnDistance*softDespawnDistance; -+ hardDespawnDistance = hardDespawnDistance*hardDespawnDistance; + } } diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java @@ -34,22 +69,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java @@ -0,0 +0,0 @@ public abstract class Mob extends LivingEntity { - int i = this.getType().getCategory().getDespawnDistance(); + + if (entityhuman != null) { + double d0 = entityhuman.distanceToSqr((Entity) this); // CraftBukkit - decompile error +- int i = this.getType().getCategory().getDespawnDistance(); ++ int i = this.level.paperConfig.hardDespawnDistances.getInt(this.getType().getCategory()); // Paper - custom despawn distances int j = i * i; -- if (d0 > (double) j) { // CraftBukkit - remove isTypeNotPersistent() check -+ if (d0 > (double) level.paperConfig.hardDespawnDistance) { // CraftBukkit - remove isTypeNotPersistent() check // Paper - custom despawn distances + if (d0 > (double) j) { // CraftBukkit - remove isTypeNotPersistent() check this.discard(); } - int k = this.getType().getCategory().getNoDespawnDistance(); +- int k = this.getType().getCategory().getNoDespawnDistance(); ++ int k = this.level.paperConfig.softDespawnDistances.getInt(this.getType().getCategory()); // Paper - custom despawn distances int l = k * k; -- if (this.noActionTime > 600 && this.random.nextInt(800) == 0 && d0 > (double) l) { // CraftBukkit - remove isTypeNotPersistent() check -+ if (this.noActionTime > 600 && this.random.nextInt(800) == 0 && d0 > level.paperConfig.softDespawnDistance) { // CraftBukkit - remove isTypeNotPersistent() check // Paper - custom despawn distances - this.discard(); -- } else if (d0 < (double) l) { -+ } else if (d0 < level.paperConfig.softDespawnDistance) { // Paper - custom despawn distances - this.noActionTime = 0; - } - } + if (this.noActionTime > 600 && this.random.nextInt(800) == 0 && d0 > (double) l) { // CraftBukkit - remove isTypeNotPersistent() check diff --git a/patches/server/Add-tick-times-API-and-mspt-command.patch b/patches/server/Add-tick-times-API-and-mspt-command.patch index a3a70941ab..d8122d0d36 100644 --- a/patches/server/Add-tick-times-API-and-mspt-command.patch +++ b/patches/server/Add-tick-times-API-and-mspt-command.patch @@ -84,8 +84,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 commands.put("paper", new PaperCommand("paper")); + commands.put("mspt", new MSPTCommand("mspt")); - version = getInt("config-version", 23); - set("config-version", 23); + version = getInt("config-version", 24); + set("config-version", 24); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java diff --git a/patches/server/Allow-for-toggling-of-spawn-chunks.patch b/patches/server/Allow-for-toggling-of-spawn-chunks.patch index 1aa084f151..3c94f266a3 100644 --- a/patches/server/Allow-for-toggling-of-spawn-chunks.patch +++ b/patches/server/Allow-for-toggling-of-spawn-chunks.patch @@ -9,8 +9,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java @@ -0,0 +0,0 @@ public class PaperWorldConfig { - softDespawnDistance = softDespawnDistance*softDespawnDistance; - hardDespawnDistance = hardDespawnDistance*hardDespawnDistance; + hardDespawnDistances.put(category, hardDistance); + } } + + public boolean keepSpawnInMemory; diff --git a/patches/server/Anti-Xray.patch b/patches/server/Anti-Xray.patch index 592bc3392f..affabf4b10 100644 --- a/patches/server/Anti-Xray.patch +++ b/patches/server/Anti-Xray.patch @@ -14,6 +14,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import java.util.Arrays; import java.util.List; + import it.unimi.dsi.fastutil.objects.Reference2IntMap; + import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; + import net.minecraft.world.entity.MobCategory; +import com.destroystokyo.paper.antixray.ChunkPacketBlockControllerAntiXray.EngineMode; import org.bukkit.Bukkit; import org.bukkit.configuration.file.YamlConfiguration; diff --git a/patches/server/Configurable-door-breaking-difficulty.patch b/patches/server/Configurable-door-breaking-difficulty.patch index 79052186b7..a9d9815603 100644 --- a/patches/server/Configurable-door-breaking-difficulty.patch +++ b/patches/server/Configurable-door-breaking-difficulty.patch @@ -8,11 +8,10 @@ diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/m index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -@@ -0,0 +0,0 @@ package com.destroystokyo.paper; - - import java.util.Arrays; - import java.util.List; -- +@@ -0,0 +0,0 @@ import java.util.List; + import it.unimi.dsi.fastutil.objects.Reference2IntMap; + import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; + import net.minecraft.world.entity.MobCategory; +import java.util.stream.Collectors; +import net.minecraft.world.Difficulty; +import net.minecraft.world.entity.monster.Vindicator; diff --git a/patches/server/Entity-load-save-limit-per-chunk.patch b/patches/server/Entity-load-save-limit-per-chunk.patch index 1f93289717..655431bd35 100644 --- a/patches/server/Entity-load-save-limit-per-chunk.patch +++ b/patches/server/Entity-load-save-limit-per-chunk.patch @@ -12,12 +12,11 @@ diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/m index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -@@ -0,0 +0,0 @@ - package com.destroystokyo.paper; - - import java.util.Arrays; +@@ -0,0 +0,0 @@ import java.util.List; + import it.unimi.dsi.fastutil.objects.Reference2IntMap; + import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; + import net.minecraft.world.entity.MobCategory; +import java.util.HashMap; - import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import net.minecraft.world.Difficulty; diff --git a/patches/server/Optimise-nearby-player-lookups.patch b/patches/server/Optimise-nearby-player-lookups.patch index 0442ff50be..2cbe711583 100644 --- a/patches/server/Optimise-nearby-player-lookups.patch +++ b/patches/server/Optimise-nearby-player-lookups.patch @@ -226,7 +226,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } else if (!this.isPersistenceRequired() && !this.requiresCustomPersistence()) { - Player entityhuman = this.level.findNearbyPlayer(this, -1.0D, EntitySelector.affectsSpawning); // Paper + // Paper start - optimise checkDespawn -+ Player entityhuman = this.level.findNearbyPlayer(this, level.paperConfig.hardDespawnDistance + 1, EntitySelector.affectsSpawning); // Paper ++ Player entityhuman = this.level.findNearbyPlayer(this, level.paperConfig.hardDespawnDistances.getInt(this.getType().getCategory()) + 1, EntitySelector.affectsSpawning); // Paper + if (entityhuman == null) { + entityhuman = ((ServerLevel)this.level).playersAffectingSpawning.isEmpty() ? null : ((ServerLevel)this.level).playersAffectingSpawning.get(0); + } diff --git a/patches/server/Paper-config-files.patch b/patches/server/Paper-config-files.patch index 252723d1fa..978715103a 100644 --- a/patches/server/Paper-config-files.patch +++ b/patches/server/Paper-config-files.patch @@ -364,8 +364,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + commands = new HashMap(); + commands.put("paper", new PaperCommand("paper")); + -+ version = getInt("config-version", 23); -+ set("config-version", 23); ++ version = getInt("config-version", 24); ++ set("config-version", 24); + readConfig(PaperConfig.class, null); + } + @@ -405,7 +405,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + } + } ++ saveConfig(); ++ } + ++ static void saveConfig() { + try { + config.save(CONFIG_FILE); + } catch (IOException ex) { @@ -503,6 +506,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + +import static com.destroystokyo.paper.PaperConfig.log; +import static com.destroystokyo.paper.PaperConfig.logError; ++import static com.destroystokyo.paper.PaperConfig.saveConfig; + +public class PaperWorldConfig { + @@ -531,6 +535,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + } + ++ public void removeOldValues() { ++ boolean needsSave = false; ++ ++ if (needsSave) { ++ saveConfig(); ++ } ++ } ++ + private boolean getBoolean(String path, boolean def) { + config.addDefault("world-settings.default." + path, def); + return config.getBoolean("world-settings." + worldName + "." + path, config.getBoolean("world-settings.default." + path)); @@ -542,8 +554,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + private int getInt(String path, int def) { -+ config.addDefault("world-settings.default." + path, def); -+ return config.getInt("world-settings." + worldName + "." + path, config.getInt("world-settings.default." + path)); ++ return getInt(path, def, true); ++ } ++ ++ private int getInt(String path, int def, boolean setDefault) { ++ if (setDefault) { ++ config.addDefault("world-settings.default." + path, def); ++ } ++ return config.getInt("world-settings." + worldName + "." + path, config.getInt("world-settings.default." + path, def)); + } + + private long getLong(String path, long def) { @@ -604,6 +622,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public static void forceUpgrade(LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, boolean eraseCache, BooleanSupplier booleansupplier, ImmutableSet> worlds) { // CraftBukkit Main.LOGGER.info("Forcing world upgrade! {}", session.getLevelId()); // CraftBukkit WorldUpgrader worldupgrader = new WorldUpgrader(session, dataFixer, worlds, eraseCache); +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop perWorldSpawnLimits = new Reference2IntOpenHashMap<>(NaturalSpawner.SPAWNING_CATEGORIES.length); + private void perWorldSpawnLimits() { -+ spawnLimitMonsters = getInt("spawn-limits.monsters", spawnLimitMonsters); -+ spawnLimitAnimals = getInt("spawn-limits.animals", spawnLimitAnimals); -+ spawnLimitWaterAnimals = getInt("spawn-limits.water-animals", spawnLimitWaterAnimals); -+ spawnLimitWaterAmbient = getInt("spawn-limits.water-ambient", spawnLimitWaterAmbient); -+ spawnLimitAmbient = getInt("spawn-limits.ambient", spawnLimitAmbient); ++ perWorldSpawnLimits.defaultReturnValue(-1); ++ if (PaperConfig.version < 24) { ++ // ambient category already had correct name ++ perWorldSpawnLimits.put(MobCategory.MONSTER, getInt("spawn-limits.monsters", -1, false)); ++ perWorldSpawnLimits.put(MobCategory.CREATURE, getInt("spawn-limits.animals", -1, false)); ++ perWorldSpawnLimits.put(MobCategory.WATER_CREATURE, getInt("spawn-limits.water-animals", -1, false)); ++ perWorldSpawnLimits.put(MobCategory.WATER_AMBIENT, getInt("spawn-limits.water-ambient", -1, false)); ++ } ++ for (MobCategory value : NaturalSpawner.SPAWNING_CATEGORIES) { ++ perWorldSpawnLimits.put(value, getInt("spawn-limits." + value.getName(), perWorldSpawnLimits.getInt(value))); ++ } + } + public int lightQueueSize = 20; @@ -38,11 +60,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.environment = env; + // Paper start - per world spawn limits -+ this.monsterSpawn = this.world.paperConfig.spawnLimitMonsters; -+ this.animalSpawn = this.world.paperConfig.spawnLimitAnimals; -+ this.waterAnimalSpawn = this.world.paperConfig.spawnLimitWaterAnimals; -+ this.waterAmbientSpawn = this.world.paperConfig.spawnLimitWaterAmbient; -+ this.ambientSpawn = this.world.paperConfig.spawnLimitAmbient; ++ this.monsterSpawn = this.world.paperConfig.perWorldSpawnLimits.getInt(net.minecraft.world.entity.MobCategory.MONSTER); ++ this.animalSpawn = this.world.paperConfig.perWorldSpawnLimits.getInt(net.minecraft.world.entity.MobCategory.CREATURE); ++ this.waterAnimalSpawn = this.world.paperConfig.perWorldSpawnLimits.getInt(net.minecraft.world.entity.MobCategory.WATER_CREATURE); ++ this.waterAmbientSpawn = this.world.paperConfig.perWorldSpawnLimits.getInt(net.minecraft.world.entity.MobCategory.WATER_AMBIENT); ++ this.ambientSpawn = this.world.paperConfig.perWorldSpawnLimits.getInt(net.minecraft.world.entity.MobCategory.AMBIENT); ++ this.waterUndergroundCreatureSpawn = this.world.paperConfig.perWorldSpawnLimits.getInt(net.minecraft.world.entity.MobCategory.UNDERGROUND_WATER_CREATURE); + // Paper end }