Optimized chunk processor

This commit is contained in:
boy0001 2015-04-08 00:47:02 +10:00
parent 8cc5949050
commit 86c46f7ec0
2 changed files with 63 additions and 5 deletions

View File

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

View File

@ -1,5 +1,6 @@
package com.intellectualcrafters.plot.listeners;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.block.BlockState;
@ -11,34 +12,91 @@ import org.bukkit.event.world.ChunkUnloadEvent;
import com.intellectualcrafters.plot.PlotSquared;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.util.TaskManager;
public class ChunkListener implements Listener {
@EventHandler
public void onChunkUnload(ChunkUnloadEvent event) {
processChunk(event.getChunk());
if (!forceUnload) {
if (processChunk(event.getChunk(), true)) {
event.setCancelled(true);
}
}
}
@EventHandler
public void onChunkLoad(ChunkLoadEvent event) {
processChunk(event.getChunk());
processChunk(event.getChunk(), false);
}
public void processChunk(Chunk chunk) {
if (!PlotSquared.isPlotWorld(chunk.getWorld().getName())) {
public void cleanChunk(final Chunk chunk) {
TaskManager.index.increment();
final Integer currentIndex = TaskManager.index.toInteger();
final Integer task = TaskManager.runTaskRepeat(new Runnable() {
@Override
public void run() {
if (!chunk.isLoaded()) {
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex);
PlotSquared.log("&aSuccessfully processed and unloaded chunk!");
chunk.unload(true, true);
return;
}
BlockState[] tiles = chunk.getTileEntities();
if (tiles.length == 0) {
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex);
PlotSquared.log("&aSuccessfully processed and unloaded chunk!");
chunk.unload(true, true);
return;
}
long start = System.currentTimeMillis();
int i = 0;
while (System.currentTimeMillis() - start < 50) {
if (i >= tiles.length) {
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex);
PlotSquared.log("&aSuccessfully processed and unloaded chunk!");
chunk.unload(true, true);
return;
}
tiles[i].getBlock().setType(Material.AIR, false);
i++;
}
}
}, 1);
TaskManager.tasks.put(currentIndex, task);
}
private boolean forceUnload = false;
public boolean processChunk(Chunk chunk, boolean unload) {
if (!PlotSquared.isPlotWorld(chunk.getWorld().getName())) {
return false;
}
Entity[] entities = chunk.getEntities();
BlockState[] tiles = chunk.getTileEntities();
if (tiles.length > Settings.CHUNK_PROCESSOR_MAX_BLOCKSTATES) {
if (unload) {
PlotSquared.log("&cPlotSquared detected unsafe chunk: " + (chunk.getX() << 4) + "," + (chunk.getX() << 4));
cleanChunk(chunk);
return true;
}
for (BlockState tile : tiles) {
tile.getBlock().setType(Material.AIR, false);
}
}
if (entities.length > Settings.CHUNK_PROCESSOR_MAX_ENTITIES) {
if (unload) {
System.out.print("FORCE UNLOAD");
chunk.load(true);
return false;
}
for (Entity ent : entities) {
ent.remove();
}
}
return false;
}
}