From 3d54e47c5e26cec03566e5db9e8b042f97b1936c Mon Sep 17 00:00:00 2001 From: Helvetica Volubi Date: Mon, 11 May 2026 11:12:58 +0800 Subject: [PATCH] more patches - stage 16/44 --- .../0013-Leaves-Old-raid-behavior.patch | 216 ------------------ ...by-task-id-in-FoliaGlobalRegionSched.patch | 21 ++ ...14-Add-config-to-enable-tick-command.patch | 59 +++-- .../0015-Leaves-Old-raid-behavior.patch | 177 ++++++++++++++ ...x-for-Raid-Revert-and-Cross-Region-D.patch | 30 +-- ...by-task-id-in-FoliaGlobalRegionSched.patch | 11 +- .../modules/experiment/CommandConfig.java | 8 +- .../modules/function/OldFeatureConfig.java | 8 +- 8 files changed, 266 insertions(+), 264 deletions(-) delete mode 100644 1todos/server/minecraft-patches/features/0013-Leaves-Old-raid-behavior.patch create mode 100644 lophine-api/paper-patches/features/0002-Add-cancel-task-by-task-id-in-FoliaGlobalRegionSched.patch rename 1todos/server/minecraft-patches/features/0007-Add-config-to-enable-tick-command.patch => lophine-server/minecraft-patches/features/0014-Add-config-to-enable-tick-command.patch (77%) create mode 100644 lophine-server/minecraft-patches/features/0015-Leaves-Old-raid-behavior.patch rename 1todos/server/minecraft-patches/features/0017-Compatibility-fix-for-Raid-Revert-and-Cross-Region-D.patch => lophine-server/minecraft-patches/features/0016-Compatibility-fix-for-Raid-Revert-and-Cross-Region-D.patch (50%) diff --git a/1todos/server/minecraft-patches/features/0013-Leaves-Old-raid-behavior.patch b/1todos/server/minecraft-patches/features/0013-Leaves-Old-raid-behavior.patch deleted file mode 100644 index 3347994..0000000 --- a/1todos/server/minecraft-patches/features/0013-Leaves-Old-raid-behavior.patch +++ /dev/null @@ -1,216 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Helvetica Volubi -Date: Fri, 11 Apr 2025 16:53:57 +0800 -Subject: [PATCH] Leaves: Old raid behavior - -Co-authored by: huanli233 <392352840@qq.com> -As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/79d9ef74c2684eb49060f07e1ab31c827326c9a5/leaves-server/minecraft-patches/features/0106-Old-raid-behavior.patch) -Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html) - -diff --git a/net/minecraft/world/effect/BadOmenMobEffect.java b/net/minecraft/world/effect/BadOmenMobEffect.java -index 80f17f33f670018240c854df589cf90cdeab6e70..c9af615ff9120c07787f436dbb6024e54e3a498b 100644 ---- a/net/minecraft/world/effect/BadOmenMobEffect.java -+++ b/net/minecraft/world/effect/BadOmenMobEffect.java -@@ -22,6 +22,11 @@ class BadOmenMobEffect extends MobEffect { - && !serverPlayer.isSpectator() - && level.getDifficulty() != Difficulty.PEACEFUL - && level.isVillage(serverPlayer.blockPosition())) { -+ // Leaves start - Revert raid changes -+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior) { -+ return level.getRaids().createOrExtendRaid(serverPlayer, serverPlayer.blockPosition()) == null; -+ } -+ // Leaves end - Revert raid changes - Raid raidAt = level.getRaidAt(serverPlayer.blockPosition()); - if (raidAt == null || raidAt.getRaidOmenLevel() < raidAt.getMaxRaidOmenLevel()) { - serverPlayer.addEffect(new MobEffectInstance(MobEffects.RAID_OMEN, 600, amplifier)); -diff --git a/net/minecraft/world/entity/raid/Raid.java b/net/minecraft/world/entity/raid/Raid.java -index dcdd6f230ff153a7b58d13b963d32376b1905b72..be9c78f2cf121e8ae55c1b18685877637a25ec80 100644 ---- a/net/minecraft/world/entity/raid/Raid.java -+++ b/net/minecraft/world/entity/raid/Raid.java -@@ -264,7 +264,7 @@ public class Raid { - } - - public boolean absorbRaidOmen(ServerPlayer player) { -- MobEffectInstance effect = player.getEffect(MobEffects.RAID_OMEN); -+ MobEffectInstance effect = player.getEffect(fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior ? MobEffects.BAD_OMEN : MobEffects.RAID_OMEN); // Leaves - old Raid Behavior - if (effect == null) { - return false; - } else { -@@ -341,7 +341,13 @@ public class Raid { - } - - if (flag1) { -- this.waveSpawnPos = this.getValidSpawnPos(level); -+ // Leaves Start - old FindSpawnPosition -+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior) { -+ this.waveSpawnPos = this.preCalcRavagerSpawnLocation(level, this.raidCooldownTicks < 100 ? 1 : 0); -+ } else { -+ this.waveSpawnPos = this.getValidSpawnPos(level); -+ } -+ // Leaves End - old FindSpawnPosition - } - - if (this.raidCooldownTicks == 300 || this.raidCooldownTicks % 20 == 0) { -@@ -396,7 +402,14 @@ public class Raid { - int i = 0; - - while (this.shouldSpawnGroup()) { -- BlockPos blockPos = this.waveSpawnPos.orElseGet(() -> this.findRandomSpawnPos(level, 20)); -+ // Leaves Start - old FindSpawnPosition -+ BlockPos blockPos; -+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior) { -+ blockPos = this.getRavagerSpawnLocation(level, i, 20); -+ } else { -+ blockPos = this.waveSpawnPos.orElseGet(() -> this.findRandomSpawnPos(level, 20)); -+ } -+ // Leaves End - old FindSpawnPosition - if (blockPos != null) { - this.started = true; - this.spawnGroup(level, blockPos); -@@ -408,7 +421,7 @@ public class Raid { - i++; - } - -- if (i > 5) { -+ if (i > (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior ? 3 : 5)) { // Leaves - old FindSpawnPosition - org.bukkit.craftbukkit.event.CraftEventFactory.callRaidStopEvent(level, this, org.bukkit.event.raid.RaidStopEvent.Reason.UNSPAWNABLE); // CraftBukkit - this.stop(); - break; -@@ -702,7 +715,7 @@ public class Raid { - int i2 = this.center.getX() + Mth.floor(Mth.cos(f2) * 32.0F * f) + level.random.nextInt(3) * Mth.floor(f); - int i3 = this.center.getZ() + Mth.floor(Mth.sin(f2) * 32.0F * f) + level.random.nextInt(3) * Mth.floor(f); - int height = level.getHeight(Heightmap.Types.WORLD_SURFACE, i2, i3); -- if (Mth.abs(height - this.center.getY()) <= 96) { -+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior || Mth.abs(height - this.center.getY()) <= 96) { // Leaves - skippable - mutableBlockPos.set(i2, height, i3); - if (!level.isVillage(mutableBlockPos) || i <= 7) { - int i4 = 10; -@@ -721,6 +734,36 @@ public class Raid { - return null; - } - -+ // Leaves Start - old FindSpawnPosition -+ @Nullable -+ private BlockPos findRandomSpawnPos(ServerLevel level, int n, int n2) { -+ int n3 = 2 - n; -+ BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(); -+ SpawnPlacementType spawnPlacementType = SpawnPlacements.getPlacementType(EntityType.RAVAGER); -+ for (int i = 0; i < n2; ++i) { -+ float f = level.random.nextFloat() * ((float)Math.PI * 2); -+ int n4 = this.center.getX() + Mth.floor(Mth.cos(f) * 32.0f * (float)n3) + level.random.nextInt(5); -+ int n5 = this.center.getZ() + Mth.floor(Mth.sin(f) * 32.0f * (float)n3) + level.random.nextInt(5); -+ int n6 = level.getHeight(Heightmap.Types.WORLD_SURFACE, n4, n5); -+ mutableBlockPos.set(n4, n6, n5); -+ if (level.isVillage(mutableBlockPos) && n < 2) continue; -+ if (!level.hasChunksAt(mutableBlockPos.getX() - 10, mutableBlockPos.getZ() - 10, mutableBlockPos.getX() + 10, mutableBlockPos.getZ() + 10) || !level.isPositionEntityTicking(mutableBlockPos) || !spawnPlacementType.isSpawnPositionOk(level, mutableBlockPos, EntityType.RAVAGER) && (!level.getBlockState((BlockPos)mutableBlockPos.below()).is(Blocks.SNOW) || !level.getBlockState(mutableBlockPos).isAir())) continue; -+ return mutableBlockPos; -+ } -+ return null; -+ } -+ -+ private Optional getValidSpawnPos(ServerLevel level, int n) { -+ for (int i = 0; i < 3; ++i) { -+ BlockPos blockPos = this.findRandomSpawnPos(level, n, 1); -+ if (blockPos == null) continue; -+ return Optional.of(blockPos); -+ } -+ return Optional.empty(); -+ } -+ // Leaves End - old FindSpawnPosition -+ -+ - private boolean addWaveMob(ServerLevel level, int wave, Raider raider) { - // Folia start - make raids thread-safe - if (!this.ownsRaid(level)) { -@@ -883,4 +926,43 @@ public class Raid { - this.spawnsPerWaveBeforeBonus = spawnsPerWaveBeforeBonus; - } - } -+ -+ // Leaves start - old FindSpawnPosition -+ private BlockPos getRavagerSpawnLocation(ServerLevel serverWorld, int proximity, int tries) { -+ int i = proximity == 0 ? 2 : 2 - proximity; -+ BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos(); -+ SpawnPlacementType spawnLocation = SpawnPlacements.getPlacementType(EntityType.RAVAGER); -+ -+ for (int j = 0; j < tries; j++) { -+ float f = serverWorld.random.nextFloat() * (float) (Math.PI * 2); -+ int k = this.center.getX() + Mth.floor(Mth.cos(f) * 32.0F * (float) i + serverWorld.random.nextInt(5)); -+ int l = this.center.getZ() + Mth.floor(Mth.sin(f) * 32.0F * (float) i + serverWorld.random.nextInt(5)); -+ int m = serverWorld.getHeight(Heightmap.Types.WORLD_SURFACE, k, l); -+ mutable.set(k, m, l); -+ -+ if (serverWorld.isVillage(mutable) && proximity < 2) { -+ continue; -+ } -+ if (serverWorld.hasChunksAt(mutable.getX() - 10, mutable.getZ() - 10, mutable.getX() + 10, mutable.getZ() + 10) -+ && serverWorld.isPositionEntityTicking(mutable) -+ && (spawnLocation.isSpawnPositionOk(serverWorld, mutable, EntityType.RAVAGER) -+ || serverWorld.getBlockState(mutable.below()).is(Blocks.SNOW) -+ && serverWorld.getBlockState(mutable).isAir()) -+ ) { -+ return mutable; -+ } -+ } -+ return null; -+ } -+ -+ private Optional preCalcRavagerSpawnLocation(ServerLevel serverWorld, int proximity) { -+ for (int i = 0; i < 3; i++) { -+ BlockPos blockPos = this.getRavagerSpawnLocation(serverWorld, proximity, 1); -+ if (blockPos != null) { -+ return Optional.of(blockPos); -+ } -+ } -+ return Optional.empty(); -+ } -+ // Leaves end - old FindSpawnPosition - } -diff --git a/net/minecraft/world/entity/raid/Raider.java b/net/minecraft/world/entity/raid/Raider.java -index 5e8245e6dd8a07ece83dd1bc20e351a92044e7a0..2b7894a4104d4cb237746a3e66d4368b6f8f3c1e 100644 ---- a/net/minecraft/world/entity/raid/Raider.java -+++ b/net/minecraft/world/entity/raid/Raider.java -@@ -127,6 +127,43 @@ public abstract class Raider extends PatrollingMonster { - - currentRaid.removeFromRaid(serverLevel, this, false); - } -+ -+ // Leaves start - Revert raid changes -+ if (this.level() instanceof ServerLevel) { -+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior && !this.hasRaid()) { -+ ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD); -+ net.minecraft.world.entity.player.Player entityhuman = null; -+ if (entity instanceof net.minecraft.world.entity.player.Player player) { -+ entityhuman = player; -+ } else if (entity instanceof net.minecraft.world.entity.animal.wolf.Wolf wolf) { -+ LivingEntity entityliving = wolf.getOwner(); -+ if (wolf.isTame() && entityliving instanceof net.minecraft.world.entity.player.Player player) { -+ entityhuman = player; -+ } -+ } -+ -+ if (entityhuman != null && !itemstack.isEmpty() && this.isCaptain()) { -+ net.minecraft.world.effect.MobEffectInstance mobeffect = entityhuman.getEffect(net.minecraft.world.effect.MobEffects.BAD_OMEN); -+ int i = 1; -+ -+ if (mobeffect != null) { -+ i += mobeffect.getAmplifier(); -+ entityhuman.removeEffectNoUpdate(net.minecraft.world.effect.MobEffects.BAD_OMEN); -+ } else { -+ --i; -+ } -+ -+ i = net.minecraft.util.Mth.clamp(i, 0, 4); -+ net.minecraft.world.effect.MobEffectInstance mobeffect1 = new net.minecraft.world.effect.MobEffectInstance(net.minecraft.world.effect.MobEffects.BAD_OMEN, 120000, i, false, false, true); -+ -+ if (serverLevel.getGameRules().get(net.minecraft.world.level.gamerules.GameRules.RAIDS)) { -+ entityhuman.addEffect(mobeffect1, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.PATROL_CAPTAIN); // CraftBukkit -+ } -+ this.setPatrolLeader(false); -+ } -+ } -+ } -+ // Leaves end - Revert raid changes - } - - super.die(damageSource); diff --git a/lophine-api/paper-patches/features/0002-Add-cancel-task-by-task-id-in-FoliaGlobalRegionSched.patch b/lophine-api/paper-patches/features/0002-Add-cancel-task-by-task-id-in-FoliaGlobalRegionSched.patch new file mode 100644 index 0000000..8d87215 --- /dev/null +++ b/lophine-api/paper-patches/features/0002-Add-cancel-task-by-task-id-in-FoliaGlobalRegionSched.patch @@ -0,0 +1,21 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Helvetica Volubi +Date: Mon, 11 May 2026 10:47:42 +0800 +Subject: [PATCH] Add cancel task by task id in FoliaGlobalRegionScheduler + + +diff --git a/src/main/java/io/papermc/paper/threadedregions/scheduler/GlobalRegionScheduler.java b/src/main/java/io/papermc/paper/threadedregions/scheduler/GlobalRegionScheduler.java +index 57455aca80ecc458b96b44c086cea94ddcecae47..763d27d303b9a588526445c453e07f5886534e82 100644 +--- a/src/main/java/io/papermc/paper/threadedregions/scheduler/GlobalRegionScheduler.java ++++ b/src/main/java/io/papermc/paper/threadedregions/scheduler/GlobalRegionScheduler.java +@@ -55,4 +55,10 @@ public interface GlobalRegionScheduler { + * @param plugin Specified plugin. + */ + void cancelTasks(@NotNull Plugin plugin); ++ ++ /** ++ * Attempts to cancel the specified task. ++ * @param taskId The task id. ++ */ ++ void cancelTask(final int taskId); + } diff --git a/1todos/server/minecraft-patches/features/0007-Add-config-to-enable-tick-command.patch b/lophine-server/minecraft-patches/features/0014-Add-config-to-enable-tick-command.patch similarity index 77% rename from 1todos/server/minecraft-patches/features/0007-Add-config-to-enable-tick-command.patch rename to lophine-server/minecraft-patches/features/0014-Add-config-to-enable-tick-command.patch index 5cfb757..94b9cd6 100644 --- a/1todos/server/minecraft-patches/features/0007-Add-config-to-enable-tick-command.patch +++ b/lophine-server/minecraft-patches/features/0014-Add-config-to-enable-tick-command.patch @@ -3,12 +3,13 @@ From: Helvetica Volubi Date: Wed, 21 Jan 2026 21:28:21 +0800 Subject: [PATCH] Add config to enable tick command +Because of some bug, we disabled sprint command diff --git a/io/papermc/paper/threadedregions/RegionizedServer.java b/io/papermc/paper/threadedregions/RegionizedServer.java -index 7748e9ac04fbd3f5259d92fc908d90889cba86c8..80b5d151e0dd6fa44794187875b4b80519839d81 100644 +index fc6402dd0a47f5b2792aa8a21703bfee18dd2388..96423a1a429f4fb1c975ad10726fe0e1ff70a6ad 100644 --- a/io/papermc/paper/threadedregions/RegionizedServer.java +++ b/io/papermc/paper/threadedregions/RegionizedServer.java -@@ -332,6 +332,11 @@ public final class RegionizedServer { +@@ -338,6 +338,11 @@ public final class RegionizedServer { this.randomWalk(); */ ++this.tickCount; @@ -20,7 +21,7 @@ index 7748e9ac04fbd3f5259d92fc908d90889cba86c8..80b5d151e0dd6fa44794187875b4b805 // expire invalid click command callbacks io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.ADVENTURE_CLICK_MANAGER.handleQueue((int)this.tickCount); // Paper // Folia - region threading - moved to global tick io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.DIALOG_CLICK_MANAGER.handleQueue((int)this.tickCount); // Paper // Folia - region threading - moved to global tick -@@ -357,6 +362,13 @@ public final class RegionizedServer { +@@ -366,6 +371,13 @@ public final class RegionizedServer { this.globalTick(world, tickCount); } @@ -34,17 +35,17 @@ index 7748e9ac04fbd3f5259d92fc908d90889cba86c8..80b5d151e0dd6fa44794187875b4b805 // tick connections this.tickConnections(); -@@ -492,7 +504,7 @@ public final class RegionizedServer { +@@ -513,7 +525,7 @@ public final class RegionizedServer { } private void tickTime(final ServerLevel world, final long tickCount) { - if (world.tickTime) { + if ((!fun.bm.lophine.config.modules.experiment.CommandConfig.tick || world.tickRateManager().runsNormally()) && world.tickTime) { // Luminol - Add a config to enable tick command - if (world.getGameRules().get(GameRules.ADVANCE_TIME)) { - world.setDayTime(world.levelData.getDayTime() + tickCount); - } + world.serverLevelData.setGameTime(world.serverLevelData.getGameTime() + tickCount); + } + } diff --git a/io/papermc/paper/threadedregions/TickRegionScheduler.java b/io/papermc/paper/threadedregions/TickRegionScheduler.java -index 0f4e8ee9438135e24e0f61a1390c59573b9e9c3f..65699d2ad66c686a8b7d1b951787ddd766800a94 100644 +index 8b09834ec36f62a73e388124129afbdfa47e6c25..ce0ace6a0c6b11f124b601d97491fee102b36554 100644 --- a/io/papermc/paper/threadedregions/TickRegionScheduler.java +++ b/io/papermc/paper/threadedregions/TickRegionScheduler.java @@ -40,8 +40,8 @@ public final class TickRegionScheduler { @@ -58,7 +59,7 @@ index 0f4e8ee9438135e24e0f61a1390c59573b9e9c3f..65699d2ad66c686a8b7d1b951787ddd7 // Folia start - watchdog public static final FoliaWatchdogThread WATCHDOG_THREAD = new FoliaWatchdogThread(); static { -@@ -448,8 +448,23 @@ public final class TickRegionScheduler { +@@ -525,8 +525,23 @@ public final class TickRegionScheduler { final long cpuStart = MEASURE_CPU_TIME ? THREAD_MX_BEAN.getCurrentThreadCpuTime() : 0L; final long tickStart = System.nanoTime(); @@ -84,7 +85,7 @@ index 0f4e8ee9438135e24e0f61a1390c59573b9e9c3f..65699d2ad66c686a8b7d1b951787ddd7 if (!this.tryMarkTicking()) { if (!this.cancelled.get()) { -@@ -498,6 +513,11 @@ public final class TickRegionScheduler { +@@ -575,6 +590,11 @@ public final class TickRegionScheduler { try { // next start isn't updated until the end of this tick this.tickRegion(tickCount, tickStart, scheduledEnd); @@ -97,10 +98,10 @@ index 0f4e8ee9438135e24e0f61a1390c59573b9e9c3f..65699d2ad66c686a8b7d1b951787ddd7 this.scheduler.regionFailed(this, false, thr); // regionFailed will schedule a shutdown, so we should avoid letting this region tick further diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java -index 91e2f3e9e85622adbd3799473634e716383bbe94..21466c225db02a5be74bf60b5ea831c5bea8a7e8 100644 +index f54f6047f326189329e11338b17105f5555dde12..6f3143deb9e5ff17fae5920b0a4ba34e3d9545c4 100644 --- a/net/minecraft/commands/Commands.java +++ b/net/minecraft/commands/Commands.java -@@ -262,7 +262,11 @@ public class Commands { +@@ -265,7 +265,11 @@ public class Commands { TeleportCommand.register(this.dispatcher); TellRawCommand.register(this.dispatcher, context); //TestCommand.register(this.dispatcher, context); // Folia - region threading @@ -110,14 +111,14 @@ index 91e2f3e9e85622adbd3799473634e716383bbe94..21466c225db02a5be74bf60b5ea831c5 + TickCommand.register(this.dispatcher); // Folia - region threading - TODO later + } + // Luminol end - Add a config to enable tick command - TimeCommand.register(this.dispatcher); + TimeCommand.register(this.dispatcher, context); TitleCommand.register(this.dispatcher, context); //TriggerCommand.register(this.dispatcher); // Folia - region threading - TODO later diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index 25324d81bbe876dbe47b33bd5749b72e4283bf80..504f21c5f1e3101e7164b97059aecce630d18cee 100644 +index 82315368d5580563fc77548f22a65d04ec73b622..8dcd684189d953aabddc4f62a3ecc5807c949ce6 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -270,7 +270,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0L) { this.sprintTickStartTime = System.nanoTime(); @@ -139,7 +140,7 @@ index 4257c47d33e3773fac766817138cc21c55d9ab76..95f6b1cbd5e33151c326689bc72292ff return true; } else { this.finishTickSprint(); -@@ -114,6 +114,12 @@ public class ServerTickRateManager extends TickRateManager { +@@ -118,6 +118,12 @@ public class ServerTickRateManager extends TickRateManager { } } @@ -153,7 +154,7 @@ index 4257c47d33e3773fac766817138cc21c55d9ab76..95f6b1cbd5e33151c326689bc72292ff this.sprintTimeSpend = this.sprintTimeSpend + (System.nanoTime() - this.sprintTickStartTime); } diff --git a/net/minecraft/server/commands/TickCommand.java b/net/minecraft/server/commands/TickCommand.java -index 14c46d585fc9bfbf9a57340508ea2e5076ac39d6..99096896a4512eed579b234e7fa0c6e9c3e8c246 100644 +index 2dd0a8f2399a83b90356fcf0777bd1aec8eef5a9..c3dcfb633877ef230ab48a455ad4f5a1d601ba48 100644 --- a/net/minecraft/server/commands/TickCommand.java +++ b/net/minecraft/server/commands/TickCommand.java @@ -14,7 +14,7 @@ import net.minecraft.server.ServerTickRateManager; @@ -164,4 +165,22 @@ index 14c46d585fc9bfbf9a57340508ea2e5076ac39d6..99096896a4512eed579b234e7fa0c6e9 + public static final float MAX_TICKRATE = 10000.0F; // Luminol - Add tick command support private static final String DEFAULT_TICKRATE = String.valueOf(20); - public static void register(CommandDispatcher dispatcher) { + public static void register(final CommandDispatcher dispatcher) { +@@ -40,7 +40,7 @@ public class TickCommand { + .executes(c -> step(c.getSource(), IntegerArgumentType.getInteger(c, "time"))) + ) + ) +- .then( ++/* .then( + Commands.literal("sprint") + .then(Commands.literal("stop").executes(c -> stopSprinting(c.getSource()))) + .then( +@@ -48,7 +48,7 @@ public class TickCommand { + .suggests((c, b) -> SharedSuggestionProvider.suggest(new String[]{"60s", "1d", "3d"}, b)) + .executes(c -> sprint(c.getSource(), IntegerArgumentType.getInteger(c, "time"))) + ) +- ) ++ )*/ + .then(Commands.literal("unfreeze").executes(c -> setFreeze(c.getSource(), false))) + .then(Commands.literal("freeze").executes(c -> setFreeze(c.getSource(), true))) + ); diff --git a/lophine-server/minecraft-patches/features/0015-Leaves-Old-raid-behavior.patch b/lophine-server/minecraft-patches/features/0015-Leaves-Old-raid-behavior.patch new file mode 100644 index 0000000..e047027 --- /dev/null +++ b/lophine-server/minecraft-patches/features/0015-Leaves-Old-raid-behavior.patch @@ -0,0 +1,177 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Helvetica Volubi +Date: Fri, 11 Apr 2025 16:53:57 +0800 +Subject: [PATCH] Leaves: Old raid behavior + +Co-authored by: huanli233 <392352840@qq.com> +As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/bda7e406b995290234e33283a181e33467ceda38/leaves-server/minecraft-patches/features/0114-Old-raid-behavior.patch) +Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html) + +diff --git a/net/minecraft/world/effect/BadOmenMobEffect.java b/net/minecraft/world/effect/BadOmenMobEffect.java +index f58b10c7dec0d2b7dc2b3d1198539b74d13038f3..0a838a2015526dde2cb8d9006a71610e0bf5e9dc 100644 +--- a/net/minecraft/world/effect/BadOmenMobEffect.java ++++ b/net/minecraft/world/effect/BadOmenMobEffect.java +@@ -22,6 +22,11 @@ class BadOmenMobEffect extends MobEffect { + && !player.isSpectator() + && level.getDifficulty() != Difficulty.PEACEFUL + && level.isVillage(player.blockPosition())) { ++ // Leaves start - Revert raid changes ++ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior) { ++ return level.getRaids().createOrExtendRaid(player, player.blockPosition()) == null; ++ } ++ // Leaves end - Revert raid changes + Raid raid = level.getRaidAt(player.blockPosition()); + if (raid == null || raid.getRaidOmenLevel() < raid.getMaxRaidOmenLevel()) { + player.addEffect(new MobEffectInstance(MobEffects.RAID_OMEN, 600, amplification)); +diff --git a/net/minecraft/world/entity/raid/Raid.java b/net/minecraft/world/entity/raid/Raid.java +index 24cc4a15731edcb701596fe7051e188637457e37..5440dc0fb8bccabb65fd9681ab368ef5028e2ca9 100644 +--- a/net/minecraft/world/entity/raid/Raid.java ++++ b/net/minecraft/world/entity/raid/Raid.java +@@ -268,7 +268,7 @@ public class Raid { + } + + public boolean absorbRaidOmen(final ServerPlayer player) { +- MobEffectInstance effect = player.getEffect(MobEffects.RAID_OMEN); ++ MobEffectInstance effect = player.getEffect(fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior ? MobEffects.BAD_OMEN : MobEffects.RAID_OMEN); // Leaves - old Raid Behavior + if (effect == null) { + return false; + } else { +@@ -345,7 +345,13 @@ public class Raid { + } + + if (shouldTryToFindSpawnPos) { +- this.waveSpawnPos = this.getValidSpawnPos(level); ++ // Leaves Start - old FindSpawnPosition ++ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior) { ++ this.waveSpawnPos = this.preCalcRavagerSpawnLocation(level, this.raidCooldownTicks < 100 ? 1 : 0); ++ } else { ++ this.waveSpawnPos = this.getValidSpawnPos(level); ++ } ++ // Leaves End - old FindSpawnPosition + } + + if (this.raidCooldownTicks == 300 || this.raidCooldownTicks % 20 == 0) { +@@ -400,7 +406,14 @@ public class Raid { + int attempt = 0; + + while (this.shouldSpawnGroup()) { +- BlockPos spawnPos = this.waveSpawnPos.orElseGet(() -> this.findRandomSpawnPos(level, 20)); ++ // Leaves Start - old FindSpawnPosition ++ BlockPos spawnPos; ++ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior) { ++ spawnPos = this.getRavagerSpawnLocation(level, attempt, 20); ++ } else { ++ spawnPos = this.waveSpawnPos.orElseGet(() -> this.findRandomSpawnPos(level, 20)); ++ } ++ // Leaves End - old FindSpawnPosition + if (spawnPos != null) { + this.started = true; + this.spawnGroup(level, spawnPos); +@@ -412,7 +425,7 @@ public class Raid { + attempt++; + } + +- if (attempt > 5) { ++ if (attempt > (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior ? 3 : 5)) { // Leaves - old FindSpawnPosition + org.bukkit.craftbukkit.event.CraftEventFactory.callRaidStopEvent(level, this, org.bukkit.event.raid.RaidStopEvent.Reason.UNSPAWNABLE); // CraftBukkit + this.stop(); + break; +@@ -716,7 +729,7 @@ public class Raid { + int spawnX = this.center.getX() + Mth.floor(Mth.cos(angle) * 32.0F * howFar) + this.random.nextInt(3) * Mth.floor(howFar); + int spawnZ = this.center.getZ() + Mth.floor(Mth.sin(angle) * 32.0F * howFar) + this.random.nextInt(3) * Mth.floor(howFar); + int spawnY = level.getHeight(Heightmap.Types.WORLD_SURFACE, spawnX, spawnZ); +- if (Mth.abs(spawnY - this.center.getY()) <= 96) { ++ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior || Mth.abs(spawnY - this.center.getY()) <= 96) { // Leaves - skippable + spawnPos.set(spawnX, spawnY, spawnZ); + if (!level.isVillage(spawnPos) || secondsRemaining <= 7) { + int delta = 10; +@@ -899,4 +912,42 @@ public class Raid { + this.spawnsPerWaveBeforeBonus = spawnsPerWaveBeforeBonus; + } + } ++ ++ // Leaves start - old FindSpawnPosition ++ @Nullable ++ private BlockPos getRavagerSpawnLocation(final ServerLevel serverWorld, final int proximity, final int tries) { ++ int i = proximity == 0 ? 2 : 2 - proximity; ++ BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos(); ++ net.minecraft.world.entity.SpawnPlacementType spawnLocation = net.minecraft.world.entity.SpawnPlacements.getPlacementType(EntityType.RAVAGER); ++ for (int j = 0; j < tries; j++) { ++ float f = serverWorld.getRandom().nextFloat() * (float) (Math.PI * 2); ++ int k = this.center.getX() + Mth.floor(Mth.cos(f) * 32.0F * (float) i + serverWorld.getRandom().nextInt(5)); ++ int l = this.center.getZ() + Mth.floor(Mth.sin(f) * 32.0F * (float) i + serverWorld.getRandom().nextInt(5)); ++ int m = serverWorld.getHeight(Heightmap.Types.WORLD_SURFACE, k, l); ++ mutable.set(k, m, l); ++ if (serverWorld.isVillage(mutable) && proximity < 2) { ++ continue; ++ } ++ if (serverWorld.hasChunksAt(mutable.getX() - 10, mutable.getZ() - 10, mutable.getX() + 10, mutable.getZ() + 10) ++ && serverWorld.isPositionEntityTicking(mutable) ++ && (spawnLocation.isSpawnPositionOk(serverWorld, mutable, EntityType.RAVAGER) ++ || serverWorld.getBlockState(mutable.below()).is(net.minecraft.world.level.block.Blocks.SNOW) ++ && serverWorld.getBlockState(mutable).isAir()) ++ ) { ++ return mutable.immutable(); ++ } ++ } ++ return null; ++ } ++ ++ private Optional preCalcRavagerSpawnLocation(final ServerLevel serverWorld, final int proximity) { ++ for (int i = 0; i < 3; i++) { ++ BlockPos blockPos = this.getRavagerSpawnLocation(serverWorld, proximity, 1); ++ if (blockPos != null) { ++ return Optional.of(blockPos); ++ } ++ } ++ return Optional.empty(); ++ } ++ // Leaves end - old FindSpawnPosition + } +diff --git a/net/minecraft/world/entity/raid/Raider.java b/net/minecraft/world/entity/raid/Raider.java +index bc2edc48ddefaab9022029f1a913a40b72e06024..1a51da9171c13711e106731c360051d183a40893 100644 +--- a/net/minecraft/world/entity/raid/Raider.java ++++ b/net/minecraft/world/entity/raid/Raider.java +@@ -128,6 +128,42 @@ public abstract class Raider extends PatrollingMonster { + + raidWhenKilled.removeFromRaid(serverLevel, this, false); + } ++ ++ // Leaves start - Revert raid changes ++ Entity killerEntity = source.getEntity(); ++ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior && !this.hasActiveRaid()) { ++ ItemStack itemstack = this.getItemBySlot(net.minecraft.world.entity.EquipmentSlot.HEAD); ++ net.minecraft.world.entity.player.Player entityhuman = null; ++ if (killerEntity instanceof net.minecraft.world.entity.player.Player player) { ++ entityhuman = player; ++ } else if (killerEntity instanceof net.minecraft.world.entity.animal.wolf.Wolf wolf) { ++ LivingEntity entityliving = wolf.getOwner(); ++ if (wolf.isTame() && entityliving instanceof net.minecraft.world.entity.player.Player player) { ++ entityhuman = player; ++ } ++ } ++ ++ if (entityhuman != null && !itemstack.isEmpty() && this.isPatrolLeader()) { ++ net.minecraft.world.effect.MobEffectInstance mobeffect = entityhuman.getEffect(net.minecraft.world.effect.MobEffects.BAD_OMEN); ++ int amp = 1; ++ ++ if (mobeffect != null) { ++ amp += mobeffect.getAmplifier(); ++ entityhuman.removeEffectNoUpdate(net.minecraft.world.effect.MobEffects.BAD_OMEN); ++ } else { ++ --amp; ++ } ++ ++ amp = net.minecraft.util.Mth.clamp(amp, 0, 4); ++ net.minecraft.world.effect.MobEffectInstance mobeffect1 = new net.minecraft.world.effect.MobEffectInstance(net.minecraft.world.effect.MobEffects.BAD_OMEN, 120000, amp, false, false, true); ++ ++ if (serverLevel.getGameRules().get(net.minecraft.world.level.gamerules.GameRules.RAIDS)) { ++ entityhuman.addEffect(mobeffect1, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.PATROL_CAPTAIN); // CraftBukkit ++ } ++ this.setPatrolLeader(false); ++ } ++ } ++ // Leaves end - Revert raid changes + } + + super.die(source); diff --git a/1todos/server/minecraft-patches/features/0017-Compatibility-fix-for-Raid-Revert-and-Cross-Region-D.patch b/lophine-server/minecraft-patches/features/0016-Compatibility-fix-for-Raid-Revert-and-Cross-Region-D.patch similarity index 50% rename from 1todos/server/minecraft-patches/features/0017-Compatibility-fix-for-Raid-Revert-and-Cross-Region-D.patch rename to lophine-server/minecraft-patches/features/0016-Compatibility-fix-for-Raid-Revert-and-Cross-Region-D.patch index 7d3c3f2..1912674 100644 --- a/1todos/server/minecraft-patches/features/0017-Compatibility-fix-for-Raid-Revert-and-Cross-Region-D.patch +++ b/lophine-server/minecraft-patches/features/0016-Compatibility-fix-for-Raid-Revert-and-Cross-Region-D.patch @@ -6,15 +6,15 @@ Subject: [PATCH] Compatibility fix for Raid Revert and Cross Region Damage diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index 5bae274f5ee869e540e4330e03af671b6b18313d..3fe9afe55b4d61db8030479d3d74b8656679cb10 100644 +index fde9fad11e130cf93205d23da09ad369b35db160..44956582516ac508681d7ca3e4e04e4270859bd8 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java -@@ -1240,6 +1240,29 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin +@@ -1234,6 +1234,29 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin } } + // Lophine Start - raid revert adapt Cross Region Damage trace -+ public boolean addEffect(MobEffectInstance effectInstance, EntityPotionEffectEvent.Cause cause, boolean fireEvent, boolean async) { ++ public boolean addEffect(final MobEffectInstance effectInstance, EntityPotionEffectEvent.Cause cause, boolean fireEvent, boolean async) { + if (!async || ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(this)) { + return addEffect(effectInstance, this, cause, fireEvent); + } else if (fun.bm.lophine.config.modules.experiment.EntityDamageSourceTraceConfig.enabled) { @@ -24,7 +24,7 @@ index 5bae274f5ee869e540e4330e03af671b6b18313d..3fe9afe55b4d61db8030479d3d74b865 + return false; + } + -+ private void postToAddEffect(MobEffectInstance effectInstance, @Nullable Entity entity, EntityPotionEffectEvent.Cause cause, boolean fireEvent) { ++ private void postToAddEffect(final MobEffectInstance effectInstance, @Nullable Entity entity, EntityPotionEffectEvent.Cause cause, boolean fireEvent) { + if (entity != null) + entity.getBukkitEntity().taskScheduler.schedule((Entity nmsEntity) -> { + try { @@ -36,19 +36,19 @@ index 5bae274f5ee869e540e4330e03af671b6b18313d..3fe9afe55b4d61db8030479d3d74b865 + } + // Lophine End - raid revert adapt Cross Region Damage trace + - public boolean canBeAffected(MobEffectInstance effectInstance) { - if (this.getType().is(EntityTypeTags.IMMUNE_TO_INFESTED)) { - return !effectInstance.is(MobEffects.INFESTED); + public boolean canBeAffected(final MobEffectInstance newEffect) { + if (this.is(EntityTypeTags.IMMUNE_TO_INFESTED)) { + return !newEffect.is(MobEffects.INFESTED); diff --git a/net/minecraft/world/entity/raid/Raider.java b/net/minecraft/world/entity/raid/Raider.java -index 2b7894a4104d4cb237746a3e66d4368b6f8f3c1e..03e3290367790add702a5856aaff3be465ea548c 100644 +index 1a51da9171c13711e106731c360051d183a40893..7094a67959e9747b2dfa55a5f5a3e90552d35466 100644 --- a/net/minecraft/world/entity/raid/Raider.java +++ b/net/minecraft/world/entity/raid/Raider.java -@@ -157,7 +157,7 @@ public abstract class Raider extends PatrollingMonster { - net.minecraft.world.effect.MobEffectInstance mobeffect1 = new net.minecraft.world.effect.MobEffectInstance(net.minecraft.world.effect.MobEffects.BAD_OMEN, 120000, i, false, false, true); +@@ -158,7 +158,7 @@ public abstract class Raider extends PatrollingMonster { + net.minecraft.world.effect.MobEffectInstance mobeffect1 = new net.minecraft.world.effect.MobEffectInstance(net.minecraft.world.effect.MobEffects.BAD_OMEN, 120000, amp, false, false, true); - if (serverLevel.getGameRules().get(net.minecraft.world.level.gamerules.GameRules.RAIDS)) { -- entityhuman.addEffect(mobeffect1, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.PATROL_CAPTAIN); // CraftBukkit -+ entityhuman.addEffect(mobeffect1, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.PATROL_CAPTAIN, true, fun.bm.lophine.config.modules.experiment.EntityDamageSourceTraceConfig.enabled); // Lophine - raid revert adapt Cross Region Damage trace - } - this.setPatrolLeader(false); + if (serverLevel.getGameRules().get(net.minecraft.world.level.gamerules.GameRules.RAIDS)) { +- entityhuman.addEffect(mobeffect1, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.PATROL_CAPTAIN); // CraftBukkit ++ entityhuman.addEffect(mobeffect1, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.PATROL_CAPTAIN, true, fun.bm.lophine.config.modules.experiment.EntityDamageSourceTraceConfig.enabled); // CraftBukkit // Lophine - raid revert adapt Cross Region Damage trace } + this.setPatrolLeader(false); + } diff --git a/lophine-server/paper-patches/features/0003-Add-cancel-task-by-task-id-in-FoliaGlobalRegionSched.patch b/lophine-server/paper-patches/features/0003-Add-cancel-task-by-task-id-in-FoliaGlobalRegionSched.patch index 8d0b163..72b7686 100644 --- a/lophine-server/paper-patches/features/0003-Add-cancel-task-by-task-id-in-FoliaGlobalRegionSched.patch +++ b/lophine-server/paper-patches/features/0003-Add-cancel-task-by-task-id-in-FoliaGlobalRegionSched.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add cancel task by task id in FoliaGlobalRegionScheduler diff --git a/src/main/java/io/papermc/paper/threadedregions/scheduler/FoliaGlobalRegionScheduler.java b/src/main/java/io/papermc/paper/threadedregions/scheduler/FoliaGlobalRegionScheduler.java -index 14ffbcb66006878eacf310547dad53718f8308eb..6c108bc7d93196803daeef4751d06cafa6eeec1a 100644 +index 14ffbcb66006878eacf310547dad53718f8308eb..f20f2735fbb4d1e38d576eafe18a0054a45aa59e 100644 --- a/src/main/java/io/papermc/paper/threadedregions/scheduler/FoliaGlobalRegionScheduler.java +++ b/src/main/java/io/papermc/paper/threadedregions/scheduler/FoliaGlobalRegionScheduler.java @@ -16,6 +16,8 @@ public class FoliaGlobalRegionScheduler implements GlobalRegionScheduler { @@ -35,12 +35,13 @@ index 14ffbcb66006878eacf310547dad53718f8308eb..6c108bc7d93196803daeef4751d06caf this.scheduleInternal(ret, initialDelayTicks); -@@ -133,7 +135,33 @@ public class FoliaGlobalRegionScheduler implements GlobalRegionScheduler { +@@ -133,7 +135,34 @@ public class FoliaGlobalRegionScheduler implements GlobalRegionScheduler { } } - private final class GlobalScheduledTask implements ScheduledTask, Runnable { + // Lophine start - add cancel task by task id ++ @Override + public void cancelTask(final int taskId) { + synchronized (this.stateLock) { + for (final List tasks : this.tasksByDeadline.values()) { @@ -70,11 +71,11 @@ index 14ffbcb66006878eacf310547dad53718f8308eb..6c108bc7d93196803daeef4751d06caf private static final int STATE_IDLE = 0; private static final int STATE_EXECUTING = 1; -@@ -145,13 +173,15 @@ public class FoliaGlobalRegionScheduler implements GlobalRegionScheduler { +@@ -145,13 +174,15 @@ public class FoliaGlobalRegionScheduler implements GlobalRegionScheduler { private final long repeatDelay; // in ticks private Consumer run; private volatile int state; -+ private int taskId; // Lophine - add task id ++ private final int taskId; // Lophine - add task id private static final VarHandle STATE_HANDLE = ConcurrentUtil.getVarHandle(GlobalScheduledTask.class, "state", int.class); @@ -87,7 +88,7 @@ index 14ffbcb66006878eacf310547dad53718f8308eb..6c108bc7d93196803daeef4751d06caf } private final int getStateVolatile() { -@@ -262,5 +292,11 @@ public class FoliaGlobalRegionScheduler implements GlobalRegionScheduler { +@@ -262,5 +293,11 @@ public class FoliaGlobalRegionScheduler implements GlobalRegionScheduler { } } } diff --git a/lophine-server/src/main/java/fun/bm/lophine/config/modules/experiment/CommandConfig.java b/lophine-server/src/main/java/fun/bm/lophine/config/modules/experiment/CommandConfig.java index f5e3a78..6618653 100644 --- a/lophine-server/src/main/java/fun/bm/lophine/config/modules/experiment/CommandConfig.java +++ b/lophine-server/src/main/java/fun/bm/lophine/config/modules/experiment/CommandConfig.java @@ -7,10 +7,10 @@ import me.earthme.luminol.enums.EnumConfigCategory; @ConfigClassInfo(category = EnumConfigCategory.EXPERIMENT, name = "command") public class CommandConfig implements IConfigModule { -// @ConfigInfo(name = "tick_command_enabled", comments = -// """ -// Allow to use tick command""") -// public static boolean tick = false; + @ConfigInfo(name = "tick_command_enabled", comments = + """ + Allow to use tick command""") + public static boolean tick = false; @ConfigInfo(name = "function_command_enabled", comments = """ diff --git a/lophine-server/src/main/java/fun/bm/lophine/config/modules/function/OldFeatureConfig.java b/lophine-server/src/main/java/fun/bm/lophine/config/modules/function/OldFeatureConfig.java index 8d40f9d..3d23782 100644 --- a/lophine-server/src/main/java/fun/bm/lophine/config/modules/function/OldFeatureConfig.java +++ b/lophine-server/src/main/java/fun/bm/lophine/config/modules/function/OldFeatureConfig.java @@ -15,10 +15,10 @@ public class OldFeatureConfig implements IConfigModule { // @ConfigInfo(name = "old_explosion_damage_calculator") // public static boolean oldExplosionDamageCalculator = false; -// -// @ConfigInfo(name = "old_raid_behavior") -// public static boolean oldRaidBehavior = false; -// + + @ConfigInfo(name = "old_raid_behavior") + public static boolean oldRaidBehavior = false; + // @ConfigInfo(name = "villager-void-trade", comments = // """ // Allow villager void trade.""")