From 0c3919b365b07e1ae460a02c65465de65217c89d Mon Sep 17 00:00:00 2001 From: boy0001 Date: Tue, 7 Apr 2015 22:17:04 +1000 Subject: [PATCH] Added experimental chunk processing: If enabled: - Detects laggy chunks based on a configured threshold - Removes all sources of lag from the chunk If the threshold is set too low, normal levels of blocks and entities will be considered "sources of lag", so just be careful when using this experimental feature. --- PlotSquared/pom.xml | 2 +- .../intellectualcrafters/plot/BukkitMain.java | 7 +++ .../plot/PlotSquared.java | 8 ++++ .../plot/config/Settings.java | 6 +++ .../plot/listeners/ChunkListener.java | 44 +++++++++++++++++++ .../plot/object/BukkitPlayer.java | 18 ++++++++ .../plot/object/PlotPlayer.java | 4 ++ 7 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/ChunkListener.java diff --git a/PlotSquared/pom.xml b/PlotSquared/pom.xml index 04480a58e..a6d8e7024 100644 --- a/PlotSquared/pom.xml +++ b/PlotSquared/pom.xml @@ -8,7 +8,7 @@ UTF-8 PlotSquared - 2.9.6 + 2.9.7 PlotSquared jar diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/BukkitMain.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/BukkitMain.java index 2e2654d73..4e2abc5c9 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/BukkitMain.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/BukkitMain.java @@ -30,6 +30,7 @@ import com.intellectualcrafters.plot.flag.FlagManager; import com.intellectualcrafters.plot.generator.BukkitHybridUtils; import com.intellectualcrafters.plot.generator.HybridGen; import com.intellectualcrafters.plot.generator.HybridUtils; +import com.intellectualcrafters.plot.listeners.ChunkListener; import com.intellectualcrafters.plot.listeners.ForceFieldListener; import com.intellectualcrafters.plot.listeners.InventoryListener; import com.intellectualcrafters.plot.listeners.PlayerEvents; @@ -103,6 +104,12 @@ public class BukkitMain extends JavaPlugin implements Listener, IPlotMain { log("&dUsing metrics will allow us to improve the plugin, please consider it :)"); } getServer().getPluginManager().registerEvents(new WorldEvents(), this); + + // Experimental + if (Settings.CHUNK_PROCESSOR) { + getServer().getPluginManager().registerEvents(new ChunkListener(), this); + } + List worlds = Bukkit.getWorlds(); if (worlds.size() > 0) { UUIDHandler.cacheAll(worlds.get(0).getName()); diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotSquared.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotSquared.java index 10c6df3a1..e9ca0d807 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotSquared.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotSquared.java @@ -810,6 +810,11 @@ public class PlotSquared { options.put("titles", Settings.TITLES); options.put("teleport.on_login", Settings.TELEPORT_ON_LOGIN); options.put("worldedit.require-selection-in-mask", Settings.REQUIRE_SELECTION); + + options.put("chunk-processor.enabled", Settings.CHUNK_PROCESSOR); + options.put("chunk-processor.max-blockstates", Settings.CHUNK_PROCESSOR_MAX_BLOCKSTATES); + options.put("chunk-processor.max-entities", Settings.CHUNK_PROCESSOR_MAX_ENTITIES); + for (final Entry node : options.entrySet()) { if (!config.contains(node.getKey())) { config.set(node.getKey(), node.getValue()); @@ -820,6 +825,9 @@ public class PlotSquared { if (Settings.DEBUG) { log(C.PREFIX.s() + "&6Debug Mode Enabled (Default). Edit the config to turn this off."); } + + Settings.CHUNK_PROCESSOR = config.getBoolean("chunk-processor.enabled"); + Settings.TNT_LISTENER = config.getBoolean("protection.tnt-listener.enabled"); Settings.PERMISSION_CACHING = config.getBoolean("cache.permissions"); Settings.CONFIRM_CLEAR = config.getBoolean("confirmation.clear"); diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/config/Settings.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/config/Settings.java index 8e8e4510a..ca7fbbbcc 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/config/Settings.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/config/Settings.java @@ -41,6 +41,12 @@ public class Settings { public static boolean CONVERT_PLOTME = true; public static boolean CACHE_PLOTME = false; public static boolean USE_PLOTME_ALIAS = false; + /** + * Chunk processor + */ + public static boolean CHUNK_PROCESSOR = false; + public static int CHUNK_PROCESSOR_MAX_BLOCKSTATES = 4096; + public static int CHUNK_PROCESSOR_MAX_ENTITIES = 512; /** * TNT listener */ diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/ChunkListener.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/ChunkListener.java new file mode 100644 index 000000000..b40529317 --- /dev/null +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/ChunkListener.java @@ -0,0 +1,44 @@ +package com.intellectualcrafters.plot.listeners; + +import org.bukkit.Chunk; +import org.bukkit.Material; +import org.bukkit.block.BlockState; +import org.bukkit.entity.Entity; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.world.ChunkLoadEvent; +import org.bukkit.event.world.ChunkUnloadEvent; + +import com.intellectualcrafters.plot.PlotSquared; +import com.intellectualcrafters.plot.config.Settings; + +public class ChunkListener implements Listener { + + @EventHandler + public void onChunkUnload(ChunkUnloadEvent event) { + processChunk(event.getChunk()); + } + + @EventHandler + public void onChunkLoad(ChunkLoadEvent event) { + processChunk(event.getChunk()); + } + + public void processChunk(Chunk chunk) { + if (!PlotSquared.isPlotWorld(chunk.getWorld().getName())) { + return; + } + Entity[] entities = chunk.getEntities(); + BlockState[] tiles = chunk.getTileEntities(); + if (tiles.length > Settings.CHUNK_PROCESSOR_MAX_BLOCKSTATES) { + for (BlockState tile : tiles) { + tile.getBlock().setType(Material.AIR, false); + } + } + if (entities.length > Settings.CHUNK_PROCESSOR_MAX_ENTITIES) { + for (Entity ent : entities) { + ent.remove(); + } + } + } +} diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/BukkitPlayer.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/BukkitPlayer.java index eb3f83359..dd1594ebe 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/BukkitPlayer.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/BukkitPlayer.java @@ -1,5 +1,6 @@ package com.intellectualcrafters.plot.object; +import java.util.HashMap; import java.util.HashSet; import java.util.UUID; @@ -18,6 +19,7 @@ public class BukkitPlayer implements PlotPlayer { public HashSet noPerm = new HashSet<>(); private int op = 0; private long last = 0; + private HashMap tmpData = null; /** * Please do not use this method. Instead use BukkitUtil.getPlayer(Player), as it caches player objects. @@ -119,4 +121,20 @@ public class BukkitPlayer implements PlotPlayer { return BukkitUtil.getLocationFull(this.player); } + @Override + public void setTmpData(String key, Object value) { + if (tmpData == null) { + tmpData = new HashMap<>(); + } + tmpData.put(key, value); + } + + @Override + public Object getTmpData(String key) { + if (tmpData == null) { + return null; + } + return tmpData.get(key); + } + } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/PlotPlayer.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/PlotPlayer.java index cb75aa726..24776994e 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/PlotPlayer.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/PlotPlayer.java @@ -9,6 +9,10 @@ import java.util.UUID; */ public interface PlotPlayer { + public void setTmpData(String key, Object value); + + public Object getTmpData(String key); + public long getPreviousLogin(); public Location getLocation();