diff --git a/README.md b/README.md index 85d8f8d..9749b62 100644 --- a/README.md +++ b/README.md @@ -2,17 +2,25 @@ ## 自定义区块卸载规则 - ## 说明 +在 Minecraft 单机版中,一个实体进入地狱门后会使得另一侧的区块加载300游戏刻(15秒) ,利用此机制可以实现一些双维度刷怪塔(如凋零农场)。 +但是在 Paper 系的服务端中,实体在通过地狱门后并不会触发另一测的区块加载。因此导致了一些双维度刷怪塔无法正常工作,因此诞生了区块加载器。 +但是在一些更特殊的环境下即便使用了区块加载器加载了区块,也无法实现双维度刷怪塔的效果。 +因为在某些服务端中使用区块加载器无法使区块加载等级达到“实体计算”的等级,此情况下的实体在通过门后会被立刻删除。 +本插件通过设置区块强制加载标签,保证区块的加载等级达到实体计算等级,以此来还原在服务端的原版双纬度刷怪塔特性。 +## 实现逻辑 -## 功能介绍 - +1. 插件会记录玩家经过的每一个区块,并为这些区块添加“强制加载”标签; +2. 被添加了强制加载标签的区块会保持高等级的常加载,此加载等级与玩家在区块中的实体计算等级相同; +3. 当一个玩家拥有的强制加载区块数量超过了配置文件中的最大值时,会将最早的区块取消强制加载标签; +4. 被取消标签的区块会按照服务端常规的区块卸载规则进行卸载; +5. 玩家退出游戏后会自动为其取消所有区块的强制加载标签,避免过多的区块被强制加载; ## 支持版本 -- 1.20.1+ (Paper、Folia) +- Folia 1.20.1+ ## 安装方法 @@ -23,22 +31,40 @@ ## 使用方法 +无 ## 管理员指南 +提示:请合理设置每个玩家能拥有的的最多强加载区块数量,避免因为过多的强加载区块导致服务器内存占用过高。 ## 指令 ### 玩家指令 +无 ### 管理员指令 +无 ## 配置文件参考 ```yaml +# 启动时清除已有的强加载区块延迟 秒 +# 建议设置为10秒 太低可能在世界加载完成前触发操作引起报错 +# -1 为不清除 如果你的服务器有其他插件会在启动时加载区块建议设置为-1 +ClearLoadedChunksOnStartupDelay: 10 +# 每个玩家拥有的最多强加载区块数 +MaxDelayChunkPerPlayer: 10 + +# tps最低阈值 低于此值将会开始自动取消强加载区块 +MinimumTpsThreshold: 15.0 + +# 每次检查tps的间隔 单位为tick 20tick=1s +TpsCheckIntervalTicks: 600 + +Debug: false ``` ## TODO diff --git a/pom.xml b/pom.xml index d0da4af..944a54b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ cn.lunadeer BetterChunkUnload - 1.9 + 1.10 jar BetterChunkUnload diff --git a/src/main/java/cn/lunadeer/betterchunkunload/BetterChunkUnload.java b/src/main/java/cn/lunadeer/betterchunkunload/BetterChunkUnload.java index 114f515..d4fdf80 100644 --- a/src/main/java/cn/lunadeer/betterchunkunload/BetterChunkUnload.java +++ b/src/main/java/cn/lunadeer/betterchunkunload/BetterChunkUnload.java @@ -1,17 +1,14 @@ package cn.lunadeer.betterchunkunload; -import cn.lunadeer.betterchunkunload.utils.ChunkClear; import cn.lunadeer.betterchunkunload.utils.ConfigManager; import cn.lunadeer.betterchunkunload.utils.XLogger; import io.papermc.paper.threadedregions.scheduler.GlobalRegionScheduler; import org.bukkit.Chunk; -import org.bukkit.entity.Player; +import org.bukkit.World; import org.bukkit.plugin.java.JavaPlugin; -import javax.xml.crypto.dsig.keyinfo.KeyValue; import java.util.Collection; import java.util.HashMap; -import java.util.List; import java.util.Map; public final class BetterChunkUnload extends JavaPlugin { @@ -26,6 +23,25 @@ public final class BetterChunkUnload extends JavaPlugin { // register events getServer().getPluginManager().registerEvents(new Events(), this); + // clear all force loaded chunks + if (config.getClearLoadedChunksOnStartupDelay() >= 0) { + XLogger.info("启动时清理强加载区块已启用"); + scheduler.runDelayed(instance, (instance) -> { + int count = 0; + for (World world : BetterChunkUnload.instance.getServer().getWorlds()) { + XLogger.debug("清除所有强加载区块: " + world.getName()); + Collection chunks = world.getForceLoadedChunks(); + for (Chunk chunk : chunks) { + count++; + world.setChunkForceLoaded(chunk.getX(), chunk.getZ(), false); + } + } + XLogger.info("共清理强加载区块(个): " + count); + }, config.getClearLoadedChunksOnStartupDelay() * 20); + } else { + XLogger.info("启动时清理强加载区块已禁用"); + } + // start tps checker scheduler.runAtFixedRate(instance, (instance) -> { tpsChecker(); diff --git a/src/main/java/cn/lunadeer/betterchunkunload/ChunkList.java b/src/main/java/cn/lunadeer/betterchunkunload/ChunkList.java index 348991c..9b44e00 100644 --- a/src/main/java/cn/lunadeer/betterchunkunload/ChunkList.java +++ b/src/main/java/cn/lunadeer/betterchunkunload/ChunkList.java @@ -4,7 +4,6 @@ import cn.lunadeer.betterchunkunload.utils.ChunkClear; import cn.lunadeer.betterchunkunload.utils.XLogger; import org.bukkit.Chunk; import org.bukkit.World; -import org.bukkit.entity.Player; import java.util.ArrayList; diff --git a/src/main/java/cn/lunadeer/betterchunkunload/Events.java b/src/main/java/cn/lunadeer/betterchunkunload/Events.java index 941791b..1d02b70 100644 --- a/src/main/java/cn/lunadeer/betterchunkunload/Events.java +++ b/src/main/java/cn/lunadeer/betterchunkunload/Events.java @@ -2,13 +2,10 @@ package cn.lunadeer.betterchunkunload; import cn.lunadeer.betterchunkunload.utils.XLogger; import io.papermc.paper.event.packet.PlayerChunkLoadEvent; -import io.papermc.paper.event.packet.PlayerChunkUnloadEvent; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.event.world.ChunkLoadEvent; -import org.bukkit.event.world.ChunkUnloadEvent; public class Events implements Listener { diff --git a/src/main/java/cn/lunadeer/betterchunkunload/TpsChecker.java b/src/main/java/cn/lunadeer/betterchunkunload/TpsChecker.java deleted file mode 100644 index 132a7ed..0000000 --- a/src/main/java/cn/lunadeer/betterchunkunload/TpsChecker.java +++ /dev/null @@ -1,19 +0,0 @@ -package cn.lunadeer.betterchunkunload; - -import cn.lunadeer.betterchunkunload.utils.XLogger; - -public class TpsChecker implements Runnable{ - @Override - public void run() { - if (!BetterChunkUnload.enable) { - return; - } - if (BetterChunkUnload.instance.getServer().getTPS()[0] > BetterChunkUnload.config.getMinimumTpsThreshold()){ - return; - } - XLogger.warn("TPS: " + BetterChunkUnload.instance.getServer().getTPS()[0] + " 低于 " + BetterChunkUnload.config.getMinimumTpsThreshold() + " 开始清理区块"); - for (ChunkList chunkList : BetterChunkUnload.getChunkList()) { - chunkList.popFront(); - } - } -} diff --git a/src/main/java/cn/lunadeer/betterchunkunload/utils/ConfigManager.java b/src/main/java/cn/lunadeer/betterchunkunload/utils/ConfigManager.java index 6fcb5f0..c19d104 100644 --- a/src/main/java/cn/lunadeer/betterchunkunload/utils/ConfigManager.java +++ b/src/main/java/cn/lunadeer/betterchunkunload/utils/ConfigManager.java @@ -19,6 +19,7 @@ public class ConfigManager { _MaxDelayChunkPerPlayer = _file.getInt("MaxDelayChunkPerPlayer", 10); _MinimumTpsThreshold = (float) _file.getDouble("MinimumTpsThreshold", 15.0); _TpsCheckIntervalTicks = _file.getInt("TpsCheckIntervalTicks", 600); + _ClearLoadedChunksOnStartupDelay = _file.getInt("ClearLoadedChunksOnStartupDelay", 10); } public Boolean isDebug() { @@ -61,6 +62,16 @@ public class ConfigManager { _plugin.saveConfig(); } + public Integer getClearLoadedChunksOnStartupDelay() { + return _ClearLoadedChunksOnStartupDelay; + } + + public void setClearLoadedChunksOnStartupDelay(Integer ClearLoadedChunksOnStartupDelay) { + _ClearLoadedChunksOnStartupDelay = ClearLoadedChunksOnStartupDelay; + _file.set("ClearLoadedChunksOnStartupDelay", ClearLoadedChunksOnStartupDelay); + _plugin.saveConfig(); + } + private final BetterChunkUnload _plugin; private FileConfiguration _file; @@ -68,5 +79,6 @@ public class ConfigManager { private Integer _MaxDelayChunkPerPlayer; private Float _MinimumTpsThreshold; - private Integer _TpsCheckIntervalTicks; + private Integer _TpsCheckIntervalTicks; + private Integer _ClearLoadedChunksOnStartupDelay; } diff --git a/src/main/java/cn/lunadeer/betterchunkunload/utils/Notification.java b/src/main/java/cn/lunadeer/betterchunkunload/utils/Notification.java index 1867a6f..a68d996 100644 --- a/src/main/java/cn/lunadeer/betterchunkunload/utils/Notification.java +++ b/src/main/java/cn/lunadeer/betterchunkunload/utils/Notification.java @@ -7,7 +7,7 @@ import net.kyori.adventure.text.format.TextColor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import static cn.lunadeer.betterchunkunload.utils.XLogger.*; +import static cn.lunadeer.betterchunkunload.utils.XLogger.debug; public class Notification { private static final Style i_style = Style.style(TextColor.color(139, 255, 123)); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 14563ff..616c85c 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,3 +1,8 @@ +# 启动时清除已有的强加载区块延迟 秒 +# 建议设置为10秒 太低可能在世界加载完成前触发操作引起报错 +# -1 为不清除 如果你的服务器有其他插件会在启动时加载区块建议设置为-1 +ClearLoadedChunksOnStartupDelay: 10 + # 每个玩家拥有的最大延迟卸载区块数 MaxDelayChunkPerPlayer: 10