diff --git a/leaf-server/minecraft-patches/features/0164-Paper-PR-Skip-AI-during-inactive-ticks-for-non-aware.patch b/leaf-server/minecraft-patches/features/0164-Paper-PR-Skip-AI-during-inactive-ticks-for-non-aware.patch index 77c6d147..57387abc 100644 --- a/leaf-server/minecraft-patches/features/0164-Paper-PR-Skip-AI-during-inactive-ticks-for-non-aware.patch +++ b/leaf-server/minecraft-patches/features/0164-Paper-PR-Skip-AI-during-inactive-ticks-for-non-aware.patch @@ -8,23 +8,23 @@ Original project: https://github.com/PaperMC/Paper Paper pull request: https://github.com/PaperMC/Paper/pull/10990 diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java -index ec50760ec81728a0b8ab8d691ed65ba6d25d32f9..6e0981844823be11775c82e22c6845d8fc6b44e2 100644 +index ec50760ec81728a0b8ab8d691ed65ba6d25d32f9..b22960f06f92ef4d9d12ab5b3891363534567a29 100644 --- a/net/minecraft/world/entity/Mob.java +++ b/net/minecraft/world/entity/Mob.java @@ -211,6 +211,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab @Override public void inactiveTick() { super.inactiveTick(); -+ // Paper start - Skip AI during inactive ticks for non-aware mobs ++ // Paper PR start - Skip AI during inactive ticks for non-aware mobs + if (org.dreeam.leaf.config.modules.opt.SkipAIForNonAwareMob.enabled && !(this.isEffectiveAi() && this.aware)) { + return; + } -+ // Paper end - Skip AI during inactive ticks for non-aware mobs ++ // Paper PR end - Skip AI during inactive ticks for non-aware mobs boolean isThrottled = org.dreeam.leaf.config.modules.opt.ThrottleInactiveGoalSelectorTick.enabled && _pufferfish_inactiveTickDisableCounter++ % 20 != 0; // Pufferfish - throttle inactive goal selector ticking if (this.goalSelector.inactiveTick(this.activatedPriority, true) && !isThrottled) { // Pufferfish - pass activated priroity // Pufferfish - throttle inactive goal selector ticking this.goalSelector.tick(); diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java -index 014bb5b6e82bb11b756430999522f4b8f9356d9f..174c37fca6b2b03a6eb36d8c7c17b6e8ec49f1cd 100644 +index 014bb5b6e82bb11b756430999522f4b8f9356d9f..e6a750ab472eba53de1e5f9e2f507f3a0a9d94d4 100644 --- a/net/minecraft/world/entity/npc/Villager.java +++ b/net/minecraft/world/entity/npc/Villager.java @@ -374,7 +374,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @@ -32,7 +32,7 @@ index 014bb5b6e82bb11b756430999522f4b8f9356d9f..174c37fca6b2b03a6eb36d8c7c17b6e8 this.setUnhappyCounter(this.getUnhappyCounter() - 1); } - if (this.isEffectiveAi()) { -+ if (this.isEffectiveAi() && (!org.dreeam.leaf.config.modules.opt.SkipAIForNonAwareMob.enabled || this.aware)) { // Paper - Skip AI during inactive ticks for non-aware mobs ++ if (this.isEffectiveAi() && (!org.dreeam.leaf.config.modules.opt.SkipAIForNonAwareMob.enabled || this.aware)) { // Paper PR - Skip AI during inactive ticks for non-aware mobs if (this.level().spigotConfig.tickInactiveVillagers) { this.customServerAiStep(this.level().getMinecraftWorld()); } else { diff --git a/leaf-server/minecraft-patches/features/0165-Paper-PR-Prevent-zombie-reinforcements-loading-chunk.patch b/leaf-server/minecraft-patches/features/0165-Paper-PR-Prevent-zombie-reinforcements-loading-chunk.patch index d05b4ab1..ae5b8ae1 100644 --- a/leaf-server/minecraft-patches/features/0165-Paper-PR-Prevent-zombie-reinforcements-loading-chunk.patch +++ b/leaf-server/minecraft-patches/features/0165-Paper-PR-Prevent-zombie-reinforcements-loading-chunk.patch @@ -12,7 +12,7 @@ before spawning, it checks isSpawnPositionOk() for the position which loads the This patch ensures the chunk at the random location is loaded before trying to spawn the reinforcement zombie in it. diff --git a/net/minecraft/world/entity/monster/Zombie.java b/net/minecraft/world/entity/monster/Zombie.java -index 185d138f65e884eb9b3fdd753bc4e2a14a25c4b1..3c1bc0259634be5d988eae93d781c351ec6f3251 100644 +index 185d138f65e884eb9b3fdd753bc4e2a14a25c4b1..8907a5cc50df34cd77f0844e6a503f87e5a2d051 100644 --- a/net/minecraft/world/entity/monster/Zombie.java +++ b/net/minecraft/world/entity/monster/Zombie.java @@ -400,6 +400,13 @@ public class Zombie extends Monster { @@ -20,11 +20,11 @@ index 185d138f65e884eb9b3fdd753bc4e2a14a25c4b1..3c1bc0259634be5d988eae93d781c351 int i3 = floor2 + Mth.nextInt(this.random, 7, 40) * Mth.nextInt(this.random, -1, 1); BlockPos blockPos = new BlockPos(i1, i2, i3); + -+ // Paper start - Prevent reinforcement checks from loading chunks ++ // Paper PR start - Prevent reinforcement checks from loading chunks + if (this.level().getChunkIfLoadedImmediately(blockPos.getX() >> 4, blockPos.getZ() >> 4) == null) { + continue; + } -+ // Paper end - Prevent reinforcement checks from loading chunks ++ // Paper PR end - Prevent reinforcement checks from loading chunks + if (SpawnPlacements.isSpawnPositionOk(type, level, blockPos) && SpawnPlacements.checkSpawnRules(type, level, EntitySpawnReason.REINFORCEMENT, blockPos, level.random)) { diff --git a/leaf-server/minecraft-patches/features/0166-PaperPR-Fix-some-beacon-event-issues.patch b/leaf-server/minecraft-patches/features/0166-Paper-PR-Fix-some-beacon-event-issues.patch similarity index 85% rename from leaf-server/minecraft-patches/features/0166-PaperPR-Fix-some-beacon-event-issues.patch rename to leaf-server/minecraft-patches/features/0166-Paper-PR-Fix-some-beacon-event-issues.patch index 3c888b06..c77f8635 100644 --- a/leaf-server/minecraft-patches/features/0166-PaperPR-Fix-some-beacon-event-issues.patch +++ b/leaf-server/minecraft-patches/features/0166-Paper-PR-Fix-some-beacon-event-issues.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Thu, 31 Aug 2023 10:23:06 +0200 -Subject: [PATCH] PaperPR: Fix some beacon event issues +Subject: [PATCH] Paper PR: Fix some beacon event issues Original license: GPLv3 Original project: https://github.com/PaperMC/Paper @@ -14,14 +14,14 @@ Moves the deactivate event call into the onRemove method for the beacon block it The field I added feels a bit wrong but it works, it's to prevent the activation event being called immediately after loading, can't see any better way to differentiate between a newly placed beacon and a newly loaded one. diff --git a/net/minecraft/world/level/block/entity/BeaconBlockEntity.java b/net/minecraft/world/level/block/entity/BeaconBlockEntity.java -index c2e15c6e1c6bfc5a9d89afc9b8aa9551bad2cc8f..bd831e116a8e394014c1a6fe3928daf3c9bdd8b5 100644 +index c2e15c6e1c6bfc5a9d89afc9b8aa9551bad2cc8f..bf79ba5da09b4b3a7152aa5f5175e86b79ec124b 100644 --- a/net/minecraft/world/level/block/entity/BeaconBlockEntity.java +++ b/net/minecraft/world/level/block/entity/BeaconBlockEntity.java @@ -173,6 +173,8 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name return VALID_EFFECTS.contains(effect) ? effect : null; } -+ public boolean justLoadedAndPreviouslyActive; // Paper - consider beacon previously active for first tick to skip activate event/sound ++ public boolean justLoadedAndPreviouslyActive; // Paper PR - consider beacon previously active for first tick to skip activate event/sound + public BeaconBlockEntity(BlockPos pos, BlockState blockState) { super(BlockEntityType.BEACON, pos, blockState); @@ -31,16 +31,16 @@ index c2e15c6e1c6bfc5a9d89afc9b8aa9551bad2cc8f..bd831e116a8e394014c1a6fe3928daf3 } // Paper start - beacon activation/deactivation events - if (originalLevels <= 0 && blockEntity.levels > 0) { -+ // Paper start ++ // Paper PR start - Fix some beacon event issues + final boolean prevActive = originalLevels > 0 && (!blockEntity.beamSections.isEmpty() || (blockEntity.justLoadedAndPreviouslyActive && !blockEntity.checkingBeamSections.isEmpty())); + blockEntity.justLoadedAndPreviouslyActive = false; + final boolean newActive = blockEntity.levels > 0 && !blockEntity.checkingBeamSections.isEmpty(); + if (!prevActive && newActive) { -+ // Paper end ++ // Paper PR end - Fix some beacon event issues org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos); new io.papermc.paper.event.block.BeaconActivatedEvent(block).callEvent(); - } else if (originalLevels > 0 && blockEntity.levels <= 0) { -+ } else if (prevActive && !newActive) { // Paper ++ } else if (prevActive && !newActive) { // Paper PR - Fix some beacon event issues org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos); new io.papermc.paper.event.block.BeaconDeactivatedEvent(block).callEvent(); } @@ -49,11 +49,11 @@ index c2e15c6e1c6bfc5a9d89afc9b8aa9551bad2cc8f..bd831e116a8e394014c1a6fe3928daf3 if (blockEntity.lastCheckY >= height) { blockEntity.lastCheckY = level.getMinY() - 1; - boolean flag = i > 0; -+ boolean flag = prevActive; // Paper - Fix MC-183981 ++ boolean flag = prevActive; // Paper PR - Fix MC-183981 blockEntity.beamSections = blockEntity.checkingBeamSections; if (!level.isClientSide) { - boolean flag1 = blockEntity.levels > 0; -+ boolean flag1 = newActive; // Paper - Fix MC-183981 ++ boolean flag1 = newActive; // Paper PR - Fix MC-183981 if (!flag && flag1) { playSound(level, pos, SoundEvents.BEACON_ACTIVATE); @@ -72,7 +72,7 @@ index c2e15c6e1c6bfc5a9d89afc9b8aa9551bad2cc8f..bd831e116a8e394014c1a6fe3928daf3 this.primaryPower = loadEffect(input, "primary_effect"); this.secondaryPower = loadEffect(input, "secondary_effect"); this.levels = input.getIntOr("Levels", 0); // CraftBukkit - SPIGOT-5053, use where available -+ this.justLoadedAndPreviouslyActive = this.levels > 0; // Paper ++ this.justLoadedAndPreviouslyActive = this.levels > 0; // Paper PR - Fix some beacon event issues this.name = parseCustomNameSafe(input, "CustomName"); this.lockKey = LockCode.fromTag(input); this.effectRange = input.getDoubleOr(PAPER_RANGE_TAG, -1); // Paper - Custom beacon ranges @@ -81,7 +81,7 @@ index c2e15c6e1c6bfc5a9d89afc9b8aa9551bad2cc8f..bd831e116a8e394014c1a6fe3928daf3 this.lastCheckY = level.getMinY() - 1; } + -+ // Paper start - BeaconDeactivatedEvent ++ // Paper PR start - Fix some beacon event issues - BeaconDeactivatedEvent + @Override + public void preRemoveSideEffects(BlockPos pos, BlockState state) { + BeaconBlockEntity beacon = this; @@ -90,5 +90,5 @@ index c2e15c6e1c6bfc5a9d89afc9b8aa9551bad2cc8f..bd831e116a8e394014c1a6fe3928daf3 + new io.papermc.paper.event.block.BeaconDeactivatedEvent(block).callEvent(); + } + } -+ // Paper end ++ // Paper PR end - Fix some beacon event issues - BeaconDeactivatedEvent } diff --git a/leaf-server/minecraft-patches/features/0189-PaperPR-Fix-MC-117075-Block-Entities-Unload-Lag-Spik.patch b/leaf-server/minecraft-patches/features/0189-Paper-PR-Fix-MC-117075-Block-Entities-Unload-Lag-Spi.patch similarity index 95% rename from leaf-server/minecraft-patches/features/0189-PaperPR-Fix-MC-117075-Block-Entities-Unload-Lag-Spik.patch rename to leaf-server/minecraft-patches/features/0189-Paper-PR-Fix-MC-117075-Block-Entities-Unload-Lag-Spi.patch index c7fc751c..0fbff872 100644 --- a/leaf-server/minecraft-patches/features/0189-PaperPR-Fix-MC-117075-Block-Entities-Unload-Lag-Spik.patch +++ b/leaf-server/minecraft-patches/features/0189-Paper-PR-Fix-MC-117075-Block-Entities-Unload-Lag-Spi.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: MrPowerGamerBR Date: Sun, 26 Nov 2023 13:02:16 -0300 -Subject: [PATCH] PaperPR: Fix MC-117075: Block Entities Unload Lag Spike +Subject: [PATCH] Paper PR: Fix MC-117075: Block Entities Unload Lag Spike Original license: GPLv3 Original project: https://github.com/SparklyPower/SparklyPaper @@ -12,7 +12,7 @@ We replaced the `blockEntityTickers` list with a custom list based on fastutil's This is WAY FASTER than using `removeAll` with a list of entries to be removed, because we don't need to calculate the identity of each block entity to be removed, and we can jump directly to where the search should begin, giving a performance boost for small removals (because we don't need to loop thru the entire list to find what element should be removed) and a performance boost for big removals (no need to calculate the identity of each block entity). diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index 8ebfb2f5cf439190ea9bd4ad81d737fbcd4514c2..ca39e3bd93f896d5c7b1fc3b9264f64555be5d50 100644 +index 3f02f57eca3768d843e58dd2936f37c7f5743402..4ba44c325c7a29d398ed10335108bc5c9556e109 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java @@ -104,7 +104,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl diff --git a/leaf-server/minecraft-patches/features/0212-PaperPR-Fix-cancelled-Projectile-Events-still-consum.patch b/leaf-server/minecraft-patches/features/0212-Paper-PR-Fix-cancelled-Projectile-Events-still-consu.patch similarity index 82% rename from leaf-server/minecraft-patches/features/0212-PaperPR-Fix-cancelled-Projectile-Events-still-consum.patch rename to leaf-server/minecraft-patches/features/0212-Paper-PR-Fix-cancelled-Projectile-Events-still-consu.patch index 6d53d270..f655e9ac 100644 --- a/leaf-server/minecraft-patches/features/0212-PaperPR-Fix-cancelled-Projectile-Events-still-consum.patch +++ b/leaf-server/minecraft-patches/features/0212-Paper-PR-Fix-cancelled-Projectile-Events-still-consu.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tamion <70228790+notTamion@users.noreply.github.com> Date: Sun, 16 Feb 2025 12:22:53 +0100 -Subject: [PATCH] PaperPR: Fix cancelled Projectile Events still consuming +Subject: [PATCH] Paper PR: Fix cancelled Projectile Events still consuming arrows Original license: GPLv3 @@ -11,7 +11,7 @@ Paper pull request: https://github.com/PaperMC/Paper/pull/12124 fixes https://github.com/PaperMC/Paper/issues/12123 diff --git a/net/minecraft/world/item/BowItem.java b/net/minecraft/world/item/BowItem.java -index ce1ce18410fc1d47d999c918a8f880b43bf9797c..b9d31b0cbeabd5c62b810e50f612878624975d4e 100644 +index ce1ce18410fc1d47d999c918a8f880b43bf9797c..ef8b4bbbd24e1e91cad4fdb028388721c993fc73 100644 --- a/net/minecraft/world/item/BowItem.java +++ b/net/minecraft/world/item/BowItem.java @@ -41,9 +41,9 @@ public class BowItem extends ProjectileWeaponItem { @@ -19,15 +19,15 @@ index ce1ce18410fc1d47d999c918a8f880b43bf9797c..b9d31b0cbeabd5c62b810e50f6128786 return false; } else { - List list = draw(stack, projectile, player); -+ List list = draw(stack, projectile, player, ProjectileDrawingItemConsumption.MAYBE_LATER); // Paper - prevent item consumption for cancelled events ++ List list = draw(stack, projectile, player, ProjectileDrawingItemConsumption.MAYBE_LATER); // Paper PR - prevent item consumption for cancelled events if (level instanceof ServerLevel serverLevel && !list.isEmpty()) { - this.shoot(serverLevel, player, player.getUsedItemHand(), stack, list, powerForTime * 3.0F, (float) serverLevel.purpurConfig.bowProjectileOffset, powerForTime == 1.0F, null, powerForTime); // Paper - Pass draw strength // Purpur - Projectile offset config -+ if (!this.shoot(serverLevel, player, player.getUsedItemHand(), stack, new UnrealizedDrawResult(list, projectile), powerForTime * 3.0F, (float) serverLevel.purpurConfig.bowProjectileOffset, powerForTime == 1.0F, null, powerForTime)) return false; // Paper - Pass draw strength // Purpur - Projectile offset config // Paper - prevent item consumption for cancelled events ++ if (!this.shoot(serverLevel, player, player.getUsedItemHand(), stack, new UnrealizedDrawResult(list, projectile), powerForTime * 3.0F, (float) serverLevel.purpurConfig.bowProjectileOffset, powerForTime == 1.0F, null, powerForTime)) return false; // Paper - Pass draw strength // Purpur - Projectile offset config // Paper PR - prevent item consumption for cancelled events } level.playSound( diff --git a/net/minecraft/world/item/CrossbowItem.java b/net/minecraft/world/item/CrossbowItem.java -index d49a5360d4a21e5b15bac94a823831e25d242a3d..2c2f169096fa904adb4cda0186bae7d0ab35f1e3 100644 +index d49a5360d4a21e5b15bac94a823831e25d242a3d..04286fdba0c22d5b6d7b3ab71ee1a1fe3ed92e6d 100644 --- a/net/minecraft/world/item/CrossbowItem.java +++ b/net/minecraft/world/item/CrossbowItem.java @@ -95,7 +95,7 @@ public class CrossbowItem extends ProjectileWeaponItem { @@ -35,7 +35,7 @@ index d49a5360d4a21e5b15bac94a823831e25d242a3d..2c2f169096fa904adb4cda0186bae7d0 private static boolean tryLoadProjectiles(LivingEntity shooter, ItemStack crossbowStack, boolean consume) { - List list = draw(crossbowStack, shooter.getProjectile(crossbowStack), shooter, consume); -+ List list = draw(crossbowStack, shooter.getProjectile(crossbowStack), shooter, consume ? ProjectileDrawingItemConsumption.IMMEDIATELY : ProjectileDrawingItemConsumption.NEVER); // Paper - prevent item consumption for cancelled events ++ List list = draw(crossbowStack, shooter.getProjectile(crossbowStack), shooter, consume ? ProjectileDrawingItemConsumption.IMMEDIATELY : ProjectileDrawingItemConsumption.NEVER); // Paper PR - prevent item consumption for cancelled events // Paper end - Add EntityLoadCrossbowEvent if (!list.isEmpty()) { crossbowStack.set(DataComponents.CHARGED_PROJECTILES, ChargedProjectiles.of(list)); @@ -45,10 +45,10 @@ index d49a5360d4a21e5b15bac94a823831e25d242a3d..2c2f169096fa904adb4cda0186bae7d0 projectile.shoot(projectileShotVector.x(), projectileShotVector.y(), projectileShotVector.z(), velocity, inaccuracy); - float shotPitch = getShotPitch(shooter.getRandom(), index); - shooter.level().playSound(null, shooter.getX(), shooter.getY(), shooter.getZ(), SoundEvents.CROSSBOW_SHOOT, shooter.getSoundSource(), 1.0F, shotPitch); -+ // Paper start - moved up to ensure events weren't cancelled ++ // Paper PR start - moved up to ensure events weren't cancelled + // float shotPitch = getShotPitch(shooter.getRandom(), index); + // shooter.level().playSound(null, shooter.getX(), shooter.getY(), shooter.getZ(), SoundEvents.CROSSBOW_SHOOT, shooter.getSoundSource(), 1.0F, shotPitch); -+ // Paper end - moved up to ensure events weren't cancelled ++ // Paper PR end - moved up to ensure events weren't cancelled } private static Vector3f getProjectileShotVector(LivingEntity shooter, Vec3 distance, float angle) { @@ -57,15 +57,15 @@ index d49a5360d4a21e5b15bac94a823831e25d242a3d..2c2f169096fa904adb4cda0186bae7d0 ) { if (level instanceof ServerLevel serverLevel) { - ChargedProjectiles chargedProjectiles = weapon.set(DataComponents.CHARGED_PROJECTILES, ChargedProjectiles.EMPTY); -+ ChargedProjectiles chargedProjectiles = weapon.get(DataComponents.CHARGED_PROJECTILES); // Paper - prevent item consumption for cancelled events ++ ChargedProjectiles chargedProjectiles = weapon.get(DataComponents.CHARGED_PROJECTILES); // Paper PR - prevent item consumption for cancelled events if (chargedProjectiles != null && !chargedProjectiles.isEmpty()) { - this.shoot(serverLevel, shooter, hand, weapon, chargedProjectiles.getItems(), velocity, inaccuracy, shooter instanceof Player, target, 1); // Paper - Pass draw strength -+ if (!this.shoot(serverLevel, shooter, hand, weapon, chargedProjectiles.getItems(), velocity, inaccuracy, shooter instanceof Player, target, 1)) return; // Paper - Pass draw strength // Paper - prevent item consumption for cancelled events ++ if (!this.shoot(serverLevel, shooter, hand, weapon, chargedProjectiles.getItems(), velocity, inaccuracy, shooter instanceof Player, target, 1)) return; // Paper - Pass draw strength // Paper PR - prevent item consumption for cancelled events if (shooter instanceof ServerPlayer serverPlayer) { CriteriaTriggers.SHOT_CROSSBOW.trigger(serverPlayer, weapon); serverPlayer.awardStat(Stats.ITEM_USED.get(weapon.getItem())); diff --git a/net/minecraft/world/item/ProjectileWeaponItem.java b/net/minecraft/world/item/ProjectileWeaponItem.java -index f12b9e4e8a78c713782af548d1cb15ef363305b4..d1661c9b971ba431da3f71fd6e0c3517c6625a11 100644 +index f12b9e4e8a78c713782af548d1cb15ef363305b4..1ac688cc89c32168bcb3ecda2a4e1f993098b3aa 100644 --- a/net/minecraft/world/item/ProjectileWeaponItem.java +++ b/net/minecraft/world/item/ProjectileWeaponItem.java @@ -40,7 +40,20 @@ public abstract class ProjectileWeaponItem extends Item { @@ -73,7 +73,7 @@ index f12b9e4e8a78c713782af548d1cb15ef363305b4..d1661c9b971ba431da3f71fd6e0c3517 public abstract int getDefaultProjectileRange(); - protected void shoot( -+ // Paper start - prevent item consumption for cancelled events ++ // Paper PR start - prevent item consumption for cancelled events + protected record UnrealizedDrawResult( + List projectileStacks, + @Nullable ItemStack originalInPlayerInventory // Null in case the unrealised draw result is a noop (case of Crossbow) @@ -86,7 +86,7 @@ index f12b9e4e8a78c713782af548d1cb15ef363305b4..d1661c9b971ba431da3f71fd6e0c3517 + } + } + protected boolean shoot( -+ // Paper end - prevent item consumption for cancelled events ++ // Paper PR end - prevent item consumption for cancelled events ServerLevel level, LivingEntity shooter, InteractionHand hand, @@ -94,7 +94,7 @@ index f12b9e4e8a78c713782af548d1cb15ef363305b4..d1661c9b971ba431da3f71fd6e0c3517 @Nullable LivingEntity target ,float drawStrength // Paper - Pass draw strength ) { -+ // Paper start - prevent item consumption for cancelled events ++ // Paper PR start - prevent item consumption for cancelled events + return shoot(level, shooter, hand, weapon, new UnrealizedDrawResult(projectileItems, null), velocity, inaccuracy, isCrit, target, drawStrength); + } + protected boolean shoot( @@ -111,32 +111,34 @@ index f12b9e4e8a78c713782af548d1cb15ef363305b4..d1661c9b971ba431da3f71fd6e0c3517 + ) { + List projectileItems = unrealizedDrawResult.projectileStacks(); + boolean atLeastOneShootBowEventUncancelled = false; -+ // Paper end - prevent item consumption for cancelled events ++ // Paper PR end - prevent item consumption for cancelled events float f = EnchantmentHelper.processProjectileSpread(level, weapon, shooter, 0.0F); float f1 = projectileItems.size() == 1 ? 0.0F : 2.0F * f / (projectileItems.size() - 1); float f2 = (projectileItems.size() - 1) % 2 * f1 / 2.0F; -@@ -67,11 +98,13 @@ public abstract class ProjectileWeaponItem extends Item { +@@ -67,11 +98,15 @@ public abstract class ProjectileWeaponItem extends Item { Projectile projectile = this.createProjectile(level, shooter, weapon, itemStack, isCrit); this.shootProjectile(shooter, projectile, i1, velocity, inaccuracy, f4, target); - org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(shooter, weapon, itemStack, projectile, hand, drawStrength, true); ++ // Paper PR start - prevent item consumption for cancelled events; call for each shot projectile + boolean preConsumption = weapon.is(Items.CROSSBOW) || shooter.level().shouldConsumeArrow; + org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(shooter, weapon, itemStack, projectile, hand, drawStrength, preConsumption); ++ // Paper PR end - prevent item consumption for cancelled events; call for each shot projectile if (event.isCancelled()) { event.getProjectile().remove(); - return; -+ continue; // Paper - prevent item consumption for cancelled events; call for each shot projectile ++ continue; // Paper PR - prevent item consumption for cancelled events; call for each shot projectile } -+ atLeastOneShootBowEventUncancelled = true; // Paper - prevent item consumption for cancelled events ++ atLeastOneShootBowEventUncancelled = true; // Paper PR - prevent item consumption for cancelled events if (event.getProjectile() == projectile.getBukkitEntity()) { if (Projectile.spawnProjectile( -@@ -79,7 +112,25 @@ public abstract class ProjectileWeaponItem extends Item { +@@ -79,7 +114,25 @@ public abstract class ProjectileWeaponItem extends Item { level, itemStack ).isRemoved()) { - return; -+ // Paper start - prevent item consumption for cancelled events ++ // Paper PR start - prevent item consumption for cancelled events + continue; // call for each shot projectile + } + } @@ -154,25 +156,25 @@ index f12b9e4e8a78c713782af548d1cb15ef363305b4..d1661c9b971ba431da3f71fd6e0c3517 + weapon.set(DataComponents.CHARGED_PROJECTILES, net.minecraft.world.item.component.ChargedProjectiles.of(newProjectiles)); + } else if (level.shouldConsumeArrow) { + unrealizedDrawResult.consumeProjectilesFromPlayerInventory(i); -+ // Paper end - prevent item consumption for cancelled events ++ // Paper PR end - prevent item consumption for cancelled events } } // CraftBukkit end -@@ -89,6 +140,7 @@ public abstract class ProjectileWeaponItem extends Item { +@@ -89,6 +142,7 @@ public abstract class ProjectileWeaponItem extends Item { } } } -+ return atLeastOneShootBowEventUncancelled; // Paper - prevent item consumption for cancelled events ++ return atLeastOneShootBowEventUncancelled; // Paper PR - prevent item consumption for cancelled events } protected int getDurabilityUse(ItemStack stack) { -@@ -112,11 +164,21 @@ public abstract class ProjectileWeaponItem extends Item { +@@ -112,11 +166,21 @@ public abstract class ProjectileWeaponItem extends Item { } protected static List draw(ItemStack weapon, ItemStack ammo, LivingEntity shooter) { - // Paper start - return draw(weapon, ammo, shooter, true); -+ // Paper start - prevent item consumption for cancelled events ++ // Paper PR start - prevent item consumption for cancelled events + return draw(weapon, ammo, shooter, ProjectileDrawingItemConsumption.IMMEDIATELY); } - protected static List draw(ItemStack weapon, ItemStack ammo, LivingEntity shooter, boolean consume) { @@ -188,56 +190,56 @@ index f12b9e4e8a78c713782af548d1cb15ef363305b4..d1661c9b971ba431da3f71fd6e0c3517 + NEVER, + } + protected static List draw(ItemStack weapon, ItemStack ammo, LivingEntity shooter, final ProjectileDrawingItemConsumption consume) { -+ // Paper end - prevent item consumption for cancelled events ++ // Paper PR end - prevent item consumption for cancelled events if (ammo.isEmpty()) { return List.of(); } else { -@@ -124,8 +186,9 @@ public abstract class ProjectileWeaponItem extends Item { +@@ -124,8 +188,9 @@ public abstract class ProjectileWeaponItem extends Item { List list = new ArrayList<>(i); ItemStack itemStack = ammo.copy(); -+ shooter.level().shouldConsumeArrow = true; // Paper - prevent item consumption for cancelled events ++ shooter.level().shouldConsumeArrow = true; // Paper PR - prevent item consumption for cancelled events for (int i1 = 0; i1 < i; i1++) { - ItemStack itemStack1 = useAmmo(weapon, i1 == 0 ? ammo : itemStack, shooter, i1 > 0 || !consume); // Paper -+ ItemStack itemStack1 = useAmmo(weapon, i1 == 0 ? ammo : itemStack, shooter, i1 > 0, consume); // Paper ++ ItemStack itemStack1 = useAmmo(weapon, i1 == 0 ? ammo : itemStack, shooter, i1 > 0, consume); // Paper PR - prevent item consumption for cancelled events if (!itemStack1.isEmpty()) { list.add(itemStack1); } -@@ -136,17 +199,23 @@ public abstract class ProjectileWeaponItem extends Item { +@@ -136,17 +201,23 @@ public abstract class ProjectileWeaponItem extends Item { } protected static ItemStack useAmmo(ItemStack weapon, ItemStack ammo, LivingEntity shooter, boolean intangable) { - int i = !intangable && !shooter.hasInfiniteMaterials() && shooter.level() instanceof ServerLevel serverLevel -+ // Paper start - prevent item consumption for cancelled events ++ // Paper PR start - prevent item consumption for cancelled events + return useAmmo(weapon, ammo, shooter, intangable, ProjectileDrawingItemConsumption.IMMEDIATELY); + } + protected static ItemStack useAmmo(ItemStack weapon, ItemStack ammo, LivingEntity shooter, boolean intangable, final ProjectileDrawingItemConsumption consumption) { + int i = !intangable && consumption != ProjectileDrawingItemConsumption.NEVER && !shooter.hasInfiniteMaterials() && shooter.level() instanceof ServerLevel serverLevel ? EnchantmentHelper.processAmmoUse(serverLevel, weapon, ammo, 1) : 0; -+ // Paper end - prevent item consumption for cancelled events ++ // Paper PR end - prevent item consumption for cancelled events if (i > ammo.getCount()) { return ItemStack.EMPTY; } else if (i == 0) { -+ if (!intangable) shooter.level().shouldConsumeArrow = false; // Paper - prevent item consumption for cancelled events ++ if (!intangable) shooter.level().shouldConsumeArrow = false; // Paper PR - prevent item consumption for cancelled events ItemStack itemStack = ammo.copyWithCount(1); itemStack.set(DataComponents.INTANGIBLE_PROJECTILE, Unit.INSTANCE); return itemStack; } else { - ItemStack itemStack = ammo.split(i); -+ ItemStack itemStack = consumption == ProjectileDrawingItemConsumption.MAYBE_LATER ? ammo.copyWithCount(i) : ammo.split(i); // Paper - prevent item consumption for cancelled events ++ ItemStack itemStack = consumption == ProjectileDrawingItemConsumption.MAYBE_LATER ? ammo.copyWithCount(i) : ammo.split(i); // Paper PR - prevent item consumption for cancelled events if (ammo.isEmpty() && shooter instanceof Player player) { player.getInventory().removeItem(ammo); } diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index 54f03ad9b7f62bf717f32376e81a49bbf600385c..a2abfc5db556bc9a80098a675545f67907a8886b 100644 +index 93be887352ac5995672a18b7289e5f4d0ca25870..f881866e460b1361f3691c5a999277673845f64e 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java @@ -171,6 +171,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl public final Map explosionDensityCache = new java.util.HashMap<>(); // Paper - Optimize explosions public java.util.ArrayDeque redstoneUpdateInfos; // Paper - Faster redstone torch rapid clock removal; Move from Map in BlockRedstoneTorch to here public final net.minecraft.world.level.levelgen.BitRandomSource simpleRandom = org.dreeam.leaf.config.modules.opt.FastRNG.enabled ? new org.dreeam.leaf.util.math.random.FasterRandomSource(net.minecraft.world.level.levelgen.RandomSupport.generateUniqueSeed()) : new ca.spottedleaf.moonrise.common.util.SimpleThreadUnsafeRandom(net.minecraft.world.level.levelgen.RandomSupport.generateUniqueSeed()); // Gale - Pufferfish - move random tick random // Leaf - Faster random generator -+ public boolean shouldConsumeArrow = true; // Paper - prevent item consumption for cancelled shot events ++ public boolean shouldConsumeArrow = true; // Paper PR - prevent item consumption for cancelled shot events // Purpur start - Add adjustable breeding cooldown to config private com.google.common.cache.Cache playerBreedingCooldowns; diff --git a/leaf-server/minecraft-patches/features/0216-Paper-PR-Throttle-failed-spawn-attempts.patch b/leaf-server/minecraft-patches/features/0216-Paper-PR-Throttle-failed-spawn-attempts.patch index 157501bb..ee31b121 100644 --- a/leaf-server/minecraft-patches/features/0216-Paper-PR-Throttle-failed-spawn-attempts.patch +++ b/leaf-server/minecraft-patches/features/0216-Paper-PR-Throttle-failed-spawn-attempts.patch @@ -31,14 +31,14 @@ vain. Throttling spawn attempts in suspected spawnproof chunks improves performance without noticeably advantaging or disadvantaging the mob farm. diff --git a/net/minecraft/world/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java -index 345d4b80bd4383e0fb66d744d87bc8ef4100fd32..a2da4fce50f31d56036d04041c4f80ed90c18b27 100644 +index 102d88fc2989f80a39826e50ee706d853bfb2c5e..838146e997a2033c3d2a96602a252178093d263e 100644 --- a/net/minecraft/world/level/NaturalSpawner.java +++ b/net/minecraft/world/level/NaturalSpawner.java @@ -158,10 +158,21 @@ public final class NaturalSpawner { // Copied from getFilteredSpawningCategories int limit = mobCategory.getMaxInstancesPerChunk(); org.bukkit.entity.SpawnCategory spawnCategory = org.bukkit.craftbukkit.util.CraftSpawnCategory.toBukkit(mobCategory); -+ // Paper start - throttle failed spawn attempts ++ // Paper PR start - throttle failed spawn attempts + boolean spawnThisTick = true; + long ticksPerSpawn = level.ticksPerSpawnCategory.getLong(spawnCategory); + long ticksPerSpawnTmp = ticksPerSpawn; @@ -46,13 +46,13 @@ index 345d4b80bd4383e0fb66d744d87bc8ef4100fd32..a2da4fce50f31d56036d04041c4f80ed + if (spawningThrottle.failedAttemptsThreshold.test(threshold -> chunk.failedSpawnAttempts[mobCategory.ordinal()] > threshold)) { + ticksPerSpawn = Math.max(ticksPerSpawn, spawningThrottle.throttledTicksPerSpawn.getOrDefault(mobCategory, -1)); + } -+ // Paper end - throttle failed spawn attempts ++ // Paper PR end - throttle failed spawn attempts if (org.bukkit.craftbukkit.util.CraftSpawnCategory.isValidForLimits(spawnCategory)) { -+ spawnThisTick = ticksPerSpawnTmp != 0 && level.getGameTime() % ticksPerSpawn == 0; // Paper - throttle failed spawn attempts ++ spawnThisTick = ticksPerSpawnTmp != 0 && level.getGameTime() % ticksPerSpawn == 0; // Paper PR - throttle failed spawn attempts limit = level.getWorld().getSpawnLimit(spawnCategory); } -+ if (!spawningThrottle.failedAttemptsThreshold.enabled() || spawnThisTick) { // Paper - throttle failed spawn attempts ++ if (!spawningThrottle.failedAttemptsThreshold.enabled() || spawnThisTick) { // Paper PR - throttle failed spawn attempts // Apply per-player limit int minDiff = Integer.MAX_VALUE; final ca.spottedleaf.moonrise.common.list.ReferenceList inRange = @@ -60,14 +60,14 @@ index 345d4b80bd4383e0fb66d744d87bc8ef4100fd32..a2da4fce50f31d56036d04041c4f80ed maxSpawns = (minDiff == Integer.MAX_VALUE) ? 0 : minDiff; canSpawn = maxSpawns > 0; -+ } else { canSpawn = false; } // Paper - throttle failed spawn attempts ++ } else { canSpawn = false; } // Paper PR - throttle failed spawn attempts } else { canSpawn = spawnState.canSpawnForCategoryLocal(mobCategory, chunk.getPos()); } if (canSpawn) { - spawnCategoryForChunk(mobCategory, level, chunk, spawnState::canSpawn, spawnState::afterSpawn, - maxSpawns, level.paperConfig().entities.spawning.perPlayerMobSpawns ? level.getChunkSource().chunkMap::updatePlayerMobTypeMap : null); -+ // Paper start - throttle failed spawn attempts ++ // Paper PR start - throttle failed spawn attempts + int spawnCount = spawnCategoryForChunk(mobCategory, level, chunk, spawnState::canSpawn, spawnState::afterSpawn, + maxSpawns, level.paperConfig().entities.spawning.perPlayerMobSpawns ? level.getChunkSource().chunkMap::updatePlayerMobTypeMap : null, false); + if (spawnCount == 0) { @@ -75,7 +75,7 @@ index 345d4b80bd4383e0fb66d744d87bc8ef4100fd32..a2da4fce50f31d56036d04041c4f80ed + } else { + chunk.failedSpawnAttempts[mobCategory.ordinal()] = 0; + } -+ // Paper end - throttle failed spawn attempts ++ // Paper end PR - throttle failed spawn attempts // Paper end - Optional per player mob spawns } } @@ -83,22 +83,22 @@ index 345d4b80bd4383e0fb66d744d87bc8ef4100fd32..a2da4fce50f31d56036d04041c4f80ed } public static void spawnCategoryForChunk( MobCategory category, ServerLevel level, LevelChunk chunk, NaturalSpawner.SpawnPredicate filter, NaturalSpawner.AfterSpawnCallback callback, final int maxSpawns, final Consumer trackEntity -+ // Paper start - throttle failed spawn attempts ++ // Paper PR start - throttle failed spawn attempts + ) { + spawnCategoryForChunk(category, level, chunk, filter, callback, maxSpawns, trackEntity, false); + } + public static int spawnCategoryForChunk( + MobCategory category, ServerLevel level, LevelChunk chunk, NaturalSpawner.SpawnPredicate filter, NaturalSpawner.AfterSpawnCallback callback, final int maxSpawns, final Consumer trackEntity, final boolean nothing -+ // Paper end - throttle failed spawn attempts ++ // Paper PR end - throttle failed spawn attempts ) { // Paper end - Optional per player mob spawns BlockPos randomPosWithin = getRandomPosWithin(level, chunk); if (randomPosWithin.getY() >= level.getMinY() + 1) { - spawnCategoryForPosition(category, level, chunk, randomPosWithin, filter, callback, maxSpawns, trackEntity); // Paper - Optional per player mob spawns -+ return spawnCategoryForPosition(category, level, chunk, randomPosWithin, filter, callback, maxSpawns, trackEntity, false); // Paper - Optional per player mob spawns // Paper - throttle failed spawn attempts ++ return spawnCategoryForPosition(category, level, chunk, randomPosWithin, filter, callback, maxSpawns, trackEntity, false); // Paper - Optional per player mob spawns // Paper PR - throttle failed spawn attempts } + -+ return 0; // Paper - throttle failed spawn attempts ++ return 0; // Paper PR - throttle failed spawn attempts } @VisibleForDebug @@ -106,24 +106,24 @@ index 345d4b80bd4383e0fb66d744d87bc8ef4100fd32..a2da4fce50f31d56036d04041c4f80ed } public static void spawnCategoryForPosition( MobCategory category, ServerLevel level, ChunkAccess chunk, BlockPos pos, NaturalSpawner.SpawnPredicate filter, NaturalSpawner.AfterSpawnCallback callback, final int maxSpawns, final @Nullable Consumer trackEntity -+ // Paper start - throttle failed spawn attempts ++ // Paper PR start - throttle failed spawn attempts + ) { + spawnCategoryForPosition(category, level, chunk, pos, filter, callback, maxSpawns, trackEntity, false); + } + public static int spawnCategoryForPosition( + MobCategory category, ServerLevel level, ChunkAccess chunk, BlockPos pos, NaturalSpawner.SpawnPredicate filter, NaturalSpawner.AfterSpawnCallback callback, final int maxSpawns, final @Nullable Consumer trackEntity, final boolean nothing -+ // Paper end - throttle failed spawn attempts ++ // Paper PR end - throttle failed spawn attempts ) { // Paper end - Optional per player mob spawns StructureManager structureManager = level.structureManager(); ChunkGenerator generator = level.getChunkSource().getGenerator(); int y = pos.getY(); -+ int i = 0; // Paper - throttle failed spawn attempts ++ int i = 0; // Paper PR - 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(); - int i = 0; -+ //int i = 0; // Paper - throttle failed spawn attempts - move up ++ //int i = 0; // Paper PR - throttle failed spawn attempts - move up for (int i1 = 0; i1 < 3; i1++) { int x = pos.getX(); @@ -132,7 +132,7 @@ index 345d4b80bd4383e0fb66d744d87bc8ef4100fd32..a2da4fce50f31d56036d04041c4f80ed // Paper end - per player mob count backoff if (doSpawning == PreSpawnStatus.ABORT) { - return; -+ return i; // Paper - throttle failed spawn attempts ++ return i; // Paper PR - throttle failed spawn attempts } if (doSpawning == PreSpawnStatus.SUCCESS // Paper end - PreCreatureSpawnEvent @@ -140,7 +140,7 @@ index 345d4b80bd4383e0fb66d744d87bc8ef4100fd32..a2da4fce50f31d56036d04041c4f80ed Mob mobForSpawn = getMobForSpawn(level, spawnerData.type()); if (mobForSpawn == null) { - return; -+ return i; // Paper - throttle failed spawn attempts ++ return i; // Paper PR - throttle failed spawn attempts } mobForSpawn.snapTo(d, y, d1, level.random.nextFloat() * 360.0F, 0.0F); @@ -149,7 +149,7 @@ index 345d4b80bd4383e0fb66d744d87bc8ef4100fd32..a2da4fce50f31d56036d04041c4f80ed // CraftBukkit end if (i >= mobForSpawn.getMaxSpawnClusterSize() || i >= maxSpawns) { // Paper - Optional per player mob spawns - return; -+ return i; // Paper - throttle failed spawn attempts ++ return i; // Paper PR - throttle failed spawn attempts } if (mobForSpawn.isMaxGroupSizeReached(i3)) { @@ -158,31 +158,31 @@ index 345d4b80bd4383e0fb66d744d87bc8ef4100fd32..a2da4fce50f31d56036d04041c4f80ed } } + -+ return i; // Paper - throttle failed spawn attempts ++ return i; // Paper PR - throttle failed spawn attempts } private static boolean isRightDistanceToPlayerAndSpawnPoint(ServerLevel level, ChunkAccess chunk, BlockPos.MutableBlockPos pos, double distance) { diff --git a/net/minecraft/world/level/chunk/ChunkAccess.java b/net/minecraft/world/level/chunk/ChunkAccess.java -index 686c031ec73acc80683aaa39a78fe9221f0215a6..d7dbe7d24a6697be6b5db729f940b16b74838d11 100644 +index 686c031ec73acc80683aaa39a78fe9221f0215a6..7fc5e56586f2fe8ea1a7437b42da893383878880 100644 --- a/net/minecraft/world/level/chunk/ChunkAccess.java +++ b/net/minecraft/world/level/chunk/ChunkAccess.java @@ -92,6 +92,7 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh private boolean slimeChunk; private boolean hasComputedSlimeChunk; // Leaf end - Matter - Secure Seed -+ public final long[] failedSpawnAttempts = new long[net.minecraft.world.entity.MobCategory.values().length]; // Paper - throttle failed spawn attempts ++ public final long[] failedSpawnAttempts = new long[net.minecraft.world.entity.MobCategory.values().length]; // Paper PR - throttle failed spawn attempts // Paper start - rewrite chunk system private volatile ca.spottedleaf.moonrise.patches.starlight.light.SWMRNibbleArray[] blockNibbles; diff --git a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -index e04d3479383cd480cf35ed7ac3c82e7f6fb69e28..ab1fc7ca0639f9e71933f623258bb8d123988262 100644 +index e04d3479383cd480cf35ed7ac3c82e7f6fb69e28..2c10d216929fbc7f00385e4baac3aa60c203b799 100644 --- a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +++ b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java @@ -94,6 +94,7 @@ public record SerializableChunkData( List blockEntities, CompoundTag structureData , @Nullable net.minecraft.nbt.Tag persistentDataContainer // CraftBukkit - persistentDataContainer -+ , @Nullable long[] failedSpawnAttempts // Paper - throttle failed spawn attempts ++ , @Nullable long[] failedSpawnAttempts // Paper PR - throttle failed spawn attempts ) { public static final Codec> BLOCK_STATE_CODEC = PalettedContainer.codecRW( Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState(), null // Paper - Anti-Xray @@ -190,7 +190,7 @@ index e04d3479383cd480cf35ed7ac3c82e7f6fb69e28..ab1fc7ca0639f9e71933f623258bb8d1 lists[i] = list2; } -+ // Paper start - throttle failed spawn attempts ++ // Paper PR start - throttle failed spawn attempts + long[] failedSpawnAttemptsData = null; + if (tag.contains("Paper.FailedSpawnAttempts")) { + failedSpawnAttemptsData = new long[net.minecraft.world.entity.MobCategory.values().length]; @@ -201,7 +201,7 @@ index e04d3479383cd480cf35ed7ac3c82e7f6fb69e28..ab1fc7ca0639f9e71933f623258bb8d1 + } + } + } -+ // Paper end - throttle failed spawn attempts ++ // Paper PR end - throttle failed spawn attempts + List list3 = tag.getList("entities").stream().flatMap(ListTag::compoundStream).toList(); List list4 = tag.getList("block_entities").stream().flatMap(ListTag::compoundStream).toList(); @@ -210,7 +210,7 @@ index e04d3479383cd480cf35ed7ac3c82e7f6fb69e28..ab1fc7ca0639f9e71933f623258bb8d1 list4, compoundOrEmpty , tag.get("ChunkBukkitValues") // CraftBukkit - ChunkBukkitValues -+ , failedSpawnAttemptsData // Paper - throttle failed spawn attempts ++ , failedSpawnAttemptsData // Paper PR - throttle failed spawn attempts ); } } @@ -218,14 +218,14 @@ index e04d3479383cd480cf35ed7ac3c82e7f6fb69e28..ab1fc7ca0639f9e71933f623258bb8d1 chunkAccess.addPackedPostProcess(this.postProcessingSections[i], i); } -+ // Paper start - throttle failed spawn attempts ++ // Paper PR start - throttle failed spawn attempts + long[] failedSpawnAttemptsData = this.failedSpawnAttempts; + if (failedSpawnAttemptsData != null) { + for (net.minecraft.world.entity.MobCategory mobCategory : net.minecraft.world.entity.MobCategory.values()) { + System.arraycopy(failedSpawnAttemptsData, 0, chunkAccess.failedSpawnAttempts, 0, failedSpawnAttemptsData.length); + } + } -+ // Paper end - throttle failed spawn attempts ++ // Paper PR end - throttle failed spawn attempts + if (chunkType == ChunkType.LEVELCHUNK) { return this.loadStarlightLightData(level, new ImposterProtoChunk((LevelChunk)chunkAccess, false)); // Paper - starlight @@ -234,7 +234,7 @@ index e04d3479383cd480cf35ed7ac3c82e7f6fb69e28..ab1fc7ca0639f9e71933f623258bb8d1 persistentDataContainer = chunk.persistentDataContainer.toTagCompound(); } // CraftBukkit end -+ final long[] failedSpawnAttemptsData = chunk.failedSpawnAttempts; // Paper - throttle failed spawn attempts ++ final long[] failedSpawnAttemptsData = chunk.failedSpawnAttempts; // Paper PR - throttle failed spawn attempts return new SerializableChunkData( level.registryAccess().lookupOrThrow(Registries.BIOME), pos, @@ -242,7 +242,7 @@ index e04d3479383cd480cf35ed7ac3c82e7f6fb69e28..ab1fc7ca0639f9e71933f623258bb8d1 list1, compoundTag , persistentDataContainer // CraftBukkit - persistentDataContainer -+ , failedSpawnAttemptsData // Paper - throttle failed spawn attempts ++ , failedSpawnAttemptsData // Paper PR - throttle failed spawn attempts ); } } @@ -250,7 +250,7 @@ index e04d3479383cd480cf35ed7ac3c82e7f6fb69e28..ab1fc7ca0639f9e71933f623258bb8d1 compoundTag.put("ChunkBukkitValues", this.persistentDataContainer); } // CraftBukkit end -+ // Paper start - throttle failed spawn attempts ++ // Paper PR start - throttle failed spawn attempts + CompoundTag failedSpawnAttemptsTag = new CompoundTag(); + long[] failedSpawnAttemptsData = this.failedSpawnAttempts; + if (failedSpawnAttemptsData != null) { @@ -264,7 +264,7 @@ index e04d3479383cd480cf35ed7ac3c82e7f6fb69e28..ab1fc7ca0639f9e71933f623258bb8d1 + if (!failedSpawnAttemptsTag.isEmpty()) { + compoundTag.put("Paper.FailedSpawnAttempts", failedSpawnAttemptsTag); + } -+ // Paper end - throttle failed spawn attempts ++ // Paper PR end - throttle failed spawn attempts // Paper start - starlight if (this.lightCorrect && !this.chunkStatus.isBefore(net.minecraft.world.level.chunk.status.ChunkStatus.LIGHT)) { // clobber vanilla value to force vanilla to relight @@ -273,7 +273,7 @@ index e04d3479383cd480cf35ed7ac3c82e7f6fb69e28..ab1fc7ca0639f9e71933f623258bb8d1 // Paper end - starlight - convert from record } + -+ // Paper start - throttle failed spawn attempts ++ // Paper PR start - throttle failed spawn attempts + // For plugin compatibility + public SerializableChunkData( + Registry biomeRegistry, @@ -317,5 +317,5 @@ index e04d3479383cd480cf35ed7ac3c82e7f6fb69e28..ab1fc7ca0639f9e71933f623258bb8d1 + persistentDataContainer, + null); + } -+ // Paper end - throttle failed spawn attempts ++ // Paper PR end - throttle failed spawn attempts } diff --git a/leaf-server/minecraft-patches/features/0234-PaperPR-Add-ticket-on-player-join-to-avoid-chunk-loa.patch b/leaf-server/minecraft-patches/features/0234-Paper-PR-Add-ticket-on-player-join-to-avoid-chunk-lo.patch similarity index 86% rename from leaf-server/minecraft-patches/features/0234-PaperPR-Add-ticket-on-player-join-to-avoid-chunk-loa.patch rename to leaf-server/minecraft-patches/features/0234-Paper-PR-Add-ticket-on-player-join-to-avoid-chunk-lo.patch index 499024dd..96253ff0 100644 --- a/leaf-server/minecraft-patches/features/0234-PaperPR-Add-ticket-on-player-join-to-avoid-chunk-loa.patch +++ b/leaf-server/minecraft-patches/features/0234-Paper-PR-Add-ticket-on-player-join-to-avoid-chunk-lo.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Fri, 13 Sep 2024 14:32:32 -0700 -Subject: [PATCH] PaperPR: Add ticket on player join to avoid chunk +Subject: [PATCH] Paper PR: Add ticket on player join to avoid chunk load-unload-load cycle Original license: GPLv3 @@ -15,32 +15,32 @@ The delay is currently set to 2 seconds, however, we may want to adjust this bef fixes Paper#9581 diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java b/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java -index 19b5e4856d471ebfa49335ed19ced767e57df771..bf33e4d17b076aaf68de4023dd4106efb0a37b7c 100644 +index 19b5e4856d471ebfa49335ed19ced767e57df771..9454a71d396128d3c55a0ba550d955af6237f9e4 100644 --- a/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java +++ b/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java @@ -48,6 +48,7 @@ public final class RegionizedPlayerChunkLoader { public static final TicketType PLAYER_TICKET = ChunkSystemTicketType.create("chunk_system:player_ticket", Long::compareTo); public static final TicketType PLAYER_TICKET_DELAYED = ChunkSystemTicketType.create("chunk_system:player_ticket_delayed", Long::compareTo, 1L); -+ public static final TicketType PLAYER_JOIN = ChunkSystemTicketType.create("chunk_system:player_join", (a, b) -> 0, 5 * 20); // Paper - Add ticket on player join to avoid chunk load-unload-load cycle ++ public static final TicketType PLAYER_JOIN = ChunkSystemTicketType.create("chunk_system:player_join", (a, b) -> 0, 5 * 20); // Paper PR - Add ticket on player join to avoid chunk load-unload-load cycle public static final int GENERATED_TICKET_LEVEL = ChunkHolderManager.FULL_LOADED_TICKET_LEVEL; public static final int LOADED_TICKET_LEVEL = ChunkTaskScheduler.getTicketLevel(ChunkStatus.EMPTY); diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java -index a478d3f7c8a90682decc5e853d7bbe6f896c02e4..bdc3ee44125ab070fb432a90cf1b02b009ba31ad 100644 +index d072ad9ae157bb44d344cd0b7e66a0d1ac6ee3dc..a3c851177709c382d53d78d0780177eacda625ca 100644 --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java @@ -441,6 +441,13 @@ public abstract class PlayerList { // this.broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player))); // CraftBukkit - replaced with loop below // Paper start - Fire PlayerJoinEvent when Player is actually ready; correctly register player BEFORE PlayerJoinEvent, so the entity is valid and doesn't require tick delay hacks player.supressTrackerForLogin = true; -+ // Paper start - Add ticket on player join to avoid chunk load-unload-load cycle ++ // Paper PR start - Add ticket on player join to avoid chunk load-unload-load cycle + serverLevel.moonrise$getChunkTaskScheduler().chunkHolderManager.addTicketAtLevel( + ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PLAYER_JOIN, + player.chunkPosition(), + ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.TICK_TICKET_LEVEL, + net.minecraft.util.Unit.INSTANCE); -+ // Paper end - Add ticket on player join to avoid chunk load-unload-load cycle ++ // Paper PR end - Add ticket on player join to avoid chunk load-unload-load cycle serverLevel.addNewPlayer(player); this.server.getCustomBossEvents().onPlayerConnect(player); // see commented out section below serverLevel.addPlayerJoin(player); // Paper end - Fire PlayerJoinEvent when Player is actually ready diff --git a/leaf-server/minecraft-patches/features/0256-optimize-mob-spawning.patch b/leaf-server/minecraft-patches/features/0256-optimize-mob-spawning.patch index 431763b7..cf8475a3 100644 --- a/leaf-server/minecraft-patches/features/0256-optimize-mob-spawning.patch +++ b/leaf-server/minecraft-patches/features/0256-optimize-mob-spawning.patch @@ -204,7 +204,7 @@ index eb5e1e67db2ee1bdbedfa244088fcb7a9356bae3..5e1f29af864df93856eabccde05a98f5 final net.minecraft.world.level.levelgen.BitRandomSource simpleRandom = this.simpleRandom; // Paper - optimise random ticking // Leaf - Faster random generator - upcasting ChunkPos pos = chunk.getPos(); diff --git a/net/minecraft/world/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java -index 81e176d17fb072f9ee531639abfe42134ae833a9..c3284577437412e1c3fb891bee2b0e20b52ccd59 100644 +index bb655318f49242858e2c25d5469705c0c314ed85..f0b78c6d89cd3010a0b8e9fbe760f615d7b8771e 100644 --- a/net/minecraft/world/level/NaturalSpawner.java +++ b/net/minecraft/world/level/NaturalSpawner.java @@ -68,6 +68,7 @@ public final class NaturalSpawner { @@ -290,7 +290,7 @@ index 81e176d17fb072f9ee531639abfe42134ae833a9..c3284577437412e1c3fb891bee2b0e20 } @@ -265,28 +328,68 @@ public final class NaturalSpawner { MobCategory category, ServerLevel level, ChunkAccess chunk, BlockPos pos, NaturalSpawner.SpawnPredicate filter, NaturalSpawner.AfterSpawnCallback callback, final int maxSpawns, final @Nullable Consumer trackEntity, final boolean nothing - // Paper end - throttle failed spawn attempts + // Paper PR end - throttle failed spawn attempts ) { + // Leaf start - optimize mob spawning + if (!(chunk instanceof LevelChunk levelChunk)) { @@ -305,12 +305,12 @@ index 81e176d17fb072f9ee531639abfe42134ae833a9..c3284577437412e1c3fb891bee2b0e20 + // Leaf start - optimize mob spawning + int posX = pos.getX(); + int posZ = pos.getZ(); - int i = 0; // Paper - throttle failed spawn attempts + int i = 0; // Paper PR - throttle failed spawn attempts - BlockState blockState = level.getBlockStateIfLoadedAndInBounds(pos); // Paper - don't load chunks for mob spawn + BlockState blockState = level.getWorldBorder().isWithinBounds(pos) ? (ChunkPos.asLong(pos) == levelChunk.getPos().longKey ? levelChunk.getBlockStateFinal(posX, y, posZ) : level.getBlockStateIfLoaded(pos)) : null; // Paper - don't load chunks for mob spawn // Leaf if (blockState != null && !blockState.isRedstoneConductor(chunk, pos)) { // Paper - don't load chunks for mob spawn BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(); - //int i = 0; // Paper - throttle failed spawn attempts - move up + //int i = 0; // Paper PR - throttle failed spawn attempts - move up + // 3 * (2 + 3 * [1, 4] * 4) + long rand = level.random.nextLong(); @@ -577,7 +577,7 @@ index db3b8a237d63255aa9ffd70c88a093002a6bd770..4a69f404eee00d8972e9501a76031d43 } diff --git a/net/minecraft/world/level/chunk/ChunkGenerator.java b/net/minecraft/world/level/chunk/ChunkGenerator.java -index 11c7c299d4affb9e78488590e7db939efe6e3dd9..a89c61aac1f1a35dc8c5943c0002661ce5fb76bf 100644 +index fb77cd58542c1a690cbeaa6ed3a4d657de6e619d..e0267e84c8fd2267b047590d712728e963d165f2 100644 --- a/net/minecraft/world/level/chunk/ChunkGenerator.java +++ b/net/minecraft/world/level/chunk/ChunkGenerator.java @@ -516,6 +516,35 @@ public abstract class ChunkGenerator { diff --git a/leaf-server/minecraft-patches/features/0270-Fix-Paper-config-fixClimbingBypassingCrammingRule.patch b/leaf-server/minecraft-patches/features/0270-Fix-Paper-config-fixClimbingBypassingCrammingRule.patch index 2eea5860..c27b3e53 100644 --- a/leaf-server/minecraft-patches/features/0270-Fix-Paper-config-fixClimbingBypassingCrammingRule.patch +++ b/leaf-server/minecraft-patches/features/0270-Fix-Paper-config-fixClimbingBypassingCrammingRule.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Fix Paper config fixClimbingBypassingCrammingRule Waiting for Paper#12793 diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index 5307e80f6e84df7a053e7132883d8338bbd751a0..d6be86981219f0fe0db15d36d9c85e9a56020373 100644 +index d745fd544263b364c1880220c076be41f269a8b7..a55b1534dc3c0745ff569f5c1e07dbeaba0fe57d 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java @@ -3850,7 +3850,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin @@ -14,12 +14,12 @@ index 5307e80f6e84df7a053e7132883d8338bbd751a0..d6be86981219f0fe0db15d36d9c85e9a final AABB box = this.getBoundingBox(); List pushableEntities = org.dreeam.leaf.config.modules.gameplay.OnlyPlayerPushable.enabled - ? getNearbyPushablePlayers(this, box, EntitySelector.pushableBy(this)) -+ ? getNearbyPushablePlayers(this, box, EntitySelector.pushable(this, this.level().paperConfig().collisions.fixClimbingBypassingCrammingRule)) // Leaf - Fix Paper config ++ ? getNearbyPushablePlayers(this, box, EntitySelector.pushable(this, this.level().paperConfig().collisions.fixClimbingBypassingCrammingRule)) // Leaf - Fix Paper config fixClimbingBypassingCrammingRule : this.level().getPushableEntities(this, box); // Leaf end - Only player pushable if (!pushableEntities.isEmpty()) { diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index 06b46b973df84b16842a28f73df75613d09e75c9..f1f2775b56caf4820e03aa87f895c6570b271187 100644 +index 72f2613c08f251bf32586d9fd039fdca80f6df02..2a1c89bb6712c97ad48b9f64c26f36afe8c811e4 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java @@ -1909,7 +1909,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl diff --git a/leaf-server/paper-patches/features/0049-PaperPR-Fix-MC-117075-Block-Entities-Unload-Lag-Spik.patch b/leaf-server/paper-patches/features/0049-Paper-PR-Fix-MC-117075-Block-Entities-Unload-Lag-Spi.patch similarity index 99% rename from leaf-server/paper-patches/features/0049-PaperPR-Fix-MC-117075-Block-Entities-Unload-Lag-Spik.patch rename to leaf-server/paper-patches/features/0049-Paper-PR-Fix-MC-117075-Block-Entities-Unload-Lag-Spi.patch index f3c9e339..81907ec4 100644 --- a/leaf-server/paper-patches/features/0049-PaperPR-Fix-MC-117075-Block-Entities-Unload-Lag-Spik.patch +++ b/leaf-server/paper-patches/features/0049-Paper-PR-Fix-MC-117075-Block-Entities-Unload-Lag-Spi.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: MrPowerGamerBR Date: Sun, 26 Nov 2023 13:02:16 -0300 -Subject: [PATCH] PaperPR: Fix MC-117075: Block Entities Unload Lag Spike +Subject: [PATCH] Paper PR: Fix MC-117075: Block Entities Unload Lag Spike Original license: GPLv3 Original project: https://github.com/SparklyPower/SparklyPaper diff --git a/leaf-server/paper-patches/features/0051-Paper-PR-Throttle-failed-spawn-attempts.patch b/leaf-server/paper-patches/features/0051-Paper-PR-Throttle-failed-spawn-attempts.patch index 36593b54..939bb4e4 100644 --- a/leaf-server/paper-patches/features/0051-Paper-PR-Throttle-failed-spawn-attempts.patch +++ b/leaf-server/paper-patches/features/0051-Paper-PR-Throttle-failed-spawn-attempts.patch @@ -31,14 +31,14 @@ 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 8e65586182bd586c95b8c4873fab6d6ff5975243..ed687b0ab589fd2ddb8bf77f42ba42cf8b1c2ea7 100644 +index a457584fcdc062d16414973228f0f0ef387dfb6e..70577f480d2acc3724ab8ab296edc952254c5dac 100644 --- a/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java @@ -183,6 +183,17 @@ public class WorldConfiguration extends ConfigurationPart { @MergeMap public Reference2IntMap ticksPerSpawn = Util.make(new Reference2IntOpenHashMap<>(NaturalSpawner.SPAWNING_CATEGORIES.length), map -> Arrays.stream(NaturalSpawner.SPAWNING_CATEGORIES).forEach(mobCategory -> map.put(mobCategory, -1))); -+ // Paper start - throttle failed spawn attempts ++ // Paper PR start - throttle failed spawn attempts + public SpawningThrottle spawningThrottle; + + public class SpawningThrottle extends ConfigurationPart { @@ -47,7 +47,7 @@ index 8e65586182bd586c95b8c4873fab6d6ff5975243..ed687b0ab589fd2ddb8bf77f42ba42cf + @MergeMap + public Reference2IntMap throttledTicksPerSpawn = Util.make(new Reference2IntOpenHashMap<>(NaturalSpawner.SPAWNING_CATEGORIES.length), map -> Arrays.stream(NaturalSpawner.SPAWNING_CATEGORIES).forEach(mobCategory -> map.put(mobCategory, -1))); + } -+ // Paper end - throttle failed spawn attempts ++ // Paper PR end - throttle failed spawn attempts + @ConfigSerializable public record DespawnRangePair(@Required DespawnRange hard, @Required DespawnRange soft) {