diff --git a/lophine-server/paper-patches/features/0007-add-cancel-task-by-task-id-in-FoliaGlobalRegionSched.patch b/lophine-server/paper-patches/features/0007-add-cancel-task-by-task-id-in-FoliaGlobalRegionSched.patch new file mode 100644 index 0000000..e7f4dfc --- /dev/null +++ b/lophine-server/paper-patches/features/0007-add-cancel-task-by-task-id-in-FoliaGlobalRegionSched.patch @@ -0,0 +1,101 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Helvetica Volubi +Date: Sat, 22 Nov 2025 01:43:26 +0800 +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 d306f911757a4d556c82c0070d4837db87afc497..7c9d3e4c399b2ea246a76b4550ba12e45e75078e 100644 +--- a/src/main/java/io/papermc/paper/threadedregions/scheduler/FoliaGlobalRegionScheduler.java ++++ b/src/main/java/io/papermc/paper/threadedregions/scheduler/FoliaGlobalRegionScheduler.java +@@ -17,6 +17,8 @@ public class FoliaGlobalRegionScheduler implements GlobalRegionScheduler { + private long tickCount = 0L; + private final Object stateLock = new Object(); + private final Long2ObjectOpenHashMap> tasksByDeadline = new Long2ObjectOpenHashMap<>(); ++ private int lastTaskId = 1; // Lophine - add task id ++ private final Object stateLockForTaskId = new Object(); // Lophine - add task id + + public void tick() { + final List run; +@@ -65,7 +67,7 @@ public class FoliaGlobalRegionScheduler implements GlobalRegionScheduler { + throw new IllegalPluginAccessException("Plugin attempted to register task while disabled"); + } + +- final GlobalScheduledTask ret = new GlobalScheduledTask(plugin, -1, task); ++ final GlobalScheduledTask ret = new GlobalScheduledTask(plugin, -1, task, this.getNextTaskId()); // Lophine - add task id + + this.scheduleInternal(ret, delayTicks); + +@@ -92,7 +94,7 @@ public class FoliaGlobalRegionScheduler implements GlobalRegionScheduler { + throw new IllegalPluginAccessException("Plugin attempted to register task while disabled"); + } + +- final GlobalScheduledTask ret = new GlobalScheduledTask(plugin, periodTicks, task); ++ final GlobalScheduledTask ret = new GlobalScheduledTask(plugin, periodTicks, task, this.getNextTaskId()); // Lophine - add task id + + this.scheduleInternal(ret, initialDelayTicks); + +@@ -134,7 +136,33 @@ public class FoliaGlobalRegionScheduler implements GlobalRegionScheduler { + } + } + +- private final class GlobalScheduledTask implements ScheduledTask, Runnable { ++ // Lophine start - add cancel task by task id ++ public void cancelTask(final int taskId) { ++ synchronized (this.stateLock) { ++ for (final List tasks : this.tasksByDeadline.values()) { ++ for (final GlobalScheduledTask task : tasks) { ++ if (task.getTaskId() == taskId) { ++ task.cancel(); ++ return; ++ } ++ } ++ } ++ } ++ } ++ ++ private int getNextTaskId() { ++ synchronized (this.stateLockForTaskId) { ++ if (this.lastTaskId == Integer.MAX_VALUE) { ++ this.lastTaskId = 1; ++ } else { ++ ++this.lastTaskId; ++ } ++ } ++ return this.lastTaskId; ++ } ++ // Lophine end - add cancel task by task id ++ ++ public final class GlobalScheduledTask implements ScheduledTask, Runnable { // Lophine - private -> public + + private static final int STATE_IDLE = 0; + private static final int STATE_EXECUTING = 1; +@@ -146,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 static final VarHandle STATE_HANDLE = ConcurrentUtil.getVarHandle(GlobalScheduledTask.class, "state", int.class); + +- private GlobalScheduledTask(final Plugin plugin, final long repeatDelay, final Consumer run) { ++ private GlobalScheduledTask(final Plugin plugin, final long repeatDelay, final Consumer run, int taskId) { // Lophine - add task id + this.plugin = plugin; + this.repeatDelay = repeatDelay; + this.run = run; ++ this.taskId = taskId; // Lophine - add task id + } + + private final int getStateVolatile() { +@@ -263,5 +293,11 @@ public class FoliaGlobalRegionScheduler implements GlobalRegionScheduler { + } + } + } ++ ++ // Lophine start - add task id ++ public int getTaskId() { ++ return taskId; ++ } ++ // Lophine end - add task id + } + } diff --git a/lophine-server/src/main/java/fun/bm/lophine/LophineLogger.java b/lophine-server/src/main/java/fun/bm/lophine/LophineLogger.java index ac453f7..e61171c 100644 --- a/lophine-server/src/main/java/fun/bm/lophine/LophineLogger.java +++ b/lophine-server/src/main/java/fun/bm/lophine/LophineLogger.java @@ -3,8 +3,6 @@ package fun.bm.lophine; import com.mojang.logging.LogUtils; import org.slf4j.Logger; -import java.util.logging.Level; - public class LophineLogger { public static final Logger LOGGER = LogUtils.getClassLogger(); // only provided for some Logger can not be initialized } diff --git a/lophine-server/src/main/java/fun/bm/lophine/config/modules/experiment/RedStoneConfig.java b/lophine-server/src/main/java/fun/bm/lophine/config/modules/experiment/RedStoneConfig.java index 75f3a87..dedbfe3 100644 --- a/lophine-server/src/main/java/fun/bm/lophine/config/modules/experiment/RedStoneConfig.java +++ b/lophine-server/src/main/java/fun/bm/lophine/config/modules/experiment/RedStoneConfig.java @@ -6,10 +6,11 @@ import me.earthme.luminol.config.flags.ConfigInfo; import me.earthme.luminol.config.flags.HotReloadUnsupported; import me.earthme.luminol.config.flags.TransformedConfig; import me.earthme.luminol.enums.EnumConfigCategory; + /* -* This is a config module for redstone in experimental level -* If we think configs from here is stable for future, we will move them to function module directory -*/ + * This is a config module for redstone in experimental level + * If we think configs from here is stable for future, we will move them to function module directory + */ @ConfigClassInfo(category = EnumConfigCategory.EXPERIMENT, name = "redstone") public class RedStoneConfig implements IConfigModule { @TransformedConfig(name = "enabled", directory = {"experiment", "redstone-ignore-upwards-update"}) diff --git a/lophine-server/src/main/java/org/leavesmc/leaves/bot/BotList.java b/lophine-server/src/main/java/org/leavesmc/leaves/bot/BotList.java index 11604f5..107830d 100644 --- a/lophine-server/src/main/java/org/leavesmc/leaves/bot/BotList.java +++ b/lophine-server/src/main/java/org/leavesmc/leaves/bot/BotList.java @@ -25,6 +25,7 @@ import com.mojang.logging.LogUtils; import fun.bm.lophine.config.modules.function.FakeplayerConfig; import io.papermc.paper.adventure.PaperAdventure; import io.papermc.paper.threadedregions.RegionizedServer; +import io.papermc.paper.threadedregions.scheduler.FoliaGlobalRegionScheduler; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.Style; import net.minecraft.nbt.CompoundTag; @@ -238,7 +239,7 @@ public class BotList { } if (bot.removeTaskId != -1) { - Bukkit.getScheduler().cancelTask(bot.removeTaskId); + ((FoliaGlobalRegionScheduler) Bukkit.getGlobalRegionScheduler()).cancelTask(bot.removeTaskId); bot.removeTaskId = -1; } diff --git a/lophine-server/src/main/java/org/leavesmc/leaves/bot/ServerBot.java b/lophine-server/src/main/java/org/leavesmc/leaves/bot/ServerBot.java index f0464fb..b68ecc1 100644 --- a/lophine-server/src/main/java/org/leavesmc/leaves/bot/ServerBot.java +++ b/lophine-server/src/main/java/org/leavesmc/leaves/bot/ServerBot.java @@ -473,7 +473,7 @@ public class ServerBot extends ServerPlayer { playerConnection.send(this.getAddEntityPacket(entityTracker.serverEntity)); if (login) { - Bukkit.getScheduler().runTaskLater(MinecraftInternalPlugin.INSTANCE, () -> playerConnection.send(new ClientboundRotateHeadPacket(this, (byte) ((getYRot() * 256f) / 360f))), 10); + Bukkit.getGlobalRegionScheduler().runDelayed(MinecraftInternalPlugin.INSTANCE, (unused) -> playerConnection.send(new ClientboundRotateHeadPacket(this, (byte) ((getYRot() * 256f) / 360f))), 10); } else { playerConnection.send(new ClientboundRotateHeadPacket(this, (byte) ((getYRot() * 256f) / 360f))); } @@ -499,7 +499,7 @@ public class ServerBot extends ServerPlayer { Component defaultMessage = this.getCombatTracker().getDeathMessage(); BotDeathEvent event = new BotDeathEvent(this.getBukkitEntity(), PaperAdventure.asAdventure(defaultMessage), flag); - this.getServer().server.getPluginManager().callEvent(event); + MinecraftServer.getServer().server.getPluginManager().callEvent(event); if (event.isCancelled()) { if (this.getHealth() <= 0) { diff --git a/lophine-server/src/main/java/org/leavesmc/leaves/command/bot/subcommands/RemoveCommand.java b/lophine-server/src/main/java/org/leavesmc/leaves/command/bot/subcommands/RemoveCommand.java index 2cf87b9..35a7b35 100644 --- a/lophine-server/src/main/java/org/leavesmc/leaves/command/bot/subcommands/RemoveCommand.java +++ b/lophine-server/src/main/java/org/leavesmc/leaves/command/bot/subcommands/RemoveCommand.java @@ -20,6 +20,7 @@ package org.leavesmc.leaves.command.bot.subcommands; import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.exceptions.CommandSyntaxException; import io.papermc.paper.adventure.PaperAdventure; +import io.papermc.paper.threadedregions.scheduler.FoliaGlobalRegionScheduler; import net.minecraft.world.entity.LivingEntity; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; @@ -102,12 +103,12 @@ public class RemoveCommand extends BotSubcommand { boolean isReschedule = bot.removeTaskId != -1; if (isReschedule) { - Bukkit.getScheduler().cancelTask(bot.removeTaskId); + ((FoliaGlobalRegionScheduler) Bukkit.getGlobalRegionScheduler()).cancelTask(bot.removeTaskId); } - bot.removeTaskId = Bukkit.getScheduler().runTaskLater(MinecraftInternalPlugin.INSTANCE, () -> { + bot.removeTaskId = ((FoliaGlobalRegionScheduler.GlobalScheduledTask) Bukkit.getGlobalRegionScheduler().runDelayed(MinecraftInternalPlugin.INSTANCE, (unused) -> { bot.removeTaskId = -1; removeBot(bot, sender); - }, removeTimeSeconds * 20L).getTaskId(); + }, removeTimeSeconds * 20L)).getTaskId(); sender.sendMessage(join(spaces(), text("Bot", GRAY),