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> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
<artifactId>PlotSquared</artifactId> <artifactId>PlotSquared</artifactId>
<version>2.9.7</version> <version>2.9.8</version>
<name>PlotSquared</name> <name>PlotSquared</name>
<packaging>jar</packaging> <packaging>jar</packaging>
<build> <build>

View File

@ -1,5 +1,6 @@
package com.intellectualcrafters.plot.listeners; package com.intellectualcrafters.plot.listeners;
import org.bukkit.Bukkit;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.BlockState; import org.bukkit.block.BlockState;
@ -11,34 +12,91 @@ import org.bukkit.event.world.ChunkUnloadEvent;
import com.intellectualcrafters.plot.PlotSquared; import com.intellectualcrafters.plot.PlotSquared;
import com.intellectualcrafters.plot.config.Settings; import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.util.TaskManager;
public class ChunkListener implements Listener { public class ChunkListener implements Listener {
@EventHandler @EventHandler
public void onChunkUnload(ChunkUnloadEvent event) { public void onChunkUnload(ChunkUnloadEvent event) {
processChunk(event.getChunk()); if (!forceUnload) {
if (processChunk(event.getChunk(), true)) {
event.setCancelled(true);
}
}
} }
@EventHandler @EventHandler
public void onChunkLoad(ChunkLoadEvent event) { public void onChunkLoad(ChunkLoadEvent event) {
processChunk(event.getChunk()); processChunk(event.getChunk(), false);
}
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);
} }
public void processChunk(Chunk chunk) { private boolean forceUnload = false;
public boolean processChunk(Chunk chunk, boolean unload) {
if (!PlotSquared.isPlotWorld(chunk.getWorld().getName())) { if (!PlotSquared.isPlotWorld(chunk.getWorld().getName())) {
return; return false;
} }
Entity[] entities = chunk.getEntities(); Entity[] entities = chunk.getEntities();
BlockState[] tiles = chunk.getTileEntities(); BlockState[] tiles = chunk.getTileEntities();
if (tiles.length > Settings.CHUNK_PROCESSOR_MAX_BLOCKSTATES) { 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) { for (BlockState tile : tiles) {
tile.getBlock().setType(Material.AIR, false); tile.getBlock().setType(Material.AIR, false);
} }
} }
if (entities.length > Settings.CHUNK_PROCESSOR_MAX_ENTITIES) { if (entities.length > Settings.CHUNK_PROCESSOR_MAX_ENTITIES) {
if (unload) {
System.out.print("FORCE UNLOAD");
chunk.load(true);
return false;
}
for (Entity ent : entities) { for (Entity ent : entities) {
ent.remove(); ent.remove();
} }
} }
return false;
} }
} }