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.
This commit is contained in:
boy0001 2015-04-07 22:17:04 +10:00
parent e8fa39004d
commit 0c3919b365
7 changed files with 88 additions and 1 deletions

View File

@ -8,7 +8,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
<artifactId>PlotSquared</artifactId> <artifactId>PlotSquared</artifactId>
<version>2.9.6</version> <version>2.9.7</version>
<name>PlotSquared</name> <name>PlotSquared</name>
<packaging>jar</packaging> <packaging>jar</packaging>
<build> <build>

View File

@ -30,6 +30,7 @@ import com.intellectualcrafters.plot.flag.FlagManager;
import com.intellectualcrafters.plot.generator.BukkitHybridUtils; import com.intellectualcrafters.plot.generator.BukkitHybridUtils;
import com.intellectualcrafters.plot.generator.HybridGen; import com.intellectualcrafters.plot.generator.HybridGen;
import com.intellectualcrafters.plot.generator.HybridUtils; import com.intellectualcrafters.plot.generator.HybridUtils;
import com.intellectualcrafters.plot.listeners.ChunkListener;
import com.intellectualcrafters.plot.listeners.ForceFieldListener; import com.intellectualcrafters.plot.listeners.ForceFieldListener;
import com.intellectualcrafters.plot.listeners.InventoryListener; import com.intellectualcrafters.plot.listeners.InventoryListener;
import com.intellectualcrafters.plot.listeners.PlayerEvents; 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 :)"); log("&dUsing metrics will allow us to improve the plugin, please consider it :)");
} }
getServer().getPluginManager().registerEvents(new WorldEvents(), this); getServer().getPluginManager().registerEvents(new WorldEvents(), this);
// Experimental
if (Settings.CHUNK_PROCESSOR) {
getServer().getPluginManager().registerEvents(new ChunkListener(), this);
}
List<World> worlds = Bukkit.getWorlds(); List<World> worlds = Bukkit.getWorlds();
if (worlds.size() > 0) { if (worlds.size() > 0) {
UUIDHandler.cacheAll(worlds.get(0).getName()); UUIDHandler.cacheAll(worlds.get(0).getName());

View File

@ -810,6 +810,11 @@ public class PlotSquared {
options.put("titles", Settings.TITLES); options.put("titles", Settings.TITLES);
options.put("teleport.on_login", Settings.TELEPORT_ON_LOGIN); options.put("teleport.on_login", Settings.TELEPORT_ON_LOGIN);
options.put("worldedit.require-selection-in-mask", Settings.REQUIRE_SELECTION); 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<String, Object> node : options.entrySet()) { for (final Entry<String, Object> node : options.entrySet()) {
if (!config.contains(node.getKey())) { if (!config.contains(node.getKey())) {
config.set(node.getKey(), node.getValue()); config.set(node.getKey(), node.getValue());
@ -820,6 +825,9 @@ public class PlotSquared {
if (Settings.DEBUG) { if (Settings.DEBUG) {
log(C.PREFIX.s() + "&6Debug Mode Enabled (Default). Edit the config to turn this off."); 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.TNT_LISTENER = config.getBoolean("protection.tnt-listener.enabled");
Settings.PERMISSION_CACHING = config.getBoolean("cache.permissions"); Settings.PERMISSION_CACHING = config.getBoolean("cache.permissions");
Settings.CONFIRM_CLEAR = config.getBoolean("confirmation.clear"); Settings.CONFIRM_CLEAR = config.getBoolean("confirmation.clear");

View File

@ -41,6 +41,12 @@ public class Settings {
public static boolean CONVERT_PLOTME = true; public static boolean CONVERT_PLOTME = true;
public static boolean CACHE_PLOTME = false; public static boolean CACHE_PLOTME = false;
public static boolean USE_PLOTME_ALIAS = 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 * TNT listener
*/ */

View File

@ -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();
}
}
}
}

View File

@ -1,5 +1,6 @@
package com.intellectualcrafters.plot.object; package com.intellectualcrafters.plot.object;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.UUID; import java.util.UUID;
@ -18,6 +19,7 @@ public class BukkitPlayer implements PlotPlayer {
public HashSet<String> noPerm = new HashSet<>(); public HashSet<String> noPerm = new HashSet<>();
private int op = 0; private int op = 0;
private long last = 0; private long last = 0;
private HashMap<String, Object> tmpData = null;
/** /**
* Please do not use this method. Instead use BukkitUtil.getPlayer(Player), as it caches player objects. * 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); 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);
}
} }

View File

@ -9,6 +9,10 @@ import java.util.UUID;
*/ */
public interface PlotPlayer { public interface PlotPlayer {
public void setTmpData(String key, Object value);
public Object getTmpData(String key);
public long getPreviousLogin(); public long getPreviousLogin();
public Location getLocation(); public Location getLocation();