9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-30 20:39:21 +00:00
Files
Leaf/patches/server/0097-Paper-PR-Throttle-failed-spawn-attempts.patch
Dreeam 03a888a390 Updated Upstream (Paper/Gale)
Upstream has released updates that appear to apply and compile correctly

Paper Changes:
PaperMC/Paper@2fdb2e9 Fix structure check API (#11307)
PaperMC/Paper@fcedb49 Update spark-paper
PaperMC/Paper@956b3d1 Ensure MaterialChoice materials are items (#11325)
PaperMC/Paper@5625051 Prevent duplicate pickup event for piglins (#11322)
PaperMC/Paper@94444ce Fix incorrect timestamp in region file header recalculation (#11318)
PaperMC/Paper@5b2c43e Remove set damage lootable item function from compasses (#11317)
PaperMC/Paper@5167856 Fix despawn ranges by defaulting to an ellipsoid shape (#11312)
PaperMC/Paper@e2da65c Deprecate API relating to menu title changes (#11309)
PaperMC/Paper@ad4c524 Properly destroy placed blocks on the end platform (#11292)
PaperMC/Paper@374d9c8 Add a method to reset Lodestone compasses back to normal ones (#11308)
PaperMC/Paper@dd8c70a Ensure TabCompleteEvent always has a mutable backing list. (#11302)
PaperMC/Paper@a7b8d95 Add enchantment seed update API (#11282)
PaperMC/Paper@789a267 Re-implement maxLeashDistance world conf and call missing event (#11301)
PaperMC/Paper@e08e667 Fix: synchronise sending chat to client with updating message signature cache (#11332)
PaperMC/Paper@2562124 [ci skip] Create SECURITY.md (#11331)

Gale Changes:
Dreeam-qwq/Gale@d8e8537 Updated Upstream (Paper)
Dreeam-qwq/Gale@492609e Updated Upstream (Paper)
Dreeam-qwq/Gale@d9a7cf0 Updated Upstream (Paper)
Dreeam-qwq/Gale@afbc1ea Updated Upstream (Paper)
2024-08-27 20:27:01 -04:00

139 lines
8.5 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: froobynooby <froobynooby@froobworld.com>
Date: Wed, 17 Jul 2024 18:46:11 +0930
Subject: [PATCH] Paper PR: Throttle failed spawn attempts
Original license: GPLv3
Original project: https://github.com/PaperMC/Paper
Paper pull request: https://github.com/PaperMC/Paper/pull/11099
For example config in paper-world-defaults.yml
```
spawning-throttle:
failed-attempts-threshold: 1200
throttled-ticks-per-spawn:
ambient: 10 # default value in bukkit.yml tickers-per * 10
axolotls: 10
creature: 4000
monster: 10
underground_water_creature: 10
water_ambient: 10
water_creature: 10
```
This patch adds the option to use longer ticks-per-spawn for a given
mob type in chunks where spawn attempts are consecutively failing.
This behaviour is particularly useful on servers where players build
mob farms. Mob farm designs often require making surrounding chunks
spawnproof, which causes the server to waste CPU cycles trying to spawn mobs in
vain. Throttling spawn attempts in suspected spawnproof chunks improves
performance without noticeably advantaging or disadvantaging the mob farm.
diff --git a/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java
index aa3624fb8aaaf2720aaef7800f537dd4b906797f..1b8fb4856fa53886e5028a666d3651d1f281d4d4 100644
--- a/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java
+++ b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java
@@ -190,6 +190,15 @@ public class WorldConfiguration extends ConfigurationPart {
@MergeMap
public Reference2IntMap<MobCategory> ticksPerSpawn = Util.make(new Reference2IntOpenHashMap<>(NaturalSpawner.SPAWNING_CATEGORIES.length), map -> Arrays.stream(NaturalSpawner.SPAWNING_CATEGORIES).forEach(mobCategory -> map.put(mobCategory, -1)));
+ public SpawningThrottle spawningThrottle;
+
+ public class SpawningThrottle extends ConfigurationPart {
+ public IntOr.Disabled failedAttemptsThreshold = IntOr.Disabled.DISABLED;
+
+ @MergeMap
+ public Reference2IntMap<MobCategory> throttledTicksPerSpawn = Util.make(new Reference2IntOpenHashMap<>(NaturalSpawner.SPAWNING_CATEGORIES.length), map -> Arrays.stream(NaturalSpawner.SPAWNING_CATEGORIES).forEach(mobCategory -> map.put(mobCategory, -1)));
+ }
+
@ConfigSerializable
public record DespawnRangePair(@Required DespawnRange hard, @Required DespawnRange soft) {
public static DespawnRangePair createDefault() {
diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
index 7e1a007ed2f2c625f01fea210c9935cb02d119e0..8e9ada03e5134d2f776bbbf872087121f649c19d 100644
--- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java
+++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
@@ -138,8 +138,14 @@ public final class NaturalSpawner {
boolean spawnThisTick = true;
int limit = enumcreaturetype.getMaxInstancesPerChunk();
SpawnCategory spawnCategory = CraftSpawnCategory.toBukkit(enumcreaturetype);
+ // Paper start - throttle failed spawn attempts
+ long ticksPerSpawn = world.ticksPerSpawnCategory.getLong(spawnCategory);
+ if (world.paperConfig().entities.spawning.spawningThrottle.failedAttemptsThreshold.test(threshold -> chunk.failedSpawnAttempts[enumcreaturetype.ordinal()] > threshold)) {
+ ticksPerSpawn = Math.max(ticksPerSpawn, world.paperConfig().entities.spawning.spawningThrottle.throttledTicksPerSpawn.getOrDefault(enumcreaturetype, -1));
+ }
+ // Paper end - throttle failed spawn attempts
if (CraftSpawnCategory.isValidForLimits(spawnCategory)) {
- spawnThisTick = world.ticksPerSpawnCategory.getLong(spawnCategory) != 0 && worlddata.getGameTime() % world.ticksPerSpawnCategory.getLong(spawnCategory) == 0;
+ spawnThisTick = world.ticksPerSpawnCategory.getLong(spawnCategory) != 0 && worlddata.getGameTime() % ticksPerSpawn == 0; // Paper - throttle failed spawn attempts
limit = world.getWorld().getSpawnLimit(spawnCategory);
}
@@ -176,6 +182,13 @@ public final class NaturalSpawner {
difference, world.paperConfig().entities.spawning.perPlayerMobSpawns ? world.getChunkSource().chunkMap::updatePlayerMobTypeMap : null);
info.mobCategoryCounts.mergeInt(enumcreaturetype, spawnCount, Integer::sum);
// Paper end - Optional per player mob spawns
+ // Paper start - throttle failed spawn attempts
+ if (spawnCount == 0) {
+ chunk.failedSpawnAttempts[enumcreaturetype.ordinal()]++;
+ } else {
+ chunk.failedSpawnAttempts[enumcreaturetype.ordinal()] = 0;
+ }
+ // Paper end - throttle failed spawn attempts
}
}
}
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
index 5bb8fe022f580a626a99324f53515890a99b798d..5cee82d3d17739858e47f24ec5340233f09d0713 100644
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
@@ -84,6 +84,7 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom
public final Map<BlockPos, BlockEntity> blockEntities = new Object2ObjectOpenHashMap();
protected final LevelHeightAccessor levelHeightAccessor;
protected final LevelChunkSection[] sections;
+ public final long[] failedSpawnAttempts = new long[net.minecraft.world.entity.MobCategory.values().length]; // Paper - throttle failed spawn attempts
// Leaf start - Matter - Feature Secure Seed
private boolean slimeChunk;
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
index 4bd048387651250135f963303c78c17f8473cfee..8257177404b23e131143017f3a7d835ad447f9fb 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
@@ -302,6 +302,16 @@ public class ChunkSerializer {
((ChunkAccess) object1).addPackedPostProcess(nbttaglist2.getShort(i1), j1);
}
}
+ // Paper start - throttle failed spawn attempts
+ if (nbt.contains("Paper.FailedSpawnAttempts", Tag.TAG_COMPOUND)) {
+ CompoundTag failedSpawnAttemptsTag = nbt.getCompound("Paper.FailedSpawnAttempts");
+ for (net.minecraft.world.entity.MobCategory mobCategory : net.minecraft.world.level.NaturalSpawner.SPAWNING_CATEGORIES) {
+ if (failedSpawnAttemptsTag.contains(mobCategory.getSerializedName(), Tag.TAG_LONG)) {
+ ((ChunkAccess) object1).failedSpawnAttempts[mobCategory.ordinal()] = failedSpawnAttemptsTag.getLong(mobCategory.getSerializedName());
+ }
+ }
+ }
+ // Paper end - throttle failed spawn attempts
ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.loadLightHook(world, chunkPos, nbt, (ChunkAccess)object1); // Paper - rewrite chunk system - note: it's ok to pass the raw value instead of wrapped
@@ -545,6 +555,18 @@ public class ChunkSerializer {
nbttagcompound.put("ChunkBukkitValues", chunk.persistentDataContainer.toTagCompound());
}
// CraftBukkit end
+ // Paper start - throttle failed spawn attempts
+ CompoundTag failedSpawnAttemptsTag = new CompoundTag();
+ for (net.minecraft.world.entity.MobCategory mobCategory : net.minecraft.world.entity.MobCategory.values()) {
+ long failedSpawnAttempts = chunk.failedSpawnAttempts[mobCategory.ordinal()];
+ if (failedSpawnAttempts > 0) {
+ failedSpawnAttemptsTag.putLong(mobCategory.getSerializedName(), failedSpawnAttempts);
+ }
+ }
+ if (!failedSpawnAttemptsTag.isEmpty()) {
+ nbttagcompound.put("Paper.FailedSpawnAttempts", failedSpawnAttemptsTag);
+ }
+ // Paper end - throttle failed spawn attempts
ca.spottedleaf.moonrise.patches.starlight.util.SaveUtil.saveLightHook(world, chunk, nbttagcompound); // Paper - rewrite chunk system
return nbttagcompound;
}