9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-29 03:49:21 +00:00

Merge branch 'ver/1.21.4' into dev/random-tick

This commit is contained in:
hayanesuru
2025-06-13 18:19:09 +09:00
121 changed files with 778 additions and 336 deletions

View File

@@ -29,7 +29,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
along with this program. If not, see <https://www.gnu.org/licenses/>.
diff --git a/io/papermc/paper/entity/activation/ActivationRange.java b/io/papermc/paper/entity/activation/ActivationRange.java
index 6db99585fa47fe2d2ae6eff8efe16190dd756511..a9269356de964585028e69a3713ca64f67ba02bf 100644

View File

@@ -3,6 +3,23 @@ From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com>
Date: Thu, 28 Mar 2024 13:36:09 -0400
Subject: [PATCH] Cache player profileResult
This patch includes code that references the Caffeine caching library,
which is licensed under the Apache License, Version 2.0.
Caffeine (https://github.com/ben-manes/caffeine)
Copyright (c) Ben Manes
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
diff --git a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
index 069477e524a28b20a0289221858bdc802704a890..114b25f933c6a1b011523581a5a02a5a2c1e827e 100644

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Replace brain maps with optimized collection
diff --git a/net/minecraft/world/entity/ai/Brain.java b/net/minecraft/world/entity/ai/Brain.java
index 083eb9a7a0bc14d30db944f356d98ca552fa1784..778e3b99a7f941a53b87cbec510db8deed5d77c8 100644
index 083eb9a7a0bc14d30db944f356d98ca552fa1784..10986e50bd3307f81074c4cb371eb4d7defc9cfc 100644
--- a/net/minecraft/world/entity/ai/Brain.java
+++ b/net/minecraft/world/entity/ai/Brain.java
@@ -45,14 +45,18 @@ public class Brain<E extends LivingEntity> {
@@ -14,11 +14,10 @@ index 083eb9a7a0bc14d30db944f356d98ca552fa1784..778e3b99a7f941a53b87cbec510db8de
private static final int SCHEDULE_UPDATE_DELAY = 20;
- private final Map<MemoryModuleType<?>, Optional<? extends ExpirableValue<?>>> memories = Maps.newHashMap();
- private final Map<SensorType<? extends Sensor<? super E>>, Sensor<? super E>> sensors = Maps.newLinkedHashMap();
- private final Map<Integer, Map<Activity, Set<BehaviorControl<? super E>>>> availableBehaviorsByPriority = Maps.newTreeMap();
+ // Leaf start - Replace brain maps with optimized collection
+ private final Map<MemoryModuleType<?>, Optional<? extends ExpirableValue<?>>> memories = new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>();
+ private final Map<SensorType<? extends Sensor<? super E>>, Sensor<? super E>> sensors = new it.unimi.dsi.fastutil.objects.Reference2ReferenceLinkedOpenHashMap<>();
+ private final Map<Integer, Map<Activity, Set<BehaviorControl<? super E>>>> availableBehaviorsByPriority = new it.unimi.dsi.fastutil.objects.Object2ObjectRBTreeMap<>();
private final Map<Integer, Map<Activity, Set<BehaviorControl<? super E>>>> availableBehaviorsByPriority = Maps.newTreeMap();
+ // Leaf end - Replace brain maps with optimized collection
private Schedule schedule = Schedule.EMPTY;
- private final Map<Activity, Set<Pair<MemoryModuleType<?>, MemoryStatus>>> activityRequirements = Maps.newHashMap();

View File

@@ -4,6 +4,23 @@ Date: Sun, 23 Jun 2024 11:26:20 +0800
Subject: [PATCH] Use caffeine cache for kickPermission instead of using
google.common.cache
This patch includes code that references the Caffeine caching library,
which is licensed under the Apache License, Version 2.0.
Caffeine (https://github.com/ben-manes/caffeine)
Copyright (c) Ben Manes
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 24aca7ba2cc3ec5f05bb4ea7d373feb730d8dd90..c30e017e6cffa6aa828b0f6e8889885dbaaa4680 100644

View File

@@ -1,47 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Taiyou06 <kaandindar21@gmail.com>
Date: Tue, 9 Nov 2077 00:00:00 +0800
Subject: [PATCH] Collect then startEachNonRunningBehavior in Brain
diff --git a/net/minecraft/world/entity/ai/Brain.java b/net/minecraft/world/entity/ai/Brain.java
index c561b749fb9b76ba9b1e9689089b743248c65d50..ea6c8e85ccff67b1c24109732f74f1e8199cad07 100644
--- a/net/minecraft/world/entity/ai/Brain.java
+++ b/net/minecraft/world/entity/ai/Brain.java
@@ -453,20 +453,29 @@ public class Brain<E extends LivingEntity> {
}
private void startEachNonRunningBehavior(ServerLevel level, E entity) {
- long gameTime = level.getGameTime();
+ // Leaf start - Collect then startEachNonRunningBehavior in Brain
+ final long gameTime = level.getGameTime();
+ List<BehaviorControl<? super E>> behaviorsToStart = new ObjectArrayList<>();
- for (Map<Activity, Set<BehaviorControl<? super E>>> map : this.availableBehaviorsByPriority.values()) {
- for (Entry<Activity, Set<BehaviorControl<? super E>>> entry : map.entrySet()) {
- Activity activity = entry.getKey();
- if (this.activeActivities.contains(activity)) {
- for (BehaviorControl<? super E> behaviorControl : entry.getValue()) {
+ for (Activity activeActivity : this.activeActivities) {
+ for (Map<Activity, Set<BehaviorControl<? super E>>> priorityMap : this.availableBehaviorsByPriority.values()) {
+ Set<BehaviorControl<? super E>> behaviors = priorityMap.get(activeActivity);
+
+ if (behaviors != null && !behaviors.isEmpty()) {
+ for (BehaviorControl<? super E> behaviorControl : behaviors) {
if (behaviorControl.getStatus() == Behavior.Status.STOPPED) {
- behaviorControl.tryStart(level, entity, gameTime);
+ behaviorsToStart.add(behaviorControl);
}
}
}
}
}
+ if (!behaviorsToStart.isEmpty()) {
+ for (BehaviorControl<? super E> behaviorControl : behaviorsToStart) {
+ behaviorControl.tryStart(level, entity, gameTime);
+ }
+ }
+ // Leaf end - Collect then startEachNonRunningBehavior in Brain
}
private void tickEachRunningBehavior(ServerLevel level, E entity) {

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Replace brain activity maps with optimized collection
diff --git a/net/minecraft/world/entity/ai/Brain.java b/net/minecraft/world/entity/ai/Brain.java
index ea6c8e85ccff67b1c24109732f74f1e8199cad07..e27284f9897923f67985e3d60c3438bd00cc4a51 100644
index 778e3b99a7f941a53b87cbec510db8deed5d77c8..4dde1642a33349335f374f17123a700dde1079d7 100644
--- a/net/minecraft/world/entity/ai/Brain.java
+++ b/net/minecraft/world/entity/ai/Brain.java
@@ -390,8 +390,8 @@ public class Brain<E extends LivingEntity> {

View File

@@ -42,10 +42,10 @@ index be820c6093dd2ae7642b9bee11edf65e3a8d7242..06ac3537f5655d048d770bb004243f20
boolean ret = false;
final boolean canProcessFullUpdates = processFullUpdates & isTickThread;
diff --git a/io/papermc/paper/redstone/RedstoneWireTurbo.java b/io/papermc/paper/redstone/RedstoneWireTurbo.java
index ff747a1ecdf3c888bca0d69de4f85dcd810b6139..62ecbbf7c167beaa3b67fc4c30e901c5d359d6b8 100644
index ff747a1ecdf3c888bca0d69de4f85dcd810b6139..b288d57d9f7bd0ccf1877cf9920bd67288ff22f7 100644
--- a/io/papermc/paper/redstone/RedstoneWireTurbo.java
+++ b/io/papermc/paper/redstone/RedstoneWireTurbo.java
@@ -829,14 +829,8 @@ public final class RedstoneWireTurbo {
@@ -829,14 +829,10 @@ public final class RedstoneWireTurbo {
j = getMaxCurrentStrength(upd, j);
int l = 0;
@@ -57,8 +57,10 @@ index ff747a1ecdf3c888bca0d69de4f85dcd810b6139..62ecbbf7c167beaa3b67fc4c30e901c5
- // is consistency to what this call returns, we may be able to cache it.
- final int k = worldIn.getBestNeighborSignal(upd.self);
- wire.shouldSignal = true;
+ // Leaf start - SparklyPaper - parallel world ticking
+ // This now correctly calls the (conditionally) thread-safe method in RedStoneWireBlock
+ final int k = wire.getBlockSignal(worldIn, upd.self);
+ // Leaf end - SparklyPaper - parallel world ticking
// The variable 'k' holds the maximum redstone power value of any adjacent blocks.
// If 'k' has the highest level of all neighbors, then the power level of this
@@ -1361,7 +1363,7 @@ index 904369f4d7db41026183f2de7c96c2f0f4dc204d..afd952ddc8942818ec01d1c750413776
return true;
} else {
diff --git a/net/minecraft/world/level/block/RedStoneWireBlock.java b/net/minecraft/world/level/block/RedStoneWireBlock.java
index 12c9d60314c99fb65e640d255a2d0c6b7790ad4d..5a60c5e4fe122d37a0aed1269128aa5e6e5e87b8 100644
index 12c9d60314c99fb65e640d255a2d0c6b7790ad4d..9d655558e8a15e4861a66e545b0991968e747b58 100644
--- a/net/minecraft/world/level/block/RedStoneWireBlock.java
+++ b/net/minecraft/world/level/block/RedStoneWireBlock.java
@@ -91,7 +91,10 @@ public class RedStoneWireBlock extends Block {
@@ -1427,7 +1429,7 @@ index 12c9d60314c99fb65e640d255a2d0c6b7790ad4d..5a60c5e4fe122d37a0aed1269128aa5e
}
private void checkCornerChangeAt(Level level, BlockPos pos) {
@@ -450,24 +472,34 @@ public class RedStoneWireBlock extends Block {
@@ -450,12 +472,21 @@ public class RedStoneWireBlock extends Block {
@Override
protected int getDirectSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) {
@@ -1451,13 +1453,7 @@ index 12c9d60314c99fb65e640d255a2d0c6b7790ad4d..5a60c5e4fe122d37a0aed1269128aa5e
int powerValue = blockState.getValue(POWER);
if (powerValue == 0) {
return 0;
} else {
return side != Direction.UP
- && !this.getConnectionState(blockAccess, blockState, pos).getValue(PROPERTY_BY_DIRECTION.get(side.getOpposite())).isConnected()
+ && !this.getConnectionState(blockAccess, blockState, pos).getValue(PROPERTY_BY_DIRECTION.get(side.getOpposite())).isConnected()
? 0
: powerValue;
}
@@ -468,6 +499,7 @@ public class RedStoneWireBlock extends Block {
} else {
return 0;
}

View File

@@ -1,11 +1,11 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Taiyou06 <kaandindar21@gmail.com>
Date: Thu, 8 May 2025 13:30:07 +0200
Subject: [PATCH] Optimise BlockEntities tickersInLevel
Subject: [PATCH] Optimize BlockEntities tickersInLevel
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
index 546fb78339c005ed71142cb3c894f816b8c72d08..e6eab6929b08503c49debbbd25497ffedad438e1 100644
index 546fb78339c005ed71142cb3c894f816b8c72d08..a90bf0d80ae4dac9b19b8e467b402917cc19a271 100644
--- a/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
@@ -72,7 +72,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
@@ -13,7 +13,7 @@ index 546fb78339c005ed71142cb3c894f816b8c72d08..e6eab6929b08503c49debbbd25497ffe
}
};
- private final Map<BlockPos, LevelChunk.RebindableTickingBlockEntityWrapper> tickersInLevel = Maps.newHashMap();
+ private final Map<BlockPos, LevelChunk.RebindableTickingBlockEntityWrapper> tickersInLevel = org.dreeam.leaf.config.modules.opt.OptimiseBlockEntities.enabled ? new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>() : Maps.newHashMap(); // Leaf - Optimise BlockEntities tickersInLevel
+ private final Map<BlockPos, LevelChunk.RebindableTickingBlockEntityWrapper> tickersInLevel = org.dreeam.leaf.config.modules.opt.OptimizeBlockEntities.enabled ? new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>() : Maps.newHashMap(); // Leaf - Optimise BlockEntities tickersInLevel
public boolean loaded;
public final ServerLevel level; // CraftBukkit - type
@Nullable

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] optimize getEntityStatus
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java
index 7554c109c35397bc1a43dd80e87764fd78645bbf..151476fd036839a416c226599279d0d8bf79717b 100644
index 7554c109c35397bc1a43dd80e87764fd78645bbf..8ae35834bb35ace0bf0ad2c79a80500cbcb19cad 100644
--- a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java
@@ -93,8 +93,14 @@ public abstract class EntityLookup implements LevelEntityGetter<Entity> {
@@ -14,14 +14,14 @@ index 7554c109c35397bc1a43dd80e87764fd78645bbf..151476fd036839a416c226599279d0d8
}
- final Visibility visibility = EntityLookup.getEntityStatus(entity);
- return visibility.isAccessible() ? entity : null;
+ // Leaf start
+ // Leaf start - optimize getEntityStatus
+ final FullChunkStatus entityStatus = ((ChunkSystemEntity) entity).moonrise$getChunkStatus();
+ return switch (entityStatus) {
+ case INACCESSIBLE -> null;
+ case FULL, BLOCK_TICKING, ENTITY_TICKING -> entity;
+ case null -> null;
+ };
+ // Leaf end
+ // Leaf end - optimize getEntityStatus
}
@Override
@@ -30,34 +30,14 @@ index 7554c109c35397bc1a43dd80e87764fd78645bbf..151476fd036839a416c226599279d0d8
}
final FullChunkStatus entityStatus = ((ChunkSystemEntity)entity).moonrise$getChunkStatus();
- return Visibility.fromFullChunkStatus(entityStatus == null ? FullChunkStatus.INACCESSIBLE : entityStatus);
+ // Leaf start
+ // Leaf start - optimize getEntityStatus
+ return switch (entityStatus) {
+ case INACCESSIBLE -> Visibility.HIDDEN;
+ case FULL, BLOCK_TICKING -> Visibility.TRACKED;
+ case ENTITY_TICKING -> Visibility.TICKING;
+ case null -> Visibility.HIDDEN;
+ };
+ // Leaf end
+ // Leaf end - optimize getEntityStatus
}
protected boolean addEntity(final Entity entity, final boolean fromDisk, final boolean event) {
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 64f24d3e0ecb91e0b4df6229354aeac549234f1b..80baa2dff5c1034a72271fc727fdb2acc1b69488 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -381,6 +381,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
// Paper end
// Paper start - rewrite chunk system
private final boolean isHardColliding = this.moonrise$isHardCollidingUncached();
+ @org.jetbrains.annotations.Nullable // Leaf
private net.minecraft.server.level.FullChunkStatus chunkStatus;
private ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData chunkData;
private int sectionX = Integer.MIN_VALUE;
@@ -394,6 +395,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
@Override
+ @org.jetbrains.annotations.Nullable // Leaf
public final net.minecraft.server.level.FullChunkStatus moonrise$getChunkStatus() {
return this.chunkStatus;
}

View File

@@ -6,7 +6,7 @@ Subject: [PATCH] optimise ChunkGenerator#getMobsAt
inline fillStartsForStructure
diff --git a/net/minecraft/world/level/StructureManager.java b/net/minecraft/world/level/StructureManager.java
index 8bc6a6c86cd8db53feefba7508b6031ba67e242e..20a2bc31a8082afd4f758bd7e91691bbc58ba16e 100644
index 8bc6a6c86cd8db53feefba7508b6031ba67e242e..90397f237c0cb79da03b3f9ca7445676324ebd11 100644
--- a/net/minecraft/world/level/StructureManager.java
+++ b/net/minecraft/world/level/StructureManager.java
@@ -78,7 +78,7 @@ public class StructureManager {
@@ -14,7 +14,7 @@ index 8bc6a6c86cd8db53feefba7508b6031ba67e242e..20a2bc31a8082afd4f758bd7e91691bb
public void fillStartsForStructure(Structure structure, LongSet structureRefs, Consumer<StructureStart> startConsumer) {
for (long l : structureRefs) {
- SectionPos sectionPos = SectionPos.of(new ChunkPos(l), this.level.getMinSectionY());
+ SectionPos sectionPos = SectionPos.of(ChunkPos.getX(l), this.level.getMinSectionY(), ChunkPos.getZ(l)); // Leaf
+ SectionPos sectionPos = SectionPos.of(ChunkPos.getX(l), this.level.getMinSectionY(), ChunkPos.getZ(l)); // Leaf - optimise ChunkGenerator#getMobsAt
StructureStart startForStructure = this.getStartForStructure(
sectionPos, structure, this.level.getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.STRUCTURE_STARTS)
);
@@ -24,13 +24,13 @@ index 8bc6a6c86cd8db53feefba7508b6031ba67e242e..20a2bc31a8082afd4f758bd7e91691bb
public Map<Structure, LongSet> getAllStructuresAt(BlockPos pos) {
- SectionPos sectionPos = SectionPos.of(pos);
- return this.level.getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.STRUCTURE_REFERENCES).getAllReferences();
+ // SectionPos sectionPos = SectionPos.of(pos); // Leaf
+ return this.level.getChunk(pos.getX() >> 4, pos.getZ() >> 4, ChunkStatus.STRUCTURE_REFERENCES).getAllReferences(); // Leaf
+ //SectionPos sectionPos = SectionPos.of(pos); // Leaf - optimise ChunkGenerator#getMobsAt
+ return this.level.getChunk(pos.getX() >> 4, pos.getZ() >> 4, ChunkStatus.STRUCTURE_REFERENCES).getAllReferences(); // Leaf - optimise ChunkGenerator#getMobsAt
}
public StructureCheckResult checkStructurePresence(ChunkPos chunkPos, Structure structure, StructurePlacement placement, boolean skipKnownStructures) {
diff --git a/net/minecraft/world/level/chunk/ChunkGenerator.java b/net/minecraft/world/level/chunk/ChunkGenerator.java
index 176adfcaa0fc458043d4bc05ead1861864b63606..87df3cd0981e94c28b816eb231942499c266a8da 100644
index 176adfcaa0fc458043d4bc05ead1861864b63606..755e635a2ece6ab6d3b166cb437e48b527041160 100644
--- a/net/minecraft/world/level/chunk/ChunkGenerator.java
+++ b/net/minecraft/world/level/chunk/ChunkGenerator.java
@@ -501,18 +501,20 @@ public abstract class ChunkGenerator {
@@ -44,7 +44,7 @@ index 176adfcaa0fc458043d4bc05ead1861864b63606..87df3cd0981e94c28b816eb231942499
- structureManager.fillStartsForStructure(structure, entry.getValue(), structureStart -> {
- if (mutableBoolean.isFalse() && predicate.test(structureStart)) {
- mutableBoolean.setTrue();
+ // Leaf start
+ // Leaf start - optimise ChunkGenerator#getMobsAt
+ for (long l : entry.getValue()) {
+ StructureStart startForStructure = structureManager.getStartForStructure(
+ null, structure, structureManager.level.getChunk(ChunkPos.getX(l), ChunkPos.getZ(l), ChunkStatus.STRUCTURE_STARTS)
@@ -60,7 +60,7 @@ index 176adfcaa0fc458043d4bc05ead1861864b63606..87df3cd0981e94c28b816eb231942499
- if (mutableBoolean.isTrue()) {
- return structureSpawnOverride.spawns();
}
+ // Leaf end
+ // Leaf end - optimise ChunkGenerator#getMobsAt
}
}

View File

@@ -57,7 +57,7 @@ index ce2621a87dec1befb016b3437ceb2d02ed6d0b75..9b37b763c6555705f3e256010f508b5a
public static boolean isInNetherFortressBounds(BlockPos pos, ServerLevel level, MobCategory category, StructureManager structureManager) {
diff --git a/net/minecraft/world/level/biome/BiomeManager.java b/net/minecraft/world/level/biome/BiomeManager.java
index a48175a7ebb1788ace46395621ed78d910178a53..cb6b99dd4504681bdf2f7dbd7e3d2218304f891a 100644
index a48175a7ebb1788ace46395621ed78d910178a53..00122472991ba0c1a0ea77053aad71cdfa92a7bd 100644
--- a/net/minecraft/world/level/biome/BiomeManager.java
+++ b/net/minecraft/world/level/biome/BiomeManager.java
@@ -15,10 +15,23 @@ public class BiomeManager {
@@ -129,7 +129,7 @@ index a48175a7ebb1788ace46395621ed78d910178a53..cb6b99dd4504681bdf2f7dbd7e3d2218
return Mth.square(zNoise + fiddle2) + Mth.square(yNoise + fiddle1) + Mth.square(xNoise + fiddle);
}
+ // Leaf start
+ // Leaf start - optimise getBiome
+ private static final double[] FIDDLE_TABLE = new double[1024];
+ static {
+ for (int i = 0; i < 1024; i++) {
@@ -139,9 +139,9 @@ index a48175a7ebb1788ace46395621ed78d910178a53..cb6b99dd4504681bdf2f7dbd7e3d2218
private static double getFiddle(long seed) {
- return (double)(((seed >> 24) & (1024 - 1)) - (1024/2)) * (0.9 / 1024.0); // Paper - avoid floorMod, fp division, and fp subtraction
+ return FIDDLE_TABLE[(int)(seed >>> 24) & 1023];
+ // return (double)(((seed >> 24) & (1024 - 1)) - (1024/2)) * (0.9 / 1024.0); // Paper - avoid floorMod, fp division, and fp subtraction
+ //return (double)(((seed >> 24) & (1024 - 1)) - (1024/2)) * (0.9 / 1024.0); // Paper - avoid floorMod, fp division, and fp subtraction
}
+ // Leaf end
+ // Leaf end - optimise getBiome
public interface NoiseBiomeSource {
Holder<Biome> getNoiseBiome(int x, int y, int z);

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] optimize mob spawning
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
index f57f8e610dac80b8095bfc0c7e4b22ff5ad6b13c..55f20122732e88037d24be311469b6cab72c37ad 100644
index f57f8e610dac80b8095bfc0c7e4b22ff5ad6b13c..c1efd558cfbfd2200295ef5755aa496e95deb7d7 100644
--- a/net/minecraft/server/level/ServerChunkCache.java
+++ b/net/minecraft/server/level/ServerChunkCache.java
@@ -70,7 +70,9 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
@@ -13,9 +13,9 @@ index f57f8e610dac80b8095bfc0c7e4b22ff5ad6b13c..55f20122732e88037d24be311469b6ca
@Nullable
@VisibleForDebug
- private NaturalSpawner.SpawnState lastSpawnState;
+ private volatile NaturalSpawner.SpawnState lastSpawnState; // Leaf
+ private long delayTimeInhabited = 0L; // Leaf
+ private long delaySpawn = -1L; // Leaf
+ private volatile NaturalSpawner.SpawnState lastSpawnState; // Leaf - optimize mob spawning
+ private long delayTimeInhabited = 0L; // Leaf - optimize mob spawning
+ private long delaySpawn = -1L; // Leaf - optimize mob spawning
// Paper start
public final ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable<net.minecraft.world.level.chunk.LevelChunk> fullChunks = new ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable<>();
public int getFullChunksCount() {
@@ -28,7 +28,7 @@ index f57f8e610dac80b8095bfc0c7e4b22ff5ad6b13c..55f20122732e88037d24be311469b6ca
- levelChunk.incrementInhabitedTime(timeInhabited);
- if (!filteredSpawningCategories.isEmpty() && this.level.getWorldBorder().isWithinBounds(pos) && lastSpawnState != null && (!org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled || _pufferfish_spawnCountsReady.get()) && this.chunkMap.anyPlayerCloseEnoughForSpawning(pos, true)) { // Spigot // Pufferfish // Leaf - Don't spawn if lastSpawnState is null
- NaturalSpawner.spawnForChunk(this.level, levelChunk, lastSpawnState, filteredSpawningCategories); // Pufferfish
+ // Leaf start
+ // Leaf start - optimize mob spawning
+ var lastSpawnState1 = this.lastSpawnState;
+ if (lastSpawnState1 != null && (!org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled || _pufferfish_spawnCountsReady.get())) {
+ long sumTimeInhabited = timeInhabited + delayTimeInhabited;
@@ -56,27 +56,27 @@ index f57f8e610dac80b8095bfc0c7e4b22ff5ad6b13c..55f20122732e88037d24be311469b6ca
+ delayTimeInhabited += timeInhabited;
+ delaySpawn = level.getGameTime();
+ }
+ // Leaf end
+ // Leaf end - optimize mob spawning
+ for (LevelChunk levelChunk : chunks) { // Leaf - split to 2 loop
+ for (LevelChunk levelChunk : chunks) { // Leaf - optimize mob spawning - split to 2 loop
if (true) { // Paper - rewrite chunk system
this.level.tickChunk(levelChunk, _int);
}
diff --git a/net/minecraft/world/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java
index 9b37b763c6555705f3e256010f508b5a0c2cdb66..7bfc636fb442036f742903c4e69a8a9fcd0e6fc2 100644
index 9b37b763c6555705f3e256010f508b5a0c2cdb66..bde7008e14a3b4c0a37a94a4890e2f7fa1ce2466 100644
--- a/net/minecraft/world/level/NaturalSpawner.java
+++ b/net/minecraft/world/level/NaturalSpawner.java
@@ -155,7 +155,13 @@ public final class NaturalSpawner {
return list;
}
+ @Deprecated(forRemoval = true) // Leaf
+ @Deprecated(forRemoval = true) // Leaf - optimize mob spawning
public static void spawnForChunk(ServerLevel level, LevelChunk chunk, NaturalSpawner.SpawnState spawnState, List<MobCategory> categories) {
+ // Leaf start
+ // Leaf start - optimize mob spawning
+ spawnForChunk(level, chunk, spawnState, categories, level.getGameTime());
+ }
+ public static void spawnForChunk(ServerLevel level, LevelChunk chunk, NaturalSpawner.SpawnState spawnState, List<MobCategory> categories, long gameTime) {
+ // Leaf end
+ // Leaf end - optimize mob spawning
for (MobCategory mobCategory : categories) {
// Paper start - Optional per player mob spawns
final boolean canSpawn;
@@ -85,7 +85,7 @@ index 9b37b763c6555705f3e256010f508b5a0c2cdb66..7bfc636fb442036f742903c4e69a8a9f
// Paper end - throttle failed spawn attempts
if (CraftSpawnCategory.isValidForLimits(spawnCategory)) {
- spawnThisTick = ticksPerSpawnTmp != 0 && level.getGameTime() % ticksPerSpawn == 0; // Paper - throttle failed spawn attempts
+ spawnThisTick = ticksPerSpawnTmp != 0 && gameTime % ticksPerSpawn == 0; // Paper - throttle failed spawn attempts // Leaf
+ spawnThisTick = ticksPerSpawnTmp != 0 && gameTime % ticksPerSpawn == 0; // Paper - throttle failed spawn attempts // Leaf - optimize mob spawning
limit = level.getWorld().getSpawnLimit(spawnCategory);
}
@@ -96,7 +96,7 @@ index 9b37b763c6555705f3e256010f508b5a0c2cdb66..7bfc636fb442036f742903c4e69a8a9f
- BlockPos randomPosWithin = getRandomPosWithin(level, chunk);
- if (randomPosWithin.getY() >= level.getMinY() + 1) {
- return spawnCategoryForPosition(category, level, chunk, randomPosWithin, filter, callback, maxSpawns, trackEntity, false); // Paper - Optional per player mob spawns // Paper - throttle failed spawn attempts
+ // Leaf start
+ // Leaf start - optimize mob spawning
+ BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos();
+ mutableRandomPosWithin(pos, level, chunk);
+ if (pos.getY() < level.getMinY() + 1) {
@@ -105,7 +105,7 @@ index 9b37b763c6555705f3e256010f508b5a0c2cdb66..7bfc636fb442036f742903c4e69a8a9f
-
- return 0; // Paper - throttle failed spawn attempts
+ return spawnCategoryForPosition(category, level, chunk, pos, filter, callback, maxSpawns, trackEntity, false); // Paper - Optional per player mob spawns // Paper - throttle failed spawn attempts
+ // Leaf end
+ // Leaf end - optimize mob spawning
}
@VisibleForDebug
@@ -113,16 +113,16 @@ index 9b37b763c6555705f3e256010f508b5a0c2cdb66..7bfc636fb442036f742903c4e69a8a9f
StructureManager structureManager = level.structureManager();
ChunkGenerator generator = level.getChunkSource().getGenerator();
int y = pos.getY();
+ int posX = pos.getX(); // Leaf
+ int posZ = pos.getZ(); // Leaf
+ int posX = pos.getX(); // Leaf - optimize mob spawning
+ int posZ = pos.getZ(); // Leaf - optimize mob spawning
int i = 0; // Paper - throttle failed spawn attempts
BlockState blockState = level.getBlockStateIfLoadedAndInBounds(pos); // Paper - don't load chunks for mob spawn
if (blockState != null && !blockState.isRedstoneConductor(chunk, pos)) { // Paper - don't load chunks for mob spawn
- BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
+ BlockPos.MutableBlockPos mutableBlockPos = pos instanceof BlockPos.MutableBlockPos pos2 ? pos2 : new BlockPos.MutableBlockPos(); // Leaf
+ BlockPos.MutableBlockPos mutableBlockPos = pos instanceof BlockPos.MutableBlockPos pos2 ? pos2 : new BlockPos.MutableBlockPos(); // Leaf - optimize mob spawning
//int i = 0; // Paper - throttle failed spawn attempts - move up
+ // Leaf start
+ // Leaf start - optimize mob spawning
+ long rand = level.random.nextLong();
+ int bits = 0;
for (int i1 = 0; i1 < 3; i1++) {
@@ -161,7 +161,7 @@ index 9b37b763c6555705f3e256010f508b5a0c2cdb66..7bfc636fb442036f742903c4e69a8a9f
+ }
+ x += rand1 - rand2;
+ z += rand3 - rand4;
+ // Leaf end
+ // Leaf end - optimize mob spawning
mutableBlockPos.set(x, y, z);
double d = x + 0.5;
double d1 = z + 0.5;
@@ -169,7 +169,7 @@ index 9b37b763c6555705f3e256010f508b5a0c2cdb66..7bfc636fb442036f742903c4e69a8a9f
if (nearestPlayer != null) {
double d2 = nearestPlayer.distanceToSqr(d, y, d1);
- if (level.isLoadedAndInBounds(mutableBlockPos) && isRightDistanceToPlayerAndSpawnPoint(level, chunk, mutableBlockPos, d2)) { // Paper - don't load chunks for mob spawn
+ if (level.getWorldBorder().isWithinBounds(mutableBlockPos) && (chunk.getPos().longKey == ChunkPos.asLong(mutableBlockPos) || level.getChunkIfLoadedImmediately(mutableBlockPos.getX() >> 4, mutableBlockPos.getZ() >> 4) != null) && isRightDistanceToPlayerAndSpawnPoint(level, chunk, mutableBlockPos, d2)) { // Paper - don't load chunks for mob spawn // Leaf
+ if (level.getWorldBorder().isWithinBounds(mutableBlockPos) && (chunk.getPos().longKey == ChunkPos.asLong(mutableBlockPos) || level.getChunkIfLoadedImmediately(mutableBlockPos.getX() >> 4, mutableBlockPos.getZ() >> 4) != null) && isRightDistanceToPlayerAndSpawnPoint(level, chunk, mutableBlockPos, d2)) { // Paper - don't load chunks for mob spawn // Leaf - optimize mob spawning
if (spawnerData == null) {
Optional<MobSpawnSettings.SpawnerData> randomSpawnMobAt = getRandomSpawnMobAt(
level, structureManager, generator, category, level.random, mutableBlockPos
@@ -179,8 +179,8 @@ index 9b37b763c6555705f3e256010f508b5a0c2cdb66..7bfc636fb442036f742903c4e69a8a9f
return !(distance <= 576.0)
- && !level.getSharedSpawnPos().closerToCenterThan(new Vec3(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5), 24.0)
- && (Objects.equals(new ChunkPos(pos), chunk.getPos()) || level.isNaturalSpawningAllowed(pos));
+ && !(level.getSharedSpawnPos().distToCenterSqr(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5) < 576.0) // Leaf
+ && (ChunkPos.asLong(pos) == chunk.getPos().longKey || level.isNaturalSpawningAllowed(pos)); // Leaf
+ && !(level.getSharedSpawnPos().distToCenterSqr(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5) < 576.0) // Leaf - optimize mob spawning
+ && (ChunkPos.asLong(pos) == chunk.getPos().longKey || level.isNaturalSpawningAllowed(pos)); // Leaf - optimize mob spawning
}
// Paper start - PreCreatureSpawnEvent
@@ -188,16 +188,16 @@ index 9b37b763c6555705f3e256010f508b5a0c2cdb66..7bfc636fb442036f742903c4e69a8a9f
}
}
+ // Leaf start
+ // Leaf start - optimize mob spawning
+ private static void mutableRandomPosWithin(BlockPos.MutableBlockPos pos1, Level level, LevelChunk chunk) {
+ ChunkPos pos = chunk.getPos();
+ int i = pos.getMinBlockX() + level.random.nextInt(16);
+ int i1 = pos.getMinBlockZ() + level.random.nextInt(16);
+ int i2 = chunk.getHeight(Heightmap.Types.WORLD_SURFACE, i, i1) + 1;
+ int i3 = Mth.randomBetweenInclusive(level.random, level.getMinY(), i2);
+ pos1.set(i, i3, i1);
+ int randomX = pos.getMinBlockX() + level.random.nextInt(16);
+ int randomZ = pos.getMinBlockZ() + level.random.nextInt(16);
+ int surfaceY = chunk.getHeight(Heightmap.Types.WORLD_SURFACE, randomX, randomZ) + 1;
+ int randomY = Mth.randomBetweenInclusive(level.random, level.getMinY(), surfaceY);
+ pos1.set(randomX, randomY, randomZ);
+ }
+ // Leaf end
+ // Leaf end - optimize mob spawning
+
private static BlockPos getRandomPosWithin(Level level, LevelChunk chunk) {
ChunkPos pos = chunk.getPos();

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] optimize structure map
diff --git a/net/minecraft/world/level/chunk/ChunkAccess.java b/net/minecraft/world/level/chunk/ChunkAccess.java
index 50a9903367f49ece2a267d10944b1515c7b93859..ceabb277bef2633de8f55e16431dbb4d0869817b 100644
index 50a9903367f49ece2a267d10944b1515c7b93859..5117671a4391690c90e7577a2518d0298e4b8c74 100644
--- a/net/minecraft/world/level/chunk/ChunkAccess.java
+++ b/net/minecraft/world/level/chunk/ChunkAccess.java
@@ -76,8 +76,8 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
@@ -14,8 +14,8 @@ index 50a9903367f49ece2a267d10944b1515c7b93859..ceabb277bef2633de8f55e16431dbb4d
// Paper - rewrite chunk system
- private final Map<Structure, StructureStart> structureStarts = Maps.newHashMap();
- private final Map<Structure, LongSet> structuresRefences = Maps.newHashMap();
+ private final Map<Structure, StructureStart> structureStarts = new it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap<>(); // Leaf
+ private final Map<Structure, LongSet> structuresRefences = new it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap<>(); // Leaf
+ private final Map<Structure, StructureStart> structureStarts = new it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap<>(); // Leaf - optimize structure map
+ private final Map<Structure, LongSet> structuresRefences = new it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap<>(); // Leaf - optimize structure map
protected final Map<BlockPos, CompoundTag> pendingBlockEntities = Maps.newHashMap();
public final Map<BlockPos, BlockEntity> blockEntities = new Object2ObjectOpenHashMap<>();
protected final LevelHeightAccessor levelHeightAccessor;
@@ -24,7 +24,7 @@ index 50a9903367f49ece2a267d10944b1515c7b93859..ceabb277bef2633de8f55e16431dbb4d
public Map<Structure, StructureStart> getAllStarts() {
- return Collections.unmodifiableMap(this.structureStarts);
+ return this.structureStarts; // Leaf
+ return this.structureStarts; // Leaf - optimize structure map
}
public void setAllStarts(Map<Structure, StructureStart> structureStarts) {
@@ -33,14 +33,14 @@ index 50a9903367f49ece2a267d10944b1515c7b93859..ceabb277bef2633de8f55e16431dbb4d
@Override
public void addReferenceForStructure(Structure structure, long reference) {
- this.structuresRefences.computeIfAbsent(structure, key -> new LongOpenHashSet()).add(reference);
+ this.structuresRefences.computeIfAbsent(structure, key -> new it.unimi.dsi.fastutil.longs.LongArraySet()).add(reference); // Leaf
+ this.structuresRefences.computeIfAbsent(structure, key -> new it.unimi.dsi.fastutil.longs.LongArraySet()).add(reference); // Leaf - optimize structure map
this.markUnsaved();
}
@Override
public Map<Structure, LongSet> getAllReferences() {
- return Collections.unmodifiableMap(this.structuresRefences);
+ return this.structuresRefences; // Leaf
+ return this.structuresRefences; // Leaf - optimize structure map
}
@Override

View File

@@ -5,14 +5,14 @@ Subject: [PATCH] throttle mob spawning
diff --git a/net/minecraft/world/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java
index 7bfc636fb442036f742903c4e69a8a9fcd0e6fc2..762bdf1fe19546f89d34b9efdad66b00dab80006 100644
index bde7008e14a3b4c0a37a94a4890e2f7fa1ce2466..458b17dca84c87591b030679c5aac6259c0f8308 100644
--- a/net/minecraft/world/level/NaturalSpawner.java
+++ b/net/minecraft/world/level/NaturalSpawner.java
@@ -166,6 +166,17 @@ public final class NaturalSpawner {
// Paper start - Optional per player mob spawns
final boolean canSpawn;
int maxSpawns = Integer.MAX_VALUE;
+ // Leaf start
+ // Leaf start - throttle mob spawning
+ if (org.dreeam.leaf.config.modules.opt.ThrottleNaturalMobSpawning.enabled) {
+ int spawnChance = org.dreeam.leaf.config.modules.opt.ThrottleNaturalMobSpawning.spawnChance[mobCategory.ordinal()];
+ long failedAttempt = org.dreeam.leaf.config.modules.opt.ThrottleNaturalMobSpawning.failedAttempts[mobCategory.ordinal()];
@@ -22,7 +22,7 @@ index 7bfc636fb442036f742903c4e69a8a9fcd0e6fc2..762bdf1fe19546f89d34b9efdad66b00
+ continue;
+ }
+ }
+ // Leaf end
+ // Leaf end - throttle mob spawning
if (level.paperConfig().entities.spawning.perPlayerMobSpawns) {
// Copied from getFilteredSpawningCategories
int limit = mobCategory.getMaxInstancesPerChunk();

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Add BlockExplosionHitEvent
diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java
index 6030c4eefd77969a1a9251de76d4291dcb0a2092..ea9c641fe9a9685307b6de2999ea4ff5342269b7 100644
index 6030c4eefd77969a1a9251de76d4291dcb0a2092..f76ec9520f6a2ee42ed3ba65068c01f4b9bc8746 100644
--- a/net/minecraft/world/level/ServerExplosion.java
+++ b/net/minecraft/world/level/ServerExplosion.java
@@ -623,9 +623,13 @@ public class ServerExplosion implements Explosion {
@@ -15,13 +15,13 @@ index 6030c4eefd77969a1a9251de76d4291dcb0a2092..ea9c641fe9a9685307b6de2999ea4ff5
- this.level
- .getBlockState(blockPos)
- .onExplosionHit(this.level, blockPos, this, (itemStack, blockPos1) -> addOrAppendStack(list, itemStack, blockPos1));
+ // Leaf start - BlockExplosionHitEvent
+ if(new org.dreeam.leaf.event.BlockExplosionHitEvent(CraftLocation.toBukkit(blockPos, bworld).getBlock(), this.source == null ? null : this.source.getBukkitEntity(), org.bukkit.craftbukkit.CraftExplosionResult.toBukkit(this.blockInteraction)).callEvent()) {
+ // Leaf start - Add BlockExplosionHitEvent
+ if (new org.dreeam.leaf.event.BlockExplosionHitEvent(CraftLocation.toBukkit(blockPos, bworld).getBlock(), this.source == null ? null : this.source.getBukkitEntity(), org.bukkit.craftbukkit.CraftExplosionResult.toBukkit(this.blockInteraction)).callEvent()) {
+ this.level
+ .getBlockState(blockPos)
+ .onExplosionHit(this.level, blockPos, this, (itemStack, blockPos1) -> addOrAppendStack(list, itemStack, blockPos1));
+ }
+ // Leaf end
+ // Leaf end - Add BlockExplosionHitEvent
}
for (ServerExplosion.StackCollector stackCollector : list) {

View File

@@ -17,7 +17,7 @@ index 0a5611b1ece4dbe2887e7fbdef45f58e7f4d53ad..9f6fc274525f2fe4e4e35e0feaa410bf
public static final StringRepresentable.EnumCodec<EquipmentSlot> CODEC = StringRepresentable.fromEnum(EquipmentSlot::values);
public static final StreamCodec<ByteBuf, EquipmentSlot> STREAM_CODEC = ByteBufCodecs.idMapper(BY_ID, equipmentSlot -> equipmentSlot.id);
diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java
index ea9c641fe9a9685307b6de2999ea4ff5342269b7..ae0dab1f8470cf53031a2ba776fa70d8ae074a87 100644
index f76ec9520f6a2ee42ed3ba65068c01f4b9bc8746..18f11006f0f4b3214c311f2db193df11736cd75c 100644
--- a/net/minecraft/world/level/ServerExplosion.java
+++ b/net/minecraft/world/level/ServerExplosion.java
@@ -532,7 +532,7 @@ public class ServerExplosion implements Explosion {

View File

@@ -1,108 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: hayanesuru <hayanesuru@outlook.jp>
Date: Wed, 4 Jun 2025 20:54:32 +0900
Subject: [PATCH] preload mob spawning position
diff --git a/net/minecraft/world/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java
index 762bdf1fe19546f89d34b9efdad66b00dab80006..0443df34de4f940f64e563ea76453493cadf200b 100644
--- a/net/minecraft/world/level/NaturalSpawner.java
+++ b/net/minecraft/world/level/NaturalSpawner.java
@@ -257,9 +257,56 @@ public final class NaturalSpawner {
// Paper end - Optional per player mob spawns
// Leaf start
BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos();
- mutableRandomPosWithin(pos, level, chunk);
- if (pos.getY() < level.getMinY() + 1) {
- return 0;
+ // Leaf start
+ if (org.dreeam.leaf.config.modules.opt.PreloadNaturalMobSpawning.enabled) {
+ if (chunk.cacheSpawnPosIndex == 16 || chunk.cacheSpawnPosIndex == -1) {
+ if (chunk.cacheSpawnPos == null) {
+ chunk.cacheSpawnPos = new long[16];
+ }
+ // cache friendly
+ for (int i = 0; i < 16; i++) {
+ mutableRandomPosWithin(pos, level, chunk);
+ if (pos.getY() >= level.getMinY() + 1
+ && level.getWorldBorder().isWithinBounds(pos)
+ && !level.isOutsideBuildHeight(pos)) {
+ LevelChunk chunk1 = chunk.getPos().longKey == ChunkPos.asLong(pos)
+ ? chunk
+ : level.chunkSource.getChunkAtIfLoadedImmediately(pos.getX() >> 4, pos.getZ() >> 4);
+ if (chunk1 != null) {
+ BlockState bs = chunk1.getBlockStateFinal(pos.getX(), pos.getY(), pos.getZ());
+ if (bs != null && !bs.isRedstoneConductor(level, pos)) {
+ chunk.cacheSpawnPos[i] = BlockPos.asLong(pos.getX(), pos.getY(), pos.getZ());
+ continue;
+ }
+ }
+ }
+ chunk.cacheSpawnPos[i] = -1;
+ }
+ chunk.cacheSpawnPosIndex = 0;
+ }
+ long cachePos = chunk.cacheSpawnPos[chunk.cacheSpawnPosIndex];
+ chunk.cacheSpawnPosIndex++;
+ if (cachePos == -1) {
+ return 0;
+ }
+ pos.set(cachePos);
+ } else {
+ mutableRandomPosWithin(pos, level, chunk);
+ if (pos.getY() < level.getMinY() + 1
+ || !level.getWorldBorder().isWithinBounds(pos)
+ || level.isOutsideBuildHeight(pos)) {
+ return 0;
+ }
+ LevelChunk chunk1 = chunk.getPos().longKey == ChunkPos.asLong(pos)
+ ? chunk
+ : level.chunkSource.getChunkAtIfLoadedImmediately(pos.getX() >> 4, pos.getZ() >> 4);
+ if (chunk1 == null) {
+ return 0;
+ }
+ BlockState bs = chunk1.getBlockStateFinal(pos.getX(), pos.getY(), pos.getZ());
+ if (bs == null || bs.isRedstoneConductor(level, pos)) {
+ return 0;
+ }
}
return spawnCategoryForPosition(category, level, chunk, pos, filter, callback, maxSpawns, trackEntity, false); // Paper - Optional per player mob spawns // Paper - throttle failed spawn attempts
// Leaf end
@@ -284,7 +331,12 @@ public final class NaturalSpawner {
MobCategory category, ServerLevel level, ChunkAccess chunk, BlockPos pos, NaturalSpawner.SpawnPredicate filter, NaturalSpawner.AfterSpawnCallback callback, final int maxSpawns, final @Nullable Consumer<Entity> trackEntity
// Paper start - throttle failed spawn attempts
) {
- spawnCategoryForPosition(category, level, chunk, pos, filter, callback, maxSpawns, trackEntity, false);
+ // Leaf start
+ BlockState blockState = level.getBlockStateIfLoadedAndInBounds(pos);
+ if (blockState != null && !blockState.isRedstoneConductor(chunk, pos)) {
+ spawnCategoryForPosition(category, level, chunk, pos, filter, callback, maxSpawns, trackEntity, false);
+ }
+ // Leaf end
}
public static int spawnCategoryForPosition(
MobCategory category, ServerLevel level, ChunkAccess chunk, BlockPos pos, NaturalSpawner.SpawnPredicate filter, NaturalSpawner.AfterSpawnCallback callback, final int maxSpawns, final @Nullable Consumer<Entity> trackEntity, final boolean nothing
@@ -297,8 +349,8 @@ public final class NaturalSpawner {
int posX = pos.getX(); // Leaf
int posZ = pos.getZ(); // Leaf
int i = 0; // Paper - throttle failed spawn attempts
- BlockState blockState = level.getBlockStateIfLoadedAndInBounds(pos); // Paper - don't load chunks for mob spawn
- if (blockState != null && !blockState.isRedstoneConductor(chunk, pos)) { // Paper - don't load chunks for mob spawn
+ // BlockState blockState = level.getBlockStateIfLoadedAndInBounds(pos); // Paper - don't load chunks for mob spawn // Leaf
+ if (true /*blockState != null && !blockState.isRedstoneConductor(chunk, pos)*/) { // Paper - don't load chunks for mob spawn // Leaf
BlockPos.MutableBlockPos mutableBlockPos = pos instanceof BlockPos.MutableBlockPos pos2 ? pos2 : new BlockPos.MutableBlockPos(); // Leaf
//int i = 0; // Paper - throttle failed spawn attempts - move up
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
index e6eab6929b08503c49debbbd25497ffedad438e1..624a177695580510c0a49d4503dee72da7fd7114 100644
--- a/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
@@ -106,6 +106,8 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
// Paper start - rewrite chunk system
private boolean postProcessingDone;
private net.minecraft.server.level.ServerChunkCache.ChunkAndHolder chunkAndHolder;
+ public long[] cacheSpawnPos = null; // Leaf
+ public int cacheSpawnPosIndex = -1; // Leaf
@Override
public final boolean moonrise$isPostProcessingDone() {

View File

@@ -100,7 +100,7 @@ index 4535858701b2bb232b9d2feb2af6551526232ddc..e65c62dbe4c1560ae153e4c4344e9194
- // Paper end - detailed watchdog information
}
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
index 55f20122732e88037d24be311469b6cab72c37ad..2f927b422c2c4f2f65d822befe3cbfd9e3bb3708 100644
index c1efd558cfbfd2200295ef5755aa496e95deb7d7..15bbd1f7f2a90b4b5427026d622764bb1c92d465 100644
--- a/net/minecraft/server/level/ServerChunkCache.java
+++ b/net/minecraft/server/level/ServerChunkCache.java
@@ -506,9 +506,10 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
@@ -149,10 +149,10 @@ index 7955a8fa9c4de139b24c9d53018b055ff4008e02..eb849c57992658005e0f514c6f7923f8
private void tickPassenger(Entity ridingEntity, Entity passengerEntity, final boolean isActive) { // Paper - EAR 2
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 80baa2dff5c1034a72271fc727fdb2acc1b69488..9f581d5bdc3f658694bbd8c80abbce4e27e568d3 100644
index 64f24d3e0ecb91e0b4df6229354aeac549234f1b..df23d80d6b18e900414aa02e5c1812f0a10f0fb7 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -1147,31 +1147,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -1145,31 +1145,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return this.onGround;
}
@@ -184,7 +184,7 @@ index 80baa2dff5c1034a72271fc727fdb2acc1b69488..9f581d5bdc3f658694bbd8c80abbce4e
public void move(MoverType type, Vec3 movement) {
// Gale start - VMP - skip entity move if movement is zero
if (!this.boundingBoxChanged && movement.equals(Vec3.ZERO)) {
@@ -1179,16 +1154,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -1177,16 +1152,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
// Gale end - VMP - skip entity move if movement is zero
final Vec3 originalMovement = movement; // Paper - Expose pre-collision velocity
@@ -201,7 +201,7 @@ index 80baa2dff5c1034a72271fc727fdb2acc1b69488..9f581d5bdc3f658694bbd8c80abbce4e
if (this.noPhysics) {
this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z);
} else {
@@ -1309,13 +1275,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -1307,13 +1273,6 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
// Gale end - skip negligible planar movement multiplication
}
}
@@ -215,7 +215,7 @@ index 80baa2dff5c1034a72271fc727fdb2acc1b69488..9f581d5bdc3f658694bbd8c80abbce4e
}
private void applyMovementEmissionAndPlaySound(Entity.MovementEmission movementEmission, Vec3 movement, BlockPos pos, BlockState state) {
@@ -4881,9 +4840,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -4879,9 +4838,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
public void setDeltaMovement(Vec3 deltaMovement) {
@@ -225,7 +225,7 @@ index 80baa2dff5c1034a72271fc727fdb2acc1b69488..9f581d5bdc3f658694bbd8c80abbce4e
}
public void addDeltaMovement(Vec3 addend) {
@@ -4989,9 +4946,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -4987,9 +4944,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
// Paper end - Fix MC-4
if (this.position.x != x || this.position.y != y || this.position.z != z) {

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Use UUID for cure reputation
diff --git a/net/minecraft/world/entity/monster/ZombieVillager.java b/net/minecraft/world/entity/monster/ZombieVillager.java
index d4b6c93f9f0e109be300164c4fd9167aba2d951c..301228895f0347ec514cefc8a11d8ca7bc2f2225 100644
index d4b6c93f9f0e109be300164c4fd9167aba2d951c..138e62965a4e532972e51c16b429e050bb147788 100644
--- a/net/minecraft/world/entity/monster/ZombieVillager.java
+++ b/net/minecraft/world/entity/monster/ZombieVillager.java
@@ -310,9 +310,10 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder {
@@ -16,7 +16,7 @@ index d4b6c93f9f0e109be300164c4fd9167aba2d951c..301228895f0347ec514cefc8a11d8ca7
if (playerByUuid instanceof ServerPlayer) {
CriteriaTriggers.CURED_ZOMBIE_VILLAGER.trigger((ServerPlayer)playerByUuid, this, villager);
- serverLevel.onReputationEvent(ReputationEventType.ZOMBIE_VILLAGER_CURED, playerByUuid, villager);
+ // serverLevel.onReputationEvent(ReputationEventType.ZOMBIE_VILLAGER_CURED, playerByUuid, villager); // Leaf - move up
+ //serverLevel.onReputationEvent(ReputationEventType.ZOMBIE_VILLAGER_CURED, playerByUuid, villager); // Leaf - Use UUID for cure reputation - move up
}
}

View File

@@ -5,14 +5,14 @@ Subject: [PATCH] Cache potential behaviors in Brain
diff --git a/net/minecraft/world/entity/ai/Brain.java b/net/minecraft/world/entity/ai/Brain.java
index 97dad57ba873c0f6404a490e358739dbaf11bc55..34b66ee67927bc0796d6c5f069393618abca9d74 100644
index 4dde1642a33349335f374f17123a700dde1079d7..5e86c8f6dffc7b4dd17acc43ec4c458368bf92a4 100644
--- a/net/minecraft/world/entity/ai/Brain.java
+++ b/net/minecraft/world/entity/ai/Brain.java
@@ -60,6 +60,7 @@ public class Brain<E extends LivingEntity> {
private Activity defaultActivity = Activity.IDLE;
private long lastScheduleUpdate = -9999L;
+ private ObjectArrayList<BehaviorControl<? super E>> cachedPotentialBehaviors;
+ private ObjectArrayList<BehaviorControl<? super E>> cachedPotentialBehaviors; // Leaf - Cache potential behaviors in Brain
public static <E extends LivingEntity> Brain.Provider<E> provider(
Collection<? extends MemoryModuleType<?>> memoryTypes, Collection<? extends SensorType<? extends Sensor<? super E>>> sensorTypes
) {
@@ -20,7 +20,7 @@ index 97dad57ba873c0f6404a490e358739dbaf11bc55..34b66ee67927bc0796d6c5f069393618
for (Brain.MemoryValue<?> memoryValue : memoryValues) {
memoryValue.setMemoryInternal(this);
}
+ this.invalidateBehaviorCache();
+ this.invalidateBehaviorCache(); // Leaf - Cache potential behaviors in Brain
}
public <T> DataResult<T> serializeStart(DynamicOps<T> ops) {
@@ -28,7 +28,7 @@ index 97dad57ba873c0f6404a490e358739dbaf11bc55..34b66ee67927bc0796d6c5f069393618
this.activeActivities.clear();
this.activeActivities.addAll(this.coreActivities);
this.activeActivities.add(activity);
+ this.invalidateBehaviorCache();
+ this.invalidateBehaviorCache(); // Leaf - Cache potential behaviors in Brain
}
}
@@ -36,56 +36,47 @@ index 97dad57ba873c0f6404a490e358739dbaf11bc55..34b66ee67927bc0796d6c5f069393618
.computeIfAbsent(activity, activity1 -> new it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet<>()) // Leaf - Replace brain activity maps with optimized collection
.add((BehaviorControl<? super E>)pair.getSecond());
}
+ this.invalidateBehaviorCache();
+ this.invalidateBehaviorCache(); // Leaf - Cache potential behaviors in Brain
}
@VisibleForTesting
public void removeAllBehaviors() {
this.availableBehaviorsByPriority.clear();
+ this.invalidateBehaviorCache();
+ this.invalidateBehaviorCache(); // Leaf - Cache potential behaviors in Brain
}
public boolean isActive(Activity activity) {
@@ -452,30 +457,40 @@ public class Brain<E extends LivingEntity> {
@@ -452,23 +457,44 @@ public class Brain<E extends LivingEntity> {
}
}
- private void startEachNonRunningBehavior(ServerLevel level, E entity) {
- // Leaf start - Collect then startEachNonRunningBehavior in Brain
- final long gameTime = level.getGameTime();
- List<BehaviorControl<? super E>> behaviorsToStart = new ObjectArrayList<>();
-
- for (Activity activeActivity : this.activeActivities) {
- for (Map<Activity, Set<BehaviorControl<? super E>>> priorityMap : this.availableBehaviorsByPriority.values()) {
- Set<BehaviorControl<? super E>> behaviors = priorityMap.get(activeActivity);
-
- if (behaviors != null && !behaviors.isEmpty()) {
- for (BehaviorControl<? super E> behaviorControl : behaviors) {
- if (behaviorControl.getStatus() == Behavior.Status.STOPPED) {
- behaviorsToStart.add(behaviorControl);
- }
- long gameTime = level.getGameTime();
+ // Leaf start - Cache potential behaviors in Brain
+ private void invalidateBehaviorCache() {
+ this.cachedPotentialBehaviors = null;
+ }
+
+ private void rebuildBehaviorCache() {
+ this.cachedPotentialBehaviors = new ObjectArrayList<>(30);
+
+ for (Map<Activity, Set<BehaviorControl<? super E>>> map : this.availableBehaviorsByPriority.values()) {
for (Map<Activity, Set<BehaviorControl<? super E>>> map : this.availableBehaviorsByPriority.values()) {
- for (Entry<Activity, Set<BehaviorControl<? super E>>> entry : map.entrySet()) {
+ for (Map.Entry<Activity, Set<BehaviorControl<? super E>>> entry : map.entrySet()) {
+ Activity activity = entry.getKey();
+ if (this.activeActivities.contains(activity)) {
Activity activity = entry.getKey();
if (this.activeActivities.contains(activity)) {
- for (BehaviorControl<? super E> behaviorControl : entry.getValue()) {
- if (behaviorControl.getStatus() == Behavior.Status.STOPPED) {
- behaviorControl.tryStart(level, entity, gameTime);
- }
+ for (BehaviorControl<? super E> task : entry.getValue()) {
+ this.cachedPotentialBehaviors.add(task);
}
}
}
}
- if (!behaviorsToStart.isEmpty()) {
- for (BehaviorControl<? super E> behaviorControl : behaviorsToStart) {
- behaviorControl.tryStart(level, entity, gameTime);
+ }
+
}
+ private ObjectArrayList<BehaviorControl<? super E>> getPotentialBehaviors() {
+ if (this.cachedPotentialBehaviors == null) {
+ this.rebuildBehaviorCache();
@@ -99,9 +90,11 @@ index 97dad57ba873c0f6404a490e358739dbaf11bc55..34b66ee67927bc0796d6c5f069393618
+ for (BehaviorControl<? super E> task : this.getPotentialBehaviors()) {
+ if (task.getStatus() == Behavior.Status.STOPPED) {
+ task.tryStart(level, entity, startTime);
}
}
- // Leaf end - Collect then startEachNonRunningBehavior in Brain
}
+ }
+ }
+ }
+ // Leaf end - Cache potential behaviors in Brain
+
private void tickEachRunningBehavior(ServerLevel level, E entity) {
long gameTime = level.getGameTime();

View File

@@ -5,14 +5,14 @@ Subject: [PATCH] Use ActivationList on runningBehaviors
diff --git a/net/minecraft/world/entity/ai/Brain.java b/net/minecraft/world/entity/ai/Brain.java
index 34b66ee67927bc0796d6c5f069393618abca9d74..f7dd07feea8884c686e78becb1f9cbd0d2769915 100644
index 5e86c8f6dffc7b4dd17acc43ec4c458368bf92a4..948731703d25eb3f86a83d45b7fd6ce4b4d3c4e8 100644
--- a/net/minecraft/world/entity/ai/Brain.java
+++ b/net/minecraft/world/entity/ai/Brain.java
@@ -61,6 +61,7 @@ public class Brain<E extends LivingEntity> {
private long lastScheduleUpdate = -9999L;
private ObjectArrayList<BehaviorControl<? super E>> cachedPotentialBehaviors;
+ private org.dreeam.leaf.util.list.ActivationList<BehaviorControl<? super E>> runningBehaviors;
private ObjectArrayList<BehaviorControl<? super E>> cachedPotentialBehaviors; // Leaf - Cache potential behaviors in Brain
+ private org.dreeam.leaf.util.list.ActivationList<BehaviorControl<? super E>> runningBehaviors; // Leaf - Use ActivationList on runningBehaviors
public static <E extends LivingEntity> Brain.Provider<E> provider(
Collection<? extends MemoryModuleType<?>> memoryTypes, Collection<? extends SensorType<? extends Sensor<? super E>>> sensorTypes
) {
@@ -33,29 +33,31 @@ index 34b66ee67927bc0796d6c5f069393618abca9d74..f7dd07feea8884c686e78becb1f9cbd0
- }
-
- return list;
+ return this.getRunningBehaviorsList();
+ return this.getRunningBehaviorsList(); // Leaf - Use ActivationList on runningBehaviors
}
public void useDefaultActivity() {
@@ -453,12 +442,14 @@ public class Brain<E extends LivingEntity> {
@@ -453,6 +442,7 @@ public class Brain<E extends LivingEntity> {
long gameTime = owner.level().getGameTime();
for (BehaviorControl<? super E> behaviorControl : this.getRunningBehaviors()) {
+ this.getRunningBehaviorsList().setVisibility(behaviorControl, false);
+ this.getRunningBehaviorsList().setVisibility(behaviorControl, false); // Leaf - Use ActivationList on runningBehaviors
behaviorControl.doStop(level, owner, gameTime);
}
}
@@ -460,6 +450,7 @@ public class Brain<E extends LivingEntity> {
// Leaf start - Cache potential behaviors in Brain
private void invalidateBehaviorCache() {
this.cachedPotentialBehaviors = null;
+ this.runningBehaviors = null;
+ this.runningBehaviors = null; // Leaf - Use ActivationList on runningBehaviors
}
private void rebuildBehaviorCache() {
@@ -476,6 +467,25 @@ public class Brain<E extends LivingEntity> {
@@ -477,6 +468,27 @@ public class Brain<E extends LivingEntity> {
}
}
+ // Leaf start - Use ActivationList on runningBehaviors
+ private void initializeRunningBehaviors() {
+ this.runningBehaviors = new org.dreeam.leaf.util.list.ActivationList<>(false);
+
@@ -74,11 +76,12 @@ index 34b66ee67927bc0796d6c5f069393618abca9d74..f7dd07feea8884c686e78becb1f9cbd0
+ }
+ return this.runningBehaviors;
+ }
+ // Leaf end - Use ActivationList on runningBehaviors
+
private ObjectArrayList<BehaviorControl<? super E>> getPotentialBehaviors() {
if (this.cachedPotentialBehaviors == null) {
this.rebuildBehaviorCache();
@@ -489,6 +499,9 @@ public class Brain<E extends LivingEntity> {
@@ -490,6 +502,9 @@ public class Brain<E extends LivingEntity> {
for (BehaviorControl<? super E> task : this.getPotentialBehaviors()) {
if (task.getStatus() == Behavior.Status.STOPPED) {
task.tryStart(level, entity, startTime);
@@ -88,13 +91,15 @@ index 34b66ee67927bc0796d6c5f069393618abca9d74..f7dd07feea8884c686e78becb1f9cbd0
}
}
}
@@ -498,6 +511,9 @@ public class Brain<E extends LivingEntity> {
@@ -500,6 +515,11 @@ public class Brain<E extends LivingEntity> {
for (BehaviorControl<? super E> behaviorControl : this.getRunningBehaviors()) {
behaviorControl.tickOrStop(level, entity, gameTime);
+ // Leaf start - Use ActivationList on runningBehaviors
+ if (behaviorControl.getStatus() != Behavior.Status.RUNNING) {
+ this.getRunningBehaviorsList().setVisibility(behaviorControl, false);
+ }
+ // Leaf end - Use ActivationList on runningBehaviors
}
}

View File

@@ -1,11 +1,19 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Taiyou06 <kaandindar21@gmail.com>
Date: Mon, 9 Jun 2025 12:00:57 +0200
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Mon, 9 Jun 2025 02:46:34 -0700
Subject: [PATCH] Paper: Fix infinite loop in RegionFile IO
Original license: GPLv3
Original project: https://github.com/PaperMC/Paper
https://github.com/PaperMC/Paper/commit/519e4224b1ba73a99c58c8fc53aab003eb6af37a
If an exception is thrown during decompress then the read process
would be started again, which of course would eventually throw in
the decompress process.
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java b/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java
index 60ed8cff397c964323fbda203ebfab3c7c9a873b..32ee1d3a0ae67738a65545e6a0046a12fb940fa4 100644
index 60ed8cff397c964323fbda203ebfab3c7c9a873b..88207a3afd0260f572c7f54003d566c2c1cb1633 100644
--- a/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java
@@ -1143,7 +1143,7 @@ public final class MoonriseRegionFileIO {
@@ -13,7 +21,7 @@ index 60ed8cff397c964323fbda203ebfab3c7c9a873b..32ee1d3a0ae67738a65545e6a0046a12
}
- if (compoundTag == null) {
+ if (throwable == null && compoundTag == null) {
+ if (throwable == null && compoundTag == null) { // Paper - Fix infinite loop in RegionFile IO
// need to re-try from the start
this.scheduleReadIO();
return;

View File

@@ -0,0 +1,20 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Taiyou06 <kaandindar21@gmail.com>
Date: Wed, 11 Jun 2025 20:51:36 +0200
Subject: [PATCH] Paper: Fix excess slot updates / inventory state id desync
Original Patch: https://github.com/PaperMC/Paper/pull/12654
diff --git a/net/minecraft/world/inventory/AbstractContainerMenu.java b/net/minecraft/world/inventory/AbstractContainerMenu.java
index ff2ff95ec9d94e2e31e8174196b384c37d56f38a..2a49a0bdeb61c4fadddc241c8ebca908959d7e9c 100644
--- a/net/minecraft/world/inventory/AbstractContainerMenu.java
+++ b/net/minecraft/world/inventory/AbstractContainerMenu.java
@@ -553,7 +553,7 @@ public abstract class AbstractContainerMenu {
slot.setChanged();
// CraftBukkit start - Make sure the client has the right slot contents
- if (player instanceof ServerPlayer serverPlayer && slot.getMaxStackSize() != 64) {
+ if (player instanceof ServerPlayer serverPlayer && slot.getMaxStackSize() != net.minecraft.world.Container.MAX_STACK) {
serverPlayer.connection.send(new ClientboundContainerSetSlotPacket(this.containerId, this.incrementStateId(), slot.index, slot.getItem()));
// Updating a crafting inventory makes the client reset the result slot, have to send it again
if (this.getBukkitView().getType() == org.bukkit.event.inventory.InventoryType.WORKBENCH || this.getBukkitView().getType() == org.bukkit.event.inventory.InventoryType.CRAFTING) {

View File

@@ -5,24 +5,14 @@ Subject: [PATCH] dump pwt thread
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
index e45d5da04428c26fc6aa97fba974bde3573d7950..745a9afcdb8ea3047c1fcdc91971ba8f034cbd39 100644
index e45d5da04428c26fc6aa97fba974bde3573d7950..16e5ab49bc96f64143eb9e0dff19b33a7e3b5f3a 100644
--- a/src/main/java/org/spigotmc/WatchdogThread.java
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
@@ -8,6 +8,7 @@ import java.lang.management.ThreadInfo;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.level.ServerLevel;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.CraftServer;
@@ -124,8 +125,21 @@ public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThre
logger.log(Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Leaf!):"); // Paper // Gale - branding changes // Leaf - Rebrand
FeatureHooks.dumpAllChunkLoadInfo(MinecraftServer.getServer(), isLongTimeout); // Paper - log detailed tick information
@@ -126,6 +126,21 @@ public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThre
WatchdogThread.dumpThread(ManagementFactory.getThreadMXBean().getThreadInfo(MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE), logger);
+ // Leaf start
logger.log(Level.SEVERE, "------------------------------");
-
+ // Leaf start - dump pwt thread
+ logger.log(Level.SEVERE, "Parallel world ticking thread dump");
+ for (Thread thread : org.apache.commons.lang3.ThreadUtils.getAllThreads()) {
+ if (MinecraftServer.getServer().serverThread == thread || thread instanceof WatchdogThread) {
@@ -30,12 +20,13 @@ index e45d5da04428c26fc6aa97fba974bde3573d7950..745a9afcdb8ea3047c1fcdc91971ba8f
+ }
+ if (thread instanceof ca.spottedleaf.moonrise.common.util.TickThread tickThread) {
+ if (tickThread instanceof ServerLevelTickThread tickThread1) {
+ WatchdogThread.dumpThread(ManagementFactory.getThreadMXBean().getThreadInfo(tickThread1.getId(), Integer.MAX_VALUE), logger);
+ WatchdogThread.dumpThread(ManagementFactory.getThreadMXBean().getThreadInfo(tickThread1.threadId(), Integer.MAX_VALUE), logger);
+ }
+ }
+ }
+ logger.log(Level.SEVERE, "------------------------------");
+ // Leaf end
+ // Leaf end - dump pwt thread
+
// Paper start - Only print full dump on long timeouts
if (isLongTimeout) {
logger.log(Level.SEVERE, "Entire Thread Dump:");

View File

@@ -13,7 +13,7 @@ public class AsyncExecutor implements Runnable {
private final Logger LOGGER = LogManager.getLogger("Leaf");
private final PriorityQueue<Runnable> jobs = PriorityQueues.synchronize(new ObjectArrayFIFOQueue<>());
private final Thread thread;
public final Thread thread;
private volatile boolean killswitch = false;
public AsyncExecutor(String threadName) {
@@ -28,10 +28,10 @@ public class AsyncExecutor implements Runnable {
thread.start();
}
public void kill() throws InterruptedException {
public void join(long millis) throws InterruptedException {
killswitch = true;
LockSupport.unpark(thread);
thread.join();
thread.join(millis);
}
public void submit(Runnable runnable) {

View File

@@ -12,20 +12,30 @@ import java.util.concurrent.TimeUnit;
public class AsyncPlayerDataSaving {
public static final ExecutorService IO_POOL = new ThreadPoolExecutor(
1, 1, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(),
new com.google.common.util.concurrent.ThreadFactoryBuilder()
.setPriority(Thread.NORM_PRIORITY - 2)
.setNameFormat("Leaf IO Thread")
.setUncaughtExceptionHandler(Util::onThreadException)
.build(),
new ThreadPoolExecutor.DiscardPolicy()
);
public static ExecutorService IO_POOL = null;
private AsyncPlayerDataSaving() {
}
public static void init() {
if (IO_POOL == null) {
IO_POOL = new ThreadPoolExecutor(
1,
1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(),
new com.google.common.util.concurrent.ThreadFactoryBuilder()
.setPriority(Thread.NORM_PRIORITY - 2)
.setNameFormat("Leaf IO Thread")
.setUncaughtExceptionHandler(Util::onThreadException)
.build(),
new ThreadPoolExecutor.DiscardPolicy()
);
} else {
throw new IllegalStateException();
}
}
public static Optional<Future<?>> submit(Runnable runnable) {
if (!AsyncPlayerDataSave.enabled) {
runnable.run();

Some files were not shown because too many files have changed in this diff Show More