/
minecraftbackup
/
AnarchyExploitFixes
Обзор
Документация
Войти
/
minecraftbackup
/
AnarchyExploitFixes
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
AnarchyExploitFixesFolia/src/main/java/me/xginko/aef/modules/chunklimits/ExpBottleLimit.java
99 строк
4 KB
xGinko
improve 1.20.6+ support
21 июн 2024, 18:43
21 июн 2024, 18:43
f0de459
Код
Авторство
О чём код?
package me.xginko.aef.modules.chunklimits; import com.cryptomorin.xseries.XEntityType; import io.papermc.paper.threadedregions.scheduler.ScheduledTask; import me.xginko.aef.modules.AEFModule; import me.xginko.aef.utils.LocationUtil; import org.bukkit.Chunk; import org.bukkit.World; import org.bukkit.entity.Entity; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.bukkit.event.entity.ExpBottleEvent; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; public class ExpBottleLimit extends AEFModule implements Consumer<ScheduledTask>, Listener { private ScheduledTask scheduledTask; private final long checkPeriod; private final int maxExpBottlePerChunk; private final boolean logIsEnabled; public ExpBottleLimit() { super("chunk-limits.exp-bottle-limit"); config.addComment(configPath + ".enable", """ Prevent players from crashing the server or other players by\s creating a ton of THROWN_EXP_BOTTLE entities, then loading\s them at once.\s Does not limit the EXP_ORBS, just the bottle entities."""); this.logIsEnabled = config.getBoolean(configPath + ".log", false); this.maxExpBottlePerChunk = config.getInt(configPath + ".max-exp-bottle-per-chunk", 25); this.checkPeriod = config.getInt(configPath + ".check-period-in-ticks", 800, "20 ticks = 1 second"); } @Override public void enable() { plugin.getServer().getPluginManager().registerEvents(this, plugin); this.scheduledTask = plugin.getServer().getGlobalRegionScheduler() .runAtFixedRate(plugin, this, checkPeriod, checkPeriod); } @Override public boolean shouldEnable() { return config.getBoolean(configPath + ".enable", true); } @Override public void disable() { HandlerList.unregisterAll(this); if (scheduledTask != null) scheduledTask.cancel(); } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) private void onExpBottle(ExpBottleEvent event) { int expBottleCount = 0; for (Entity entity : event.getEntity().getChunk().getEntities()) { if (entity.getType() != XEntityType.EXPERIENCE_BOTTLE.get()) continue; expBottleCount++; if (expBottleCount > maxExpBottlePerChunk) { entity.getScheduler().execute(plugin, () -> { entity.remove(); if (logIsEnabled) info("Removed XP-Bottle at " + LocationUtil.toString(entity.getLocation()) + " because reached limit of " + maxExpBottlePerChunk); }, null, 1L); } } } @Override public void accept(ScheduledTask task) { for (World world : plugin.getServer().getWorlds()) { for (Chunk chunk : world.getLoadedChunks()) { plugin.getServer().getRegionScheduler().execute(plugin, world, chunk.getX(), chunk.getZ(), () -> { if (!chunk.isEntitiesLoaded()) return; AtomicInteger droppedItemCount = new AtomicInteger(); for (Entity entity : chunk.getEntities()) { entity.getScheduler().execute(plugin, () -> { if (entity.getType() != XEntityType.EXPERIENCE_BOTTLE.get()) return; if (droppedItemCount.incrementAndGet() <= maxExpBottlePerChunk) return; entity.remove(); if (logIsEnabled) info("Removed XP-Bottle at " + LocationUtil.toString(entity.getLocation()) + " because reached limit of " + maxExpBottlePerChunk); }, null, 1L); } }); } } } }