Chat / Merge blocks placer / generator

This commit is contained in:
Jesse Boyd
2016-06-13 14:47:50 +10:00
parent 506455ae40
commit 4f0ede646e
71 changed files with 4523 additions and 4959 deletions

View File

@ -11,13 +11,12 @@ import com.intellectualcrafters.plot.util.ChunkManager;
import com.intellectualcrafters.plot.util.EconHandler;
import com.intellectualcrafters.plot.util.EventUtil;
import com.intellectualcrafters.plot.util.InventoryUtil;
import com.intellectualcrafters.plot.util.PlotQueue;
import com.intellectualcrafters.plot.util.SchematicHandler;
import com.intellectualcrafters.plot.util.SetupUtils;
import com.intellectualcrafters.plot.util.TaskManager;
import com.intellectualcrafters.plot.util.UUIDHandlerImplementation;
import com.intellectualcrafters.plot.util.WorldUtil;
import com.intellectualcrafters.plot.util.block.QueueProvider;
import java.io.File;
import java.util.List;
@ -135,10 +134,10 @@ public interface IPlotMain extends ILogger {
EconHandler getEconomyHandler();
/**
* Get the {@link PlotQueue} class.
* Get the {@link com.intellectualcrafters.plot.util.block.QueueProvider} class.
* @return
*/
PlotQueue initPlotQueue();
QueueProvider initBlockQueue();
/**
* Get the {@link WorldUtil} class.

View File

@ -39,18 +39,17 @@ import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.MathMan;
import com.intellectualcrafters.plot.util.ReflectionUtils;
import com.intellectualcrafters.plot.util.SchematicHandler;
import com.intellectualcrafters.plot.util.SetQueue;
import com.intellectualcrafters.plot.util.SetupUtils;
import com.intellectualcrafters.plot.util.StringMan;
import com.intellectualcrafters.plot.util.TaskManager;
import com.intellectualcrafters.plot.util.UUIDHandler;
import com.intellectualcrafters.plot.util.WorldUtil;
import com.intellectualcrafters.plot.util.area.QuadMap;
import com.intellectualcrafters.plot.util.block.GlobalBlockQueue;
import com.intellectualcrafters.plot.util.expiry.ExpireManager;
import com.intellectualcrafters.plot.util.expiry.ExpiryTask;
import com.plotsquared.listener.WESubscriber;
import com.sk89q.worldedit.WorldEdit;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@ -112,7 +111,6 @@ public class PS {
public YamlConfiguration worlds;
public YamlConfiguration storage;
public YamlConfiguration commands;
public TaskManager TASK;
public WorldEdit worldedit;
public URL update;
private ILogger logger;
@ -153,7 +151,7 @@ public class PS {
if (getJavaVersion() < 1.8) {
PS.log(C.CONSOLE_JAVA_OUTDATED_1_8);
}
this.TASK = this.IMP.getTaskManager();
TaskManager.IMP = this.IMP.getTaskManager();
setupConfigs();
this.translationFile =
MainUtil.getFile(this.IMP.getDirectory(), Settings.Paths.TRANSLATIONS + File.separator + "PlotSquared.use_THIS.yml");
@ -219,7 +217,8 @@ public class PS {
// World Util
WorldUtil.IMP = this.IMP.initWorldUtil();
// Set block
SetQueue.IMP.queue = this.IMP.initPlotQueue();
GlobalBlockQueue.IMP = new GlobalBlockQueue(IMP.initBlockQueue(), 1);
GlobalBlockQueue.IMP.runTask();
// Set chunk
ChunkManager.manager = this.IMP.initChunkManager();
// Schematic handler
@ -1802,7 +1801,7 @@ public class PS {
*/
public void disable() {
try {
this.TASK = null;
TaskManager.IMP = null;
this.database = null;
// Validate that all data in the db is correct
final HashSet<Plot> plots = new HashSet<>();

View File

@ -10,7 +10,7 @@ import com.intellectualcrafters.plot.object.RunnableVal2;
import com.intellectualcrafters.plot.object.RunnableVal3;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.Permissions;
import com.intellectualcrafters.plot.util.SetQueue;
import com.intellectualcrafters.plot.util.block.GlobalBlockQueue;
import com.plotsquared.general.commands.Command;
import com.plotsquared.general.commands.CommandDeclaration;
@ -45,7 +45,7 @@ public class Clear extends Command {
@Override
public void run() {
plot.unlink();
SetQueue.IMP.addTask(new Runnable() {
GlobalBlockQueue.IMP.addTask(new Runnable() {
@Override
public void run() {
plot.removeRunning();

View File

@ -27,18 +27,17 @@ import com.intellectualcrafters.plot.util.EventUtil;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.MathMan;
import com.intellectualcrafters.plot.util.SchematicHandler;
import com.intellectualcrafters.plot.util.SetQueue;
import com.intellectualcrafters.plot.util.SetupUtils;
import com.intellectualcrafters.plot.util.StringMan;
import com.intellectualcrafters.plot.util.TaskManager;
import com.intellectualcrafters.plot.util.UUIDHandler;
import com.intellectualcrafters.plot.util.WorldUtil;
import com.intellectualcrafters.plot.util.block.GlobalBlockQueue;
import com.intellectualcrafters.plot.util.expiry.ExpireManager;
import com.intellectualcrafters.plot.util.expiry.PlotAnalysis;
import com.plotsquared.general.commands.Command;
import com.plotsquared.general.commands.CommandDeclaration;
import com.plotsquared.listener.WEManager;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@ -48,7 +47,6 @@ import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
@ -119,12 +117,12 @@ public class DebugExec extends SubCommand {
// Instances
this.scope.put("PS", PS.get());
this.scope.put("SetQueue", SetQueue.IMP);
this.scope.put("GlobalBlockQueue", GlobalBlockQueue.IMP);
this.scope.put("ExpireManager", ExpireManager.IMP);
if (PS.get().worldedit != null) {
this.scope.put("WEManager", new WEManager());
}
this.scope.put("TaskManager", PS.get().TASK);
this.scope.put("TaskManager", TaskManager.IMP);
this.scope.put("TitleManager", AbstractTitle.TITLE_CLASS);
this.scope.put("ConsolePlayer", ConsolePlayer.getConsole());
this.scope.put("SchematicHandler", SchematicHandler.manager);

View File

@ -8,8 +8,7 @@ import com.intellectualcrafters.plot.object.RunnableVal;
import com.intellectualcrafters.plot.object.RunnableVal2;
import com.intellectualcrafters.plot.object.RunnableVal3;
import com.intellectualcrafters.plot.util.ChunkManager;
import com.intellectualcrafters.plot.util.PlotChunk;
import com.intellectualcrafters.plot.util.SetQueue;
import com.intellectualcrafters.plot.util.block.LocalBlockQueue;
import com.plotsquared.general.commands.Command;
import com.plotsquared.general.commands.CommandDeclaration;
import java.util.HashSet;
@ -28,12 +27,11 @@ public class Relight extends Command {
return;
}
HashSet<RegionWrapper> regions = plot.getRegions();
final LocalBlockQueue queue = plot.getArea().getQueue(false);
ChunkManager.chunkTask(plot, new RunnableVal<int[]>() {
@Override
public void run(int[] value) {
SetQueue.ChunkWrapper cw = SetQueue.IMP.new ChunkWrapper(plot.getArea().worldname, value[0], value[1]);
PlotChunk<?> pc = SetQueue.IMP.queue.getChunk(cw);
pc.fixLighting();
queue.fixChunkLighting(value[0], value[1]);
}
}, new Runnable() {
@Override

View File

@ -12,10 +12,10 @@ import com.intellectualcrafters.plot.object.PlotManager;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.Permissions;
import com.intellectualcrafters.plot.util.SetQueue;
import com.intellectualcrafters.plot.util.StringComparison;
import com.intellectualcrafters.plot.util.StringMan;
import com.intellectualcrafters.plot.util.WorldUtil;
import com.intellectualcrafters.plot.util.block.GlobalBlockQueue;
import com.plotsquared.general.commands.Command;
import com.plotsquared.general.commands.CommandDeclaration;
@ -114,7 +114,7 @@ public class Set extends SubCommand {
current.setComponent(component, blocks);
}
MainUtil.sendMessage(player, C.GENERATING_COMPONENT);
SetQueue.IMP.addTask(new Runnable() {
GlobalBlockQueue.IMP.addTask(new Runnable() {
@Override
public void run() {
plot.removeRunning();

View File

@ -13,12 +13,11 @@ import com.intellectualcrafters.plot.object.PlotManager;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.SetupObject;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.SetQueue;
import com.intellectualcrafters.plot.util.SetupUtils;
import com.intellectualcrafters.plot.util.TaskManager;
import com.intellectualcrafters.plot.util.WorldUtil;
import com.intellectualcrafters.plot.util.block.GlobalBlockQueue;
import com.plotsquared.general.commands.CommandDeclaration;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@ -156,7 +155,7 @@ public class Template extends SubCommand {
setup.step = new ConfigurationNode[0];
setup.world = world;
SetupUtils.manager.setupWorld(setup);
SetQueue.IMP.addTask(new Runnable() {
GlobalBlockQueue.IMP.addTask(new Runnable() {
@Override
public void run() {
MainUtil.sendMessage(player, "Done!");

View File

@ -13,6 +13,8 @@ import com.intellectualcrafters.plot.util.ChunkManager;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.TaskManager;
import com.intellectualcrafters.plot.util.WorldUtil;
import com.intellectualcrafters.plot.util.block.GlobalBlockQueue;
import com.intellectualcrafters.plot.util.block.LocalBlockQueue;
import com.plotsquared.general.commands.CommandDeclaration;
import java.io.File;
@ -189,10 +191,11 @@ public class Trim extends SubCommand {
}
}
}
final LocalBlockQueue queue = GlobalBlockQueue.IMP.getNewQueue(world, false);
TaskManager.objectTask(chunks, new RunnableVal<ChunkLoc>() {
@Override
public void run(ChunkLoc value) {
ChunkManager.manager.regenerateChunk(world, value);
queue.regenChunk(value.x, value.z);
}
}, this);
}

View File

@ -1,16 +1,16 @@
package com.intellectualcrafters.plot.generator;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.object.LazyResult;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.PlotBlock;
import com.intellectualcrafters.plot.object.PlotManager;
import com.intellectualcrafters.plot.object.PseudoRandom;
import com.intellectualcrafters.plot.object.RegionWrapper;
import com.intellectualcrafters.plot.util.PlotChunk;
import com.intellectualcrafters.plot.util.SetQueue;
import com.intellectualcrafters.plot.util.SetQueue.ChunkWrapper;
import com.intellectualcrafters.plot.util.block.DelegateLocalBlockQueue;
import com.intellectualcrafters.plot.util.block.GlobalBlockQueue;
import com.intellectualcrafters.plot.util.block.LocalBlockQueue;
import com.intellectualcrafters.plot.util.block.ScopedLocalBlockQueue;
import java.util.Set;
public class AugmentedUtils {
@ -23,18 +23,10 @@ public class AugmentedUtils {
enabled = true;
}
public static boolean generate(final String world, final int cx, final int cz, LazyResult<PlotChunk<?>> lazyChunk) {
public static boolean generate(final String world, final int cx, final int cz, LocalBlockQueue queue) {
if (!enabled) {
return false;
}
if (lazyChunk == null) {
lazyChunk = new LazyResult<PlotChunk<?>>() {
@Override
public PlotChunk<?> create() {
return SetQueue.IMP.queue.getChunk(SetQueue.IMP.new ChunkWrapper(world, cx, cz));
}
};
}
final int bx = cx << 4;
final int bz = cz << 4;
RegionWrapper region = new RegionWrapper(bx, bx + 15, bz, bz + 15);
@ -44,7 +36,6 @@ public class AugmentedUtils {
}
PseudoRandom r = new PseudoRandom();
r.state = (cx << 16) | (cz & 0xFFFF);
ChunkWrapper wrap = SetQueue.IMP.new ChunkWrapper(world, cx, cz);
boolean toReturn = false;
for (final PlotArea area : areas) {
if (area.TYPE == 0) {
@ -57,8 +48,11 @@ public class AugmentedUtils {
if (generator == null) {
continue;
}
final PlotChunk<?> result = lazyChunk.getOrCreate();
final PlotChunk<?> primaryMask;
// Mask
if (queue == null) {
queue = GlobalBlockQueue.IMP.getNewQueue(world, false);
}
LocalBlockQueue primaryMask;
// coords
int bxx;
int bzz;
@ -70,42 +64,29 @@ public class AugmentedUtils {
bzz = Math.max(0, area.getRegion().minZ - bz);
txx = Math.min(15, area.getRegion().maxX - bx);
tzz = Math.min(15, area.getRegion().maxZ - bz);
primaryMask = new PlotChunk<Object>(wrap) {
primaryMask = new DelegateLocalBlockQueue(queue) {
@Override
public Object getChunkAbs() {
return null;
}
@Override
public void setBlock(int x, int y, int z, int id, byte data) {
if (area.contains(bx + x, bz + z)) {
result.setBlock(x, y, z, id, data);
public boolean setBlock(int x, int y, int z, int id, int data) {
if (area.contains(x, z)) {
return super.setBlock(x, y, z, id, data);
}
return false;
}
@Override
public void setBiome(int x, int z, int biome) {
if (area.contains(bx + x, bz + z)) {
result.setBiome(x, z, biome);
public boolean setBiome(int x, int z, String biome) {
if (area.contains(x, z)) {
return super.setBiome(x, z, biome);
}
}
@Override
public PlotChunk clone() {
return null;
}
@Override
public PlotChunk shallowClone() {
return null;
return false;
}
};
} else {
bxx = bzz = 0;
txx = tzz = 15;
primaryMask = result;
primaryMask = queue;
}
PlotChunk<?> secondaryMask;
LocalBlockQueue secondaryMask;
PlotBlock air = PlotBlock.get((short) 0, (byte) 0);
if (area.TERRAIN == 2) {
PlotManager manager = area.getPlotManager();
@ -118,7 +99,7 @@ public class AugmentedUtils {
boolean can = manager.getPlotId(area, rx, 0, rz) == null;
if (can) {
for (int y = 1; y < 128; y++) {
result.setBlock(x, y, z, air);
queue.setBlock(x, y, z, air);
}
canPlace[x][z] = can;
has = true;
@ -129,30 +110,18 @@ public class AugmentedUtils {
continue;
}
toReturn = true;
secondaryMask = new PlotChunk<Object>(wrap) {
secondaryMask = new DelegateLocalBlockQueue(primaryMask) {
@Override
public Object getChunkAbs() {
return null;
}
@Override
public void setBlock(int x, int y, int z, int id, byte data) {
public boolean setBlock(int x, int y, int z, int id, int data) {
if (canPlace[x][z]) {
primaryMask.setBlock(x, y, z, id, data);
return super.setBlock(x, y, z, id, data);
}
return false;
}
@Override
public void setBiome(int x, int z, int biome) {}
@Override
public PlotChunk clone() {
return null;
}
@Override
public PlotChunk shallowClone() {
return null;
public boolean setBiome(int x, int y, String biome) {
return super.setBiome(x, y, biome);
}
};
} else {
@ -160,19 +129,17 @@ public class AugmentedUtils {
for (int x = bxx; x <= txx; x++) {
for (int z = bzz; z <= tzz; z++) {
for (int y = 1; y < 128; y++) {
result.setBlock(x, y, z, air);
queue.setBlock(x, y, z, air);
}
}
}
toReturn = true;
}
generator.generateChunk(secondaryMask, area, r);
generator.populateChunk(secondaryMask, area, r);
}
if (lazyChunk.get() != null) {
lazyChunk.get().addToQueue();
lazyChunk.get().flush(false);
ScopedLocalBlockQueue scoped = new ScopedLocalBlockQueue(secondaryMask, new Location(area.worldname, bx, 0, bz), new Location(area.worldname, bx + 15, 255, bz + 15));
generator.generateChunk(scoped, area, r);
generator.populateChunk(scoped, area, r);
}
queue.flush();
return toReturn;
}
}

View File

@ -7,9 +7,8 @@ import com.intellectualcrafters.plot.object.PlotBlock;
import com.intellectualcrafters.plot.object.PlotId;
import com.intellectualcrafters.plot.object.PseudoRandom;
import com.intellectualcrafters.plot.object.RegionWrapper;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.SetQueue;
import com.intellectualcrafters.plot.util.block.GlobalBlockQueue;
import com.intellectualcrafters.plot.util.block.LocalBlockQueue;
import java.util.ArrayList;
/**
@ -55,20 +54,22 @@ public class ClassicPlotManager extends SquarePlotManager {
if (dpw.WALL_BLOCK.id != 0 || !dpw.WALL_BLOCK.equals(dpw.CLAIMED_WALL_BLOCK)) {
setWall(dpw, plot.getId(), new PlotBlock[]{dpw.WALL_BLOCK});
}
SetQueue.IMP.addTask(whenDone);
GlobalBlockQueue.IMP.addTask(whenDone);
return true;
}
public boolean setFloor(PlotArea plotArea, PlotId plotId, PlotBlock[] blocks) {
Plot plot = plotArea.getPlotAbs(plotId);
LocalBlockQueue queue = plotArea.getQueue(false);
if (plot.isBasePlot()) {
ClassicPlotWorld dpw = (ClassicPlotWorld) plotArea;
for (RegionWrapper region : plot.getRegions()) {
Location pos1 = new Location(plotArea.worldname, region.minX, dpw.PLOT_HEIGHT, region.minZ);
Location pos2 = new Location(plotArea.worldname, region.maxX, dpw.PLOT_HEIGHT, region.maxZ);
MainUtil.setCuboidAsync(plotArea.worldname, pos1, pos2, blocks);
queue.setCuboid(pos1, pos2, blocks);
}
}
queue.enqueue();
return true;
}
@ -77,11 +78,13 @@ public class ClassicPlotManager extends SquarePlotManager {
if (!plot.isBasePlot()) {
return false;
}
LocalBlockQueue queue = plotArea.getQueue(false);
for (RegionWrapper region : plot.getRegions()) {
Location pos1 = new Location(plotArea.worldname, region.minX, 1, region.minZ);
Location pos2 = new Location(plotArea.worldname, region.maxX, 255, region.maxZ);
MainUtil.setCuboidAsync(plotArea.worldname, pos1, pos2, blocks);
queue.setCuboid(pos1, pos2, blocks);
}
queue.enqueue();
return true;
}
@ -91,11 +94,13 @@ public class ClassicPlotManager extends SquarePlotManager {
return false;
}
ClassicPlotWorld dpw = (ClassicPlotWorld) plotArea;
LocalBlockQueue queue = plotArea.getQueue(false);
for (RegionWrapper region : plot.getRegions()) {
Location pos1 = new Location(plotArea.worldname, region.minX, dpw.PLOT_HEIGHT + 1, region.minZ);
Location pos2 = new Location(plotArea.worldname, region.maxX, 255, region.maxZ);
MainUtil.setCuboidAsync(plotArea.worldname, pos1, pos2, blocks);
queue.setCuboid(pos1, pos2, blocks);
}
queue.enqueue();
return true;
}
@ -105,11 +110,13 @@ public class ClassicPlotManager extends SquarePlotManager {
return false;
}
ClassicPlotWorld dpw = (ClassicPlotWorld) plotArea;
LocalBlockQueue queue = plotArea.getQueue(false);
for (RegionWrapper region : plot.getRegions()) {
Location pos1 = new Location(plotArea.worldname, region.minX, 1, region.minZ);
Location pos2 = new Location(plotArea.worldname, region.maxX, dpw.PLOT_HEIGHT - 1, region.maxZ);
MainUtil.setCuboidAsync(plotArea.worldname, pos1, pos2, blocks);
queue.setCuboid(pos1, pos2, blocks);
}
queue.enqueue();
return true;
}
@ -120,8 +127,10 @@ public class ClassicPlotManager extends SquarePlotManager {
}
Location[] corners = plot.getCorners();
ClassicPlotWorld dpw = (ClassicPlotWorld) plotArea;
SetQueue.IMP.setBlock(plotArea.worldname, (corners[0].getX() + corners[1].getX()) / 2, dpw.PLOT_HEIGHT,
LocalBlockQueue queue = plotArea.getQueue(false);
queue.setBlock((corners[0].getX() + corners[1].getX()) / 2, dpw.PLOT_HEIGHT,
(corners[0].getZ() + corners[1].getZ()) / 2, blocks[0]);
queue.enqueue();
return true;
}
@ -134,11 +143,12 @@ public class ClassicPlotManager extends SquarePlotManager {
Location bottom = plot.getBottomAbs();
Location top = plot.getExtendedTopAbs();
PseudoRandom random = new PseudoRandom();
LocalBlockQueue queue = plotArea.getQueue(false);
if (!plot.getMerged(0)) {
int z = bottom.getZ();
for (int x = bottom.getX(); x <= top.getX(); x++) {
for (int y = dpw.PLOT_HEIGHT; y <= 255; y++) {
SetQueue.IMP.setBlock(plotArea.worldname, x, y, z, blocks[random.random(blocks.length)]);
queue.setBlock(x, y, z, blocks[random.random(blocks.length)]);
}
}
}
@ -146,7 +156,7 @@ public class ClassicPlotManager extends SquarePlotManager {
int x = bottom.getX();
for (int z = bottom.getZ(); z <= top.getZ(); z++) {
for (int y = dpw.PLOT_HEIGHT; y <= 255; y++) {
SetQueue.IMP.setBlock(plotArea.worldname, x, y, z, blocks[random.random(blocks.length)]);
queue.setBlock(x, y, z, blocks[random.random(blocks.length)]);
}
}
}
@ -155,7 +165,7 @@ public class ClassicPlotManager extends SquarePlotManager {
int z = top.getZ();
for (int x = bottom.getX(); x <= top.getX(); x++) {
for (int y = dpw.PLOT_HEIGHT; y <= 255; y++) {
SetQueue.IMP.setBlock(plotArea.worldname, x, y, z, blocks[random.random(blocks.length)]);
queue.setBlock(x, y, z, blocks[random.random(blocks.length)]);
}
}
}
@ -163,7 +173,7 @@ public class ClassicPlotManager extends SquarePlotManager {
int x = top.getX();
for (int z = bottom.getZ(); z <= top.getZ(); z++) {
for (int y = dpw.PLOT_HEIGHT; y <= 255; y++) {
SetQueue.IMP.setBlock(plotArea.worldname, x, y, z, blocks[random.random(blocks.length)]);
queue.setBlock(x, y, z, blocks[random.random(blocks.length)]);
}
}
}
@ -171,9 +181,10 @@ public class ClassicPlotManager extends SquarePlotManager {
for (RegionWrapper region : plot.getRegions()) {
Location pos1 = new Location(plotArea.worldname, region.minX, 255, region.minZ);
Location pos2 = new Location(plotArea.worldname, region.maxX, 255, region.maxZ);
MainUtil.setCuboidAsync(plotArea.worldname, pos1, pos2, blocks);
queue.setCuboid(pos1, pos2, blocks);
}
}
queue.enqueue();
return true;
}
@ -186,11 +197,12 @@ public class ClassicPlotManager extends SquarePlotManager {
Location bot = plot.getExtendedBottomAbs().subtract(plot.getMerged(3) ? 0 : 1, 0, plot.getMerged(0) ? 0 : 1);
Location top = plot.getExtendedTopAbs().add(1, 0, 1);
PseudoRandom random = new PseudoRandom();
LocalBlockQueue queue = plotArea.getQueue(false);
if (!plot.getMerged(0)) {
int z = bot.getZ();
for (int x = bot.getX(); x < top.getX(); x++) {
for (int y = 1; y <= dpw.WALL_HEIGHT; y++) {
SetQueue.IMP.setBlock(plotArea.worldname, x, y, z, blocks[random.random(blocks.length)]);
queue.setBlock(x, y, z, blocks[random.random(blocks.length)]);
}
}
}
@ -198,7 +210,7 @@ public class ClassicPlotManager extends SquarePlotManager {
int x = bot.getX();
for (int z = bot.getZ(); z < top.getZ(); z++) {
for (int y = 1; y <= dpw.WALL_HEIGHT; y++) {
SetQueue.IMP.setBlock(plotArea.worldname, x, y, z, blocks[random.random(blocks.length)]);
queue.setBlock(x, y, z, blocks[random.random(blocks.length)]);
}
}
}
@ -206,7 +218,7 @@ public class ClassicPlotManager extends SquarePlotManager {
int z = top.getZ();
for (int x = bot.getX(); x < top.getX() + (plot.getMerged(1) ? 0 : 1); x++) {
for (int y = 1; y <= dpw.WALL_HEIGHT; y++) {
SetQueue.IMP.setBlock(plotArea.worldname, x, y, z, blocks[random.random(blocks.length)]);
queue.setBlock(x, y, z, blocks[random.random(blocks.length)]);
}
}
}
@ -214,10 +226,11 @@ public class ClassicPlotManager extends SquarePlotManager {
int x = top.getX();
for (int z = bot.getZ(); z < top.getZ() + (plot.getMerged(2) ? 0 : 1); z++) {
for (int y = 1; y <= dpw.WALL_HEIGHT; y++) {
SetQueue.IMP.setBlock(plotArea.worldname, x, y, z, blocks[random.random(blocks.length)]);
queue.setBlock(x, y, z, blocks[random.random(blocks.length)]);
}
}
}
queue.enqueue();
return true;
}
@ -230,31 +243,33 @@ public class ClassicPlotManager extends SquarePlotManager {
Location bot = plot.getExtendedBottomAbs().subtract(plot.getMerged(3) ? 0 : 1, 0, plot.getMerged(0) ? 0 : 1);
Location top = plot.getExtendedTopAbs().add(1, 0, 1);
PseudoRandom random = new PseudoRandom();
LocalBlockQueue queue = plotArea.getQueue(false);
int y = dpw.WALL_HEIGHT + 1;
if (!plot.getMerged(0)) {
int z = bot.getZ();
for (int x = bot.getX(); x < top.getX(); x++) {
SetQueue.IMP.setBlock(plotArea.worldname, x, y, z, blocks[random.random(blocks.length)]);
queue.setBlock(x, y, z, blocks[random.random(blocks.length)]);
}
}
if (!plot.getMerged(3)) {
int x = bot.getX();
for (int z = bot.getZ(); z < top.getZ(); z++) {
SetQueue.IMP.setBlock(plotArea.worldname, x, y, z, blocks[random.random(blocks.length)]);
queue.setBlock(x, y, z, blocks[random.random(blocks.length)]);
}
}
if (!plot.getMerged(2)) {
int z = top.getZ();
for (int x = bot.getX(); x < top.getX() + (plot.getMerged(1) ? 0 : 1); x++) {
SetQueue.IMP.setBlock(plotArea.worldname, x, y, z, blocks[random.random(blocks.length)]);
queue.setBlock(x, y, z, blocks[random.random(blocks.length)]);
}
}
if (!plot.getMerged(1)) {
int x = top.getX();
for (int z = bot.getZ(); z < top.getZ() + (plot.getMerged(2) ? 0 : 1); z++) {
SetQueue.IMP.setBlock(plotArea.worldname, x, y, z, blocks[random.random(blocks.length)]);
queue.setBlock(x, y, z, blocks[random.random(blocks.length)]);
}
}
queue.enqueue();
return true;
}
@ -270,24 +285,26 @@ public class ClassicPlotManager extends SquarePlotManager {
int ex = sx + dpw.ROAD_WIDTH - 1;
int sz = pos1.getZ() - 2;
int ez = pos2.getZ() + 2;
MainUtil.setSimpleCuboidAsync(plotArea.worldname,
LocalBlockQueue queue = plotArea.getQueue(false);
queue.setCuboid(
new Location(plotArea.worldname, sx, Math.min(dpw.WALL_HEIGHT, dpw.ROAD_HEIGHT) + 1, sz + 1),
new Location(plotArea.worldname, ex, 255, ez - 1), PlotBlock.get((short) 0, (byte) 0));
MainUtil.setSimpleCuboidAsync(plotArea.worldname, new Location(plotArea.worldname, sx, 0, sz + 1),
queue.setCuboid(new Location(plotArea.worldname, sx, 0, sz + 1),
new Location(plotArea.worldname, ex, 0, ez - 1), PlotBlock.get((short) 7,
(byte) 0));
MainUtil.setSimpleCuboidAsync(plotArea.worldname, new Location(plotArea.worldname, sx, 1, sz + 1),
queue.setCuboid(new Location(plotArea.worldname, sx, 1, sz + 1),
new Location(plotArea.worldname, sx, dpw.WALL_HEIGHT, ez - 1), dpw.WALL_FILLING);
MainUtil.setSimpleCuboidAsync(plotArea.worldname, new Location(plotArea.worldname, sx, dpw.WALL_HEIGHT + 1, sz + 1),
queue.setCuboid(new Location(plotArea.worldname, sx, dpw.WALL_HEIGHT + 1, sz + 1),
new Location(plotArea.worldname, sx, dpw.WALL_HEIGHT + 1, ez - 1),
dpw.WALL_BLOCK);
MainUtil.setSimpleCuboidAsync(plotArea.worldname, new Location(plotArea.worldname, ex, 1, sz + 1),
queue.setCuboid(new Location(plotArea.worldname, ex, 1, sz + 1),
new Location(plotArea.worldname, ex, dpw.WALL_HEIGHT, ez - 1), dpw.WALL_FILLING);
MainUtil.setSimpleCuboidAsync(plotArea.worldname, new Location(plotArea.worldname, ex, dpw.WALL_HEIGHT + 1, sz + 1),
queue.setCuboid(new Location(plotArea.worldname, ex, dpw.WALL_HEIGHT + 1, sz + 1),
new Location(plotArea.worldname, ex, dpw.WALL_HEIGHT + 1, ez - 1),
dpw.WALL_BLOCK);
MainUtil.setSimpleCuboidAsync(plotArea.worldname, new Location(plotArea.worldname, sx + 1, 1, sz + 1),
queue.setCuboid(new Location(plotArea.worldname, sx + 1, 1, sz + 1),
new Location(plotArea.worldname, ex - 1, dpw.ROAD_HEIGHT, ez - 1), dpw.ROAD_BLOCK);
queue.enqueue();
return true;
}
@ -300,23 +317,25 @@ public class ClassicPlotManager extends SquarePlotManager {
int ez = sz + dpw.ROAD_WIDTH - 1;
int sx = pos1.getX() - 2;
int ex = pos2.getX() + 2;
MainUtil.setSimpleCuboidAsync(plotArea.worldname,
LocalBlockQueue queue = plotArea.getQueue(false);
queue.setCuboid(
new Location(plotArea.worldname, sx + 1, Math.min(dpw.WALL_HEIGHT, dpw.ROAD_HEIGHT) + 1, sz),
new Location(plotArea.worldname, ex - 1, 255, ez), PlotBlock.get((short) 0, (byte) 0));
MainUtil.setSimpleCuboidAsync(plotArea.worldname, new Location(plotArea.worldname, sx + 1, 0, sz),
queue.setCuboid(new Location(plotArea.worldname, sx + 1, 0, sz),
new Location(plotArea.worldname, ex - 1, 0, ez), PlotBlock.get((short) 7, (byte) 0));
MainUtil.setSimpleCuboidAsync(plotArea.worldname, new Location(plotArea.worldname, sx + 1, 1, sz),
queue.setCuboid(new Location(plotArea.worldname, sx + 1, 1, sz),
new Location(plotArea.worldname, ex - 1, dpw.WALL_HEIGHT, sz), dpw.WALL_FILLING);
MainUtil.setSimpleCuboidAsync(plotArea.worldname, new Location(plotArea.worldname, sx + 1, dpw.WALL_HEIGHT + 1, sz),
queue.setCuboid(new Location(plotArea.worldname, sx + 1, dpw.WALL_HEIGHT + 1, sz),
new Location(plotArea.worldname, ex - 1, dpw.WALL_HEIGHT + 1, sz),
dpw.WALL_BLOCK);
MainUtil.setSimpleCuboidAsync(plotArea.worldname, new Location(plotArea.worldname, sx + 1, 1, ez),
queue.setCuboid(new Location(plotArea.worldname, sx + 1, 1, ez),
new Location(plotArea.worldname, ex - 1, dpw.WALL_HEIGHT, ez), dpw.WALL_FILLING);
MainUtil.setSimpleCuboidAsync(plotArea.worldname, new Location(plotArea.worldname, sx + 1, dpw.WALL_HEIGHT + 1, ez),
queue.setCuboid(new Location(plotArea.worldname, sx + 1, dpw.WALL_HEIGHT + 1, ez),
new Location(plotArea.worldname, ex - 1, dpw.WALL_HEIGHT + 1, ez),
dpw.WALL_BLOCK);
MainUtil.setSimpleCuboidAsync(plotArea.worldname, new Location(plotArea.worldname, sx + 1, 1, sz + 1),
queue.setCuboid(new Location(plotArea.worldname, sx + 1, 1, sz + 1),
new Location(plotArea.worldname, ex - 1, dpw.ROAD_HEIGHT, ez - 1), dpw.ROAD_BLOCK);
queue.enqueue();
return true;
}
@ -328,13 +347,15 @@ public class ClassicPlotManager extends SquarePlotManager {
int ex = sx + dpw.ROAD_WIDTH - 1;
int sz = pos2.getZ() + 1;
int ez = sz + dpw.ROAD_WIDTH - 1;
MainUtil.setSimpleCuboidAsync(plotArea.worldname, new Location(plotArea.worldname, sx + 1, dpw.ROAD_HEIGHT + 1, sz + 1),
LocalBlockQueue queue = plotArea.getQueue(false);
queue.setCuboid(new Location(plotArea.worldname, sx + 1, dpw.ROAD_HEIGHT + 1, sz + 1),
new Location(plotArea.worldname, ex - 1, 255, ez - 1), PlotBlock.get(
(short) 0, (byte) 0));
MainUtil.setSimpleCuboidAsync(plotArea.worldname, new Location(plotArea.worldname, sx + 1, 0, sz + 1),
queue.setCuboid(new Location(plotArea.worldname, sx + 1, 0, sz + 1),
new Location(plotArea.worldname, ex - 1, 0, ez - 1), PlotBlock.get((short) 7, (byte) 0));
MainUtil.setSimpleCuboidAsync(plotArea.worldname, new Location(plotArea.worldname, sx + 1, 1, sz + 1),
queue.setCuboid(new Location(plotArea.worldname, sx + 1, 1, sz + 1),
new Location(plotArea.worldname, ex - 1, dpw.ROAD_HEIGHT, ez - 1), dpw.ROAD_BLOCK);
queue.enqueue();
return true;
}
@ -347,12 +368,14 @@ public class ClassicPlotManager extends SquarePlotManager {
int ex = sx + dpw.ROAD_WIDTH - 1;
int sz = pos1.getZ() - 1;
int ez = pos2.getZ() + 1;
MainUtil.setSimpleCuboidAsync(plotArea.worldname, new Location(plotArea.worldname, sx, Math.min(dpw.PLOT_HEIGHT, dpw.ROAD_HEIGHT) + 1, sz),
LocalBlockQueue queue = plotArea.getQueue(false);
queue.setCuboid(new Location(plotArea.worldname, sx, Math.min(dpw.PLOT_HEIGHT, dpw.ROAD_HEIGHT) + 1, sz),
new Location(plotArea.worldname, ex, 255, ez), PlotBlock.get((short) 0, (byte) 0));
MainUtil.setCuboidAsync(plotArea.worldname, new Location(plotArea.worldname, sx, 1, sz + 1),
queue.setCuboid(new Location(plotArea.worldname, sx, 1, sz + 1),
new Location(plotArea.worldname, ex, dpw.PLOT_HEIGHT - 1, ez - 1), dpw.MAIN_BLOCK);
MainUtil.setCuboidAsync(plotArea.worldname, new Location(plotArea.worldname, sx, dpw.PLOT_HEIGHT, sz + 1),
queue.setCuboid(new Location(plotArea.worldname, sx, dpw.PLOT_HEIGHT, sz + 1),
new Location(plotArea.worldname, ex, dpw.PLOT_HEIGHT, ez - 1), dpw.TOP_BLOCK);
queue.enqueue();
return true;
}
@ -365,12 +388,14 @@ public class ClassicPlotManager extends SquarePlotManager {
int ez = sz + dpw.ROAD_WIDTH - 1;
int sx = pos1.getX() - 1;
int ex = pos2.getX() + 1;
MainUtil.setSimpleCuboidAsync(plotArea.worldname, new Location(plotArea.worldname, sx, Math.min(dpw.PLOT_HEIGHT, dpw.ROAD_HEIGHT) + 1, sz),
LocalBlockQueue queue = plotArea.getQueue(false);
queue.setCuboid(new Location(plotArea.worldname, sx, Math.min(dpw.PLOT_HEIGHT, dpw.ROAD_HEIGHT) + 1, sz),
new Location(plotArea.worldname, ex, 255, ez), PlotBlock.get((short) 0, (byte) 0));
MainUtil.setCuboidAsync(plotArea.worldname, new Location(plotArea.worldname, sx + 1, 1, sz),
queue.setCuboid(new Location(plotArea.worldname, sx + 1, 1, sz),
new Location(plotArea.worldname, ex - 1, dpw.PLOT_HEIGHT - 1, ez), dpw.MAIN_BLOCK);
MainUtil.setCuboidAsync(plotArea.worldname, new Location(plotArea.worldname, sx + 1, dpw.PLOT_HEIGHT, sz),
queue.setCuboid(new Location(plotArea.worldname, sx + 1, dpw.PLOT_HEIGHT, sz),
new Location(plotArea.worldname, ex - 1, dpw.PLOT_HEIGHT, ez), dpw.TOP_BLOCK);
queue.enqueue();
return true;
}
@ -382,12 +407,14 @@ public class ClassicPlotManager extends SquarePlotManager {
int ex = sx + dpw.ROAD_WIDTH - 1;
int sz = location.getZ() + 1;
int ez = sz + dpw.ROAD_WIDTH - 1;
MainUtil.setSimpleCuboidAsync(plotArea.worldname, new Location(plotArea.worldname, sx, dpw.ROAD_HEIGHT + 1, sz),
LocalBlockQueue queue = plotArea.getQueue(false);
queue.setCuboid(new Location(plotArea.worldname, sx, dpw.ROAD_HEIGHT + 1, sz),
new Location(plotArea.worldname, ex, 255, ez), PlotBlock.get((short) 0, (byte) 0));
MainUtil.setCuboidAsync(plotArea.worldname, new Location(plotArea.worldname, sx, 1, sz),
queue.setCuboid(new Location(plotArea.worldname, sx, 1, sz),
new Location(plotArea.worldname, ex, dpw.ROAD_HEIGHT - 1, ez), dpw.MAIN_BLOCK);
MainUtil.setCuboidAsync(plotArea.worldname, new Location(plotArea.worldname, sx, dpw.ROAD_HEIGHT, sz),
queue.setCuboid(new Location(plotArea.worldname, sx, dpw.ROAD_HEIGHT, sz),
new Location(plotArea.worldname, ex, dpw.ROAD_HEIGHT, ez), dpw.TOP_BLOCK);
queue.enqueue();
return true;
}

View File

@ -1,14 +1,15 @@
package com.intellectualcrafters.plot.generator;
import com.intellectualcrafters.jnbt.CompoundTag;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.PlotBlock;
import com.intellectualcrafters.plot.object.PlotId;
import com.intellectualcrafters.plot.object.PlotManager;
import com.intellectualcrafters.plot.object.PseudoRandom;
import com.intellectualcrafters.plot.util.MathMan;
import com.intellectualcrafters.plot.util.PlotChunk;
import com.intellectualcrafters.plot.util.SchematicHandler;
import com.intellectualcrafters.plot.util.block.ScopedLocalBlockQueue;
import java.util.HashMap;
import java.util.Map.Entry;
@ -20,12 +21,12 @@ public class HybridGen extends IndependentPlotGenerator {
}
@Override
public void generateChunk(PlotChunk<?> result, PlotArea settings, PseudoRandom random) {
public void generateChunk(ScopedLocalBlockQueue result, PlotArea settings, PseudoRandom random) {
HybridPlotWorld hpw = (HybridPlotWorld) settings;
// Biome
for (short x = 0; x < 16; x++) {
for (short z = 0; z < 16; z++) {
result.setBiome(x, z, hpw.PLOT_BIOME);
result.fillBiome(hpw.PLOT_BIOME);
}
}
// Bedrock
@ -37,10 +38,11 @@ public class HybridGen extends IndependentPlotGenerator {
}
}
// Coords
int cx = result.getX();
int cz = result.getZ();
int bx = (cx << 4) - hpw.ROAD_OFFSET_X;
int bz = (cz << 4) - hpw.ROAD_OFFSET_Z;
Location min = result.getMin();
int cx = min.getX() >> 4;
int cz = min.getZ() >> 4;
int bx = (min.getX()) - hpw.ROAD_OFFSET_X;
int bz = (min.getZ()) - hpw.ROAD_OFFSET_Z;
short rbx;
if (bx < 0) {
rbx = (short) (hpw.SIZE + (bx % hpw.SIZE));
@ -183,11 +185,12 @@ public class HybridGen extends IndependentPlotGenerator {
}
@Override
public boolean populateChunk(PlotChunk<?> result, PlotArea settings, PseudoRandom random) {
public boolean populateChunk(ScopedLocalBlockQueue result, PlotArea settings, PseudoRandom random) {
HybridPlotWorld hpw = (HybridPlotWorld) settings;
if (hpw.G_SCH_STATE != null) {
int cx = result.getX();
int cz = result.getZ();
Location min = result.getMin();
int cx = min.getX() >> 4;
int cz = min.getZ() >> 4;
int p1x = cx << 4;
int p1z = cz << 4;
int bx = p1x - hpw.ROAD_OFFSET_X;

View File

@ -3,7 +3,6 @@ package com.intellectualcrafters.plot.generator;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.commands.Template;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.object.ChunkLoc;
import com.intellectualcrafters.plot.object.FileBytes;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
@ -14,9 +13,8 @@ import com.intellectualcrafters.plot.object.RunnableVal;
import com.intellectualcrafters.plot.util.ChunkManager;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.MathMan;
import com.intellectualcrafters.plot.util.SetQueue;
import com.intellectualcrafters.plot.util.WorldUtil;
import com.intellectualcrafters.plot.util.block.GlobalBlockQueue;
import com.intellectualcrafters.plot.util.block.LocalBlockQueue;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
@ -72,6 +70,7 @@ public class HybridPlotManager extends ClassicPlotManager {
private void createSchemAbs(HybridPlotWorld hpw, Location pos1, Location pos2, boolean clear) {
int size = hpw.SIZE;
LocalBlockQueue queue = hpw.getQueue(false);
for (int x = pos1.getX(); x <= pos2.getX(); x++) {
short absX = (short) ((x - hpw.ROAD_OFFSET_X) % size);
if (absX < 0) {
@ -85,16 +84,17 @@ public class HybridPlotManager extends ClassicPlotManager {
HashMap<Integer, PlotBlock> blocks = hpw.G_SCH.get(MathMan.pair(absX, absZ));
if (clear) {
for (short y = (short) 0; y <= hpw.SCHEMATIC_HEIGHT; y++) {
SetQueue.IMP.setBlock(hpw.worldname, x, y, z, 0);
queue.setBlock(x, y, z, 0);
}
}
if (blocks != null) {
for (Entry<Integer, PlotBlock> entry : blocks.entrySet()) {
SetQueue.IMP.setBlock(hpw.worldname, x, entry.getKey(), z, entry.getValue());
queue.setBlock(x, entry.getKey(), z, entry.getValue());
}
}
}
}
queue.enqueue();
}
@Override
@ -157,13 +157,14 @@ public class HybridPlotManager extends ClassicPlotManager {
bedrock = PlotBlock.get((short) 0, (byte) 0);
}
final PlotBlock air = PlotBlock.get((short) 0, (byte) 0);
final String biome = WorldUtil.IMP.getBiomeList()[dpw.PLOT_BIOME];
final String biome = dpw.PLOT_BIOME;
final LocalBlockQueue queue = plotArea.getQueue(false);
ChunkManager.chunkTask(pos1, pos2, new RunnableVal<int[]>() {
@Override
public void run(int[] value) {
// If the chunk isn't near the edge and it isn't an augmented world we can just regen the whole chunk
if (canRegen && (value[6] == 0)) {
ChunkManager.manager.regenerateChunk(world, new ChunkLoc(value[0], value[1]));
queue.regenChunk(value[0], value[1]);
return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -174,25 +175,26 @@ public class HybridPlotManager extends ClassicPlotManager {
// These two locations are for each component (e.g. bedrock, main block, floor, air)
Location bot = new Location(world, value[2], 0, value[3]);
Location top = new Location(world, value[4], 1, value[5]);
MainUtil.setSimpleCuboidAsync(world, bot, top, bedrock);
queue.setCuboid(bot, top, bedrock);
// Each component has a different layer
bot.setY(1);
top.setY(dpw.PLOT_HEIGHT);
MainUtil.setCuboidAsync(world, bot, top, filling);
queue.setCuboid(bot, top, filling);
bot.setY(dpw.PLOT_HEIGHT);
top.setY(dpw.PLOT_HEIGHT + 1);
MainUtil.setCuboidAsync(world, bot, top, plotfloor);
queue.setCuboid(bot, top, plotfloor);
bot.setY(dpw.PLOT_HEIGHT + 1);
top.setY(256);
MainUtil.setSimpleCuboidAsync(world, bot, top, air);
queue.setCuboid(bot, top, air);
// And finally set the schematic, the y value is unimportant for this function
pastePlotSchematic(dpw, bot, top);
}
}, new Runnable() {
@Override
public void run() {
queue.enqueue();
// And notify whatever called this when plot clearing is done
SetQueue.IMP.addTask(whenDone);
GlobalBlockQueue.IMP.addTask(whenDone);
}
}, 10);
return true;

View File

@ -8,7 +8,6 @@ import com.intellectualcrafters.plot.flag.Flags;
import com.intellectualcrafters.plot.object.ChunkLoc;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.util.expiry.PlotAnalysis;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.PlotBlock;
import com.intellectualcrafters.plot.object.PlotId;
@ -18,9 +17,10 @@ import com.intellectualcrafters.plot.object.RunnableVal;
import com.intellectualcrafters.plot.util.ChunkManager;
import com.intellectualcrafters.plot.util.MathMan;
import com.intellectualcrafters.plot.util.SchematicHandler;
import com.intellectualcrafters.plot.util.SetQueue;
import com.intellectualcrafters.plot.util.TaskManager;
import com.intellectualcrafters.plot.util.block.GlobalBlockQueue;
import com.intellectualcrafters.plot.util.block.LocalBlockQueue;
import com.intellectualcrafters.plot.util.expiry.PlotAnalysis;
import java.io.File;
import java.util.ArrayDeque;
import java.util.ArrayList;
@ -107,7 +107,27 @@ public abstract class HybridUtils {
run.run();
}
public abstract int checkModified(String world, int x1, int x2, int y1, int y2, int z1, int z2, PlotBlock[] blocks);
public int checkModified(LocalBlockQueue queue, int x1, int x2, int y1, int y2, int z1, int z2, PlotBlock[] blocks) {
int count = 0;
for (int y = y1; y <= y2; y++) {
for (int x = x1; x <= x2; x++) {
for (int z = z1; z <= z2; z++) {
PlotBlock block = queue.getBlock(x, y, z);
boolean same = false;
for (PlotBlock p : blocks) {
if (block.id == p.id) {
same = true;
break;
}
}
if (!same) {
count++;
}
}
}
}
return count;
}
public final ArrayList<ChunkLoc> getChunks(ChunkLoc region) {
ArrayList<ChunkLoc> chunks = new ArrayList<>();
@ -139,6 +159,7 @@ public abstract class HybridUtils {
whenDone.value = 0;
final ClassicPlotWorld cpw = (ClassicPlotWorld) plotArea;
final ArrayDeque<RegionWrapper> zones = new ArrayDeque<>(plot.getRegions());
final LocalBlockQueue queue = GlobalBlockQueue.IMP.getNewQueue(cpw.worldname, false);
Runnable run = new Runnable() {
@Override
public void run() {
@ -159,11 +180,10 @@ public abstract class HybridUtils {
int bz = value[3];
int ex = value[4];
int ez = value[5];
whenDone.value += checkModified(plot.getArea().worldname, bx, ex, 1, cpw.PLOT_HEIGHT - 1, bz, ez, cpw.MAIN_BLOCK);
whenDone.value += checkModified(plot.getArea().worldname, bx, ex, cpw.PLOT_HEIGHT, cpw.PLOT_HEIGHT, bz, ez, cpw.TOP_BLOCK);
whenDone.value += checkModified(queue, bx, ex, 1, cpw.PLOT_HEIGHT - 1, bz, ez, cpw.MAIN_BLOCK);
whenDone.value += checkModified(queue, bx, ex, cpw.PLOT_HEIGHT, cpw.PLOT_HEIGHT, bz, ez, cpw.TOP_BLOCK);
whenDone.value += checkModified(
plot.getArea().worldname, bx, ex, cpw.PLOT_HEIGHT + 1, 255, bz, ez,
new PlotBlock[]{PlotBlock.get((short) 0, (byte) 0)});
queue, bx, ex, cpw.PLOT_HEIGHT + 1, 255, bz, ez, new PlotBlock[]{PlotBlock.get((short) 0, (byte) 0)});
}
}, this, 5);
@ -281,7 +301,7 @@ public abstract class HybridUtils {
PS.debug("&d - Potentially skipping 1024 chunks");
PS.debug("&d - TODO: recommend chunkster if corrupt");
}
SetQueue.IMP.addTask(new Runnable() {
GlobalBlockQueue.IMP.addTask(new Runnable() {
@Override
public void run() {
TaskManager.runTaskLater(task, 20);
@ -297,6 +317,7 @@ public abstract class HybridUtils {
public boolean setupRoadSchematic(Plot plot) {
final String world = plot.getArea().worldname;
final LocalBlockQueue queue = GlobalBlockQueue.IMP.getNewQueue(world, false);
Location bot = plot.getBottomAbs().subtract(1, 0, 1);
Location top = plot.getTopAbs();
final HybridPlotWorld plotworld = (HybridPlotWorld) plot.getArea();
@ -305,10 +326,10 @@ public abstract class HybridUtils {
int sy = plotworld.ROAD_HEIGHT;
int ex = bot.getX();
int ez = top.getZ();
int ey = get_ey(world, sx, ex, sz, ez, sy);
int ey = get_ey(queue, sx, ex, sz, ez, sy);
int bz = sz - plotworld.ROAD_WIDTH;
int tz = sz - 1;
int ty = get_ey(world, sx, ex, bz, tz, sy);
int ty = get_ey(queue, sx, ex, bz, tz, sy);
Set<RegionWrapper> sideRoad = new HashSet<>(Collections.singletonList(new RegionWrapper(sx, ex, sy, ey, sz, ez)));
final Set<RegionWrapper> intersection = new HashSet<>(Collections.singletonList(new RegionWrapper(sx, ex, sy, ty, bz, tz)));
@ -332,7 +353,22 @@ public abstract class HybridUtils {
return true;
}
public abstract int get_ey(String world, int sx, int ex, int sz, int ez, int sy);
public int get_ey(LocalBlockQueue queue, int sx, int ex, int sz, int ez, int sy) {
int ey = sy;
for (int x = sx; x <= ex; x++) {
for (int z = sz; z <= ez; z++) {
for (int y = sy; y < 256; y++) {
if (y > ey) {
PlotBlock block = queue.getBlock(x, y, z);
if (block.id != 0) {
ey = y;
}
}
}
}
}
return ey;
}
public boolean regenerateRoad(final PlotArea area, final ChunkLoc chunk, int extend) {
int x = chunk.x << 4;
@ -359,6 +395,7 @@ public abstract class HybridUtils {
PlotId id2 = manager.getPlotId(plotWorld, ex, 0, ez);
x -= plotWorld.ROAD_OFFSET_X;
z -= plotWorld.ROAD_OFFSET_Z;
LocalBlockQueue queue = GlobalBlockQueue.IMP.getNewQueue(plotWorld.worldname, false);
if (id1 == null || id2 == null || id1 != id2) {
boolean result = ChunkManager.manager.loadChunk(area.worldname, chunk, false);
if (result) {
@ -399,26 +436,20 @@ public abstract class HybridUtils {
if (condition) {
HashMap<Integer, PlotBlock> blocks = plotWorld.G_SCH.get(MathMan.pair(absX, absZ));
for (short y = (short) plotWorld.ROAD_HEIGHT; y <= plotWorld.ROAD_HEIGHT + plotWorld.SCHEMATIC_HEIGHT + extend; y++) {
SetQueue.IMP.setBlock(area.worldname, x + X + plotWorld.ROAD_OFFSET_X, y, z + Z + plotWorld.ROAD_OFFSET_Z, 0);
queue.setBlock(x + X + plotWorld.ROAD_OFFSET_X, y, z + Z + plotWorld.ROAD_OFFSET_Z, 0);
}
if (blocks != null) {
for (Entry<Integer, PlotBlock> entry : blocks.entrySet()) {
SetQueue.IMP.setBlock(area.worldname, x + X + plotWorld.ROAD_OFFSET_X, entry.getKey(),
z + Z + plotWorld.ROAD_OFFSET_Z, entry.getValue());
queue.setBlock(x + X + plotWorld.ROAD_OFFSET_X, entry.getKey(), z + Z + plotWorld.ROAD_OFFSET_Z, entry.getValue());
}
}
}
}
}
SetQueue.IMP.addTask(new Runnable() {
@Override
public void run() {
ChunkManager.manager.unloadChunk(area.worldname, chunk, true, true);
}
});
return true;
}
}
queue.enqueue();
return false;
}
}

View File

@ -6,7 +6,7 @@ import com.intellectualcrafters.plot.object.PlotId;
import com.intellectualcrafters.plot.object.PlotManager;
import com.intellectualcrafters.plot.object.PseudoRandom;
import com.intellectualcrafters.plot.object.SetupObject;
import com.intellectualcrafters.plot.util.PlotChunk;
import com.intellectualcrafters.plot.util.block.ScopedLocalBlockQueue;
/**
* This class allows for implementation independent world generation.
@ -28,9 +28,9 @@ public abstract class IndependentPlotGenerator {
* @param settings
* @param random
*/
public abstract void generateChunk(PlotChunk<?> result, PlotArea settings, PseudoRandom random);
public abstract void generateChunk(ScopedLocalBlockQueue result, PlotArea settings, PseudoRandom random);
public boolean populateChunk(PlotChunk<?> result, PlotArea settings, PseudoRandom random) {
public boolean populateChunk(ScopedLocalBlockQueue result, PlotArea settings, PseudoRandom random) {
return false;
}

View File

@ -0,0 +1,45 @@
package com.intellectualcrafters.plot.object;
import com.intellectualcrafters.plot.util.MathMan;
import com.intellectualcrafters.plot.util.StringMan;
public class ChunkWrapper {
public final int x;
public final int z;
public final String world;
public ChunkWrapper(String world, int x, int z) {
this.world = world;
this.x = x;
this.z = z;
}
@Override
public int hashCode() {
return MathMan.pair((short) x, (short) z);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (this.hashCode() != obj.hashCode()) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
ChunkWrapper other = (ChunkWrapper) obj;
return (this.x == other.x) && (this.z == other.z) && StringMan.isEqual(this.world, other.world);
}
@Override
public String toString() {
return this.world + ":" + this.x + "," + this.z;
}
}

View File

@ -17,14 +17,14 @@ import com.intellectualcrafters.plot.util.EventUtil;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.Permissions;
import com.intellectualcrafters.plot.util.SchematicHandler;
import com.intellectualcrafters.plot.util.SetQueue;
import com.intellectualcrafters.plot.util.StringMan;
import com.intellectualcrafters.plot.util.TaskManager;
import com.intellectualcrafters.plot.util.UUIDHandler;
import com.intellectualcrafters.plot.util.WorldUtil;
import com.intellectualcrafters.plot.util.block.GlobalBlockQueue;
import com.intellectualcrafters.plot.util.block.LocalBlockQueue;
import com.intellectualcrafters.plot.util.expiry.PlotAnalysis;
import com.plotsquared.listener.PlotListener;
import java.awt.Rectangle;
import java.awt.geom.Area;
import java.awt.geom.PathIterator;
@ -782,7 +782,7 @@ public class Plot {
manager.claimPlot(Plot.this.area, current);
}
}
SetQueue.IMP.addTask(run);
GlobalBlockQueue.IMP.addTask(run);
return;
}
Plot current = queue.poll();
@ -794,10 +794,11 @@ public class Plot {
}
};
if (!isMerged() && this.area.getRegion().equals(getLargestRegion())) {
final LocalBlockQueue blockQueue = area.getQueue(false);
ChunkManager.largeRegionTask(this.area.worldname, this.area.getRegion(), new RunnableVal<ChunkLoc>() {
@Override
public void run(ChunkLoc value) {
ChunkManager.manager.regenerateChunk(Plot.this.area.worldname, value);
blockQueue.regenChunk(value.x, value.z);
}
}, whenDone);
} else {
@ -1246,20 +1247,17 @@ public class Plot {
* This should not need to be called
*/
public void refreshChunks() {
TaskManager.runTask(new Runnable() {
@Override
public void run() {
HashSet<ChunkLoc> chunks = new HashSet<>();
for (RegionWrapper region : Plot.this.getRegions()) {
for (int x = region.minX >> 4; x <= region.maxX >> 4; x++) {
for (int z = region.minZ >> 4; z <= region.maxZ >> 4; z++) {
chunks.add(new ChunkLoc(x, z));
}
LocalBlockQueue queue = GlobalBlockQueue.IMP.getNewQueue(area.worldname, false);
HashSet<ChunkLoc> chunks = new HashSet<>();
for (RegionWrapper region : Plot.this.getRegions()) {
for (int x = region.minX >> 4; x <= region.maxX >> 4; x++) {
for (int z = region.minZ >> 4; z <= region.maxZ >> 4; z++) {
if (chunks.add(new ChunkLoc(x, z))) {
queue.refreshChunk(x, z);
}
}
SetQueue.IMP.queue.sendChunk(Plot.this.area.worldname, chunks);
}
});
}
}
/** Remove the plot sign if it is set. */
@ -1269,7 +1267,9 @@ public class Plot {
return;
}
Location loc = manager.getSignLoc(this.area, this);
SetQueue.IMP.setBlock(this.area.worldname, loc.getX(), loc.getY(), loc.getZ(), 0);
LocalBlockQueue queue = GlobalBlockQueue.IMP.getNewQueue(area.worldname, false);
queue.setBlock(loc.getX(), loc.getY(), loc.getZ(), 0);
queue.flush();
}
/** Set the plot sign if plot signs are enabled. */

View File

@ -15,9 +15,9 @@ import com.intellectualcrafters.plot.util.EventUtil;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.PlotGameMode;
import com.intellectualcrafters.plot.util.StringMan;
import com.intellectualcrafters.plot.util.WorldUtil;
import com.intellectualcrafters.plot.util.area.QuadMap;
import com.intellectualcrafters.plot.util.block.GlobalBlockQueue;
import com.intellectualcrafters.plot.util.block.LocalBlockQueue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@ -48,7 +48,7 @@ public abstract class PlotArea {
public boolean ALLOW_SIGNS = true;
public boolean MOB_SPAWNING = false;
public boolean MOB_SPAWNER_SPAWNING = false;
public int PLOT_BIOME = 1;
public String PLOT_BIOME = "FOREST";
public boolean PLOT_CHAT = false;
public boolean SCHEMATIC_CLAIM_SPECIFY = false;
public boolean SCHEMATIC_ON_CLAIM = false;
@ -91,6 +91,10 @@ public abstract class PlotArea {
this.worldhash = worldName.hashCode();
}
public LocalBlockQueue getQueue(boolean autoQueue) {
return GlobalBlockQueue.IMP.getNewQueue(worldname, autoQueue);
}
/**
* Create a new PlotArea object with no functionality/information.
* - Mainly used during startup before worlds are created as a temporary object
@ -211,7 +215,7 @@ public abstract class PlotArea {
this.AUTO_MERGE = config.getBoolean("plot.auto_merge");
this.MAX_PLOT_MEMBERS = config.getInt("limits.max-members");
this.ALLOW_SIGNS = config.getBoolean("plot.create_signs");
this.PLOT_BIOME = WorldUtil.IMP.getBiomeFromString(Configuration.BIOME.parseString(config.getString("plot.biome")));
this.PLOT_BIOME = Configuration.BIOME.parseString(config.getString("plot.biome"));
this.SCHEMATIC_ON_CLAIM = config.getBoolean("schematic.on_claim");
this.SCHEMATIC_FILE = config.getString("schematic.file");
this.SCHEMATIC_CLAIM_SPECIFY = config.getBoolean("schematic.specify_on_claim");

View File

@ -4,24 +4,23 @@ import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.object.ChunkLoc;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.RegionWrapper;
import com.intellectualcrafters.plot.object.RunnableVal;
import com.intellectualcrafters.plot.util.SetQueue.ChunkWrapper;
import com.intellectualcrafters.plot.util.block.GlobalBlockQueue;
import com.intellectualcrafters.plot.util.block.LocalBlockQueue;
import com.intellectualcrafters.plot.util.block.OffsetLocalBlockQueue;
import com.intellectualcrafters.plot.util.block.ScopedLocalBlockQueue;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public abstract class ChunkManager {
public static ChunkManager manager = null;
private static RunnableVal<PlotChunk<?>> CURRENT_FORCE_CHUNK;
private static RunnableVal<PlotChunk<?>> CURRENT_ADD_CHUNK;
private static RunnableVal<ScopedLocalBlockQueue> CURRENT_FORCE_CHUNK;
private static RunnableVal<ScopedLocalBlockQueue> CURRENT_ADD_CHUNK;
public static ChunkLoc getChunkChunk(Location location) {
int x = location.getX() >> 9;
@ -29,40 +28,41 @@ public abstract class ChunkManager {
return new ChunkLoc(x, z);
}
public static void setChunkInPlotArea(RunnableVal<PlotChunk<?>> force, RunnableVal<PlotChunk<?>> add, String world, ChunkLoc loc) {
public static void setChunkInPlotArea(RunnableVal<ScopedLocalBlockQueue> force, RunnableVal<ScopedLocalBlockQueue> add, String world, ChunkLoc loc) {
LocalBlockQueue queue = GlobalBlockQueue.IMP.getNewQueue(world, false);
if (PS.get().isAugmented(world)) {
ChunkWrapper wrap = SetQueue.IMP.new ChunkWrapper(world, loc.x, loc.z);
PlotChunk<?> chunk = SetQueue.IMP.queue.getChunk(wrap);
OffsetLocalBlockQueue offset = new OffsetLocalBlockQueue(queue, loc.x >> 4, 0, loc.z >> 4);
ScopedLocalBlockQueue scoped = new ScopedLocalBlockQueue(offset, new Location(world, 0, 0, 0), new Location(world, 15, 255, 15));
if (force != null) {
force.run(chunk);
force.run(scoped);
} else {
scoped.regenChunk(loc.x, loc.z);
if (add != null) {
add.run(scoped);
}
}
manager.regenerateChunk(world, loc);
if (add != null) {
add.run(chunk);
}
chunk.addToQueue();
chunk.flush(true);
queue.flush();
} else {
CURRENT_FORCE_CHUNK = force;
CURRENT_ADD_CHUNK = add;
manager.regenerateChunk(world, loc);
queue.regenChunk(loc.x, loc.z);
CURRENT_FORCE_CHUNK = null;
CURRENT_ADD_CHUNK = null;
}
}
public static boolean preProcessChunk(PlotChunk<?> chunk) {
public static boolean preProcessChunk(ScopedLocalBlockQueue queue) {
if (CURRENT_FORCE_CHUNK != null) {
CURRENT_FORCE_CHUNK.run(chunk);
CURRENT_FORCE_CHUNK.run(queue);
CURRENT_FORCE_CHUNK = null;
return true;
}
return false;
}
public static boolean postProcessChunk(PlotChunk<?> chunk) {
public static boolean postProcessChunk(ScopedLocalBlockQueue queue) {
if (CURRENT_ADD_CHUNK != null) {
CURRENT_ADD_CHUNK.run(chunk);
CURRENT_ADD_CHUNK.run(queue);
CURRENT_ADD_CHUNK = null;
return true;
}
@ -228,20 +228,6 @@ public abstract class ChunkManager {
return chunks;
}
public void regenerateChunk(String world, ChunkLoc loc) {
SetQueue.IMP.regenerateChunk(world, loc);
SetQueue.IMP.queue.sendChunk(world, Collections.singletonList(loc));
for (Map.Entry<String, PlotPlayer> entry : UUIDHandler.getPlayers().entrySet()) {
PlotPlayer pp = entry.getValue();
Location pLoc = pp.getLocation();
if (!StringMan.isEqual(world, pLoc.getWorld()) || !pLoc.getChunkLoc().equals(loc)) {
continue;
}
pLoc.setY(WorldUtil.IMP.getHighestBlock(world, pLoc.getX(), pLoc.getZ()));
pp.teleport(pLoc);
}
}
public void deleteRegionFiles(String world, Collection<ChunkLoc> chunks) {
deleteRegionFiles(world, chunks, null);
}

View File

@ -8,18 +8,14 @@ import com.intellectualcrafters.plot.database.DBFunc;
import com.intellectualcrafters.plot.flag.Flag;
import com.intellectualcrafters.plot.flag.FlagManager;
import com.intellectualcrafters.plot.flag.Flags;
import com.intellectualcrafters.plot.object.ChunkLoc;
import com.intellectualcrafters.plot.object.ConsolePlayer;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.PlotBlock;
import com.intellectualcrafters.plot.object.PlotId;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.PseudoRandom;
import com.intellectualcrafters.plot.object.RegionWrapper;
import com.intellectualcrafters.plot.object.RunnableVal;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
@ -202,7 +198,7 @@ public class MainUtil {
* @return true if any changes were made
*/
public static boolean resetBiome(PlotArea area, Location pos1, Location pos2) {
String biome = WorldUtil.IMP.getBiomeList()[area.PLOT_BIOME];
String biome = area.PLOT_BIOME;
if (!StringMan.isEqual(WorldUtil.IMP.getBiome(area.worldname, (pos1.getX() + pos2.getX()) / 2, (pos1.getZ() + pos2.getZ()) / 2), biome)) {
MainUtil.setBiome(area.worldname, pos1.getX(), pos1.getZ(), pos2.getX(), pos2.getZ(), biome);
return true;
@ -491,15 +487,6 @@ public class MainUtil {
return area.getPlotAbs(id);
}
/**
* Resend the chunk at a location.
* @param world
* @param loc
*/
public static void update(String world, ChunkLoc loc) {
SetQueue.IMP.queue.sendChunk(world, Collections.singletonList(loc));
}
public static File getFile(File base, String path) {
if (Paths.get(path).isAbsolute()) {
return new File(path);
@ -507,46 +494,6 @@ public class MainUtil {
return new File(base, path);
}
/**
* Set a cuboid asynchronously to a set of blocks.
* @param world
* @param pos1
* @param pos2
* @param blocks
*/
public static void setCuboidAsync(String world, Location pos1, Location pos2, PlotBlock[] blocks) {
if (blocks.length == 1) {
setSimpleCuboidAsync(world, pos1, pos2, blocks[0]);
return;
}
for (int y = pos1.getY(); y <= Math.min(255, pos2.getY()); y++) {
for (int x = pos1.getX(); x <= pos2.getX(); x++) {
for (int z = pos1.getZ(); z <= pos2.getZ(); z++) {
int i = PseudoRandom.random.random(blocks.length);
PlotBlock block = blocks[i];
SetQueue.IMP.setBlock(world, x, y, z, block);
}
}
}
}
/**
* Set a cuboid asynchronously to a block.
* @param world
* @param pos1
* @param pos2
* @param newBlock
*/
public static void setSimpleCuboidAsync(String world, Location pos1, Location pos2, PlotBlock newBlock) {
for (int y = pos1.getY(); y <= Math.min(255, pos2.getY()); y++) {
for (int x = pos1.getX(); x <= pos2.getX(); x++) {
for (int z = pos1.getZ(); z <= pos2.getZ(); z++) {
SetQueue.IMP.setBlock(world, x, y, z, newBlock);
}
}
}
}
/**
* Synchronously set the biome in a selection.
* @param world

View File

@ -21,6 +21,120 @@ public class MathMan {
}
}
private final static int[] table = {
0, 16, 22, 27, 32, 35, 39, 42, 45, 48, 50, 53, 55, 57,
59, 61, 64, 65, 67, 69, 71, 73, 75, 76, 78, 80, 81, 83,
84, 86, 87, 89, 90, 91, 93, 94, 96, 97, 98, 99, 101, 102,
103, 104, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116, 117, 118,
119, 120, 121, 122, 123, 124, 125, 126, 128, 128, 129, 130, 131, 132,
133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 144, 145,
146, 147, 148, 149, 150, 150, 151, 152, 153, 154, 155, 155, 156, 157,
158, 159, 160, 160, 161, 162, 163, 163, 164, 165, 166, 167, 167, 168,
169, 170, 170, 171, 172, 173, 173, 174, 175, 176, 176, 177, 178, 178,
179, 180, 181, 181, 182, 183, 183, 184, 185, 185, 186, 187, 187, 188,
189, 189, 190, 191, 192, 192, 193, 193, 194, 195, 195, 196, 197, 197,
198, 199, 199, 200, 201, 201, 202, 203, 203, 204, 204, 205, 206, 206,
207, 208, 208, 209, 209, 210, 211, 211, 212, 212, 213, 214, 214, 215,
215, 216, 217, 217, 218, 218, 219, 219, 220, 221, 221, 222, 222, 223,
224, 224, 225, 225, 226, 226, 227, 227, 228, 229, 229, 230, 230, 231,
231, 232, 232, 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238,
239, 240, 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246,
246, 247, 247, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253,
253, 254, 254, 255
};
public static long pairInt(int x, int y) {
return (((long)x) << 32) | (y & 0xffffffffL);
}
public static int unpairIntX(long pair) {
return (int)(pair >> 32);
}
public static int unpairIntY(long pair) {
return (int)pair;
}
public static byte pair16(byte x, byte y) {
return (byte) (x + (y << 4));
}
public static byte unpair16x(byte value) {
return (byte) (value & 0xF);
}
public static byte unpair16y(byte value) {
return (byte) ((value >> 4) & 0xF);
}
public static int sqrt(int x) {
int xn;
if (x >= 0x10000) {
if (x >= 0x1000000) {
if (x >= 0x10000000) {
if (x >= 0x40000000) {
xn = table[x >> 24] << 8;
} else {
xn = table[x >> 22] << 7;
}
} else {
if (x >= 0x4000000) {
xn = table[x >> 20] << 6;
} else {
xn = table[x >> 18] << 5;
}
}
xn = (xn + 1 + (x / xn)) >> 1;
xn = (xn + 1 + (x / xn)) >> 1;
return ((xn * xn) > x) ? --xn : xn;
} else {
if (x >= 0x100000) {
if (x >= 0x400000) {
xn = table[x >> 16] << 4;
} else {
xn = table[x >> 14] << 3;
}
} else {
if (x >= 0x40000) {
xn = table[x >> 12] << 2;
} else {
xn = table[x >> 10] << 1;
}
}
xn = (xn + 1 + (x / xn)) >> 1;
return ((xn * xn) > x) ? --xn : xn;
}
} else {
if (x >= 0x100) {
if (x >= 0x1000) {
if (x >= 0x4000) {
xn = (table[x >> 8]) + 1;
} else {
xn = (table[x >> 6] >> 1) + 1;
}
} else {
if (x >= 0x400) {
xn = (table[x >> 4] >> 2) + 1;
} else {
xn = (table[x >> 2] >> 3) + 1;
}
}
return ((xn * xn) > x) ? --xn : xn;
} else {
if (x >= 0) {
return table[x] >> 4;
}
}
}
throw new IllegalArgumentException("Invalid number:" + x);
}
public static double getMean(int[] array) {
double count = 0;
for (int i : array) {
@ -115,7 +229,7 @@ public class MathMan {
}
public static double sqrtApprox(double d) {
return Double.longBitsToDouble(((Double.doubleToLongBits(d) - (1L << 52)) >> 1) + (1L << 61));
return Double.longBitsToDouble(((Double.doubleToLongBits(d) - (1l << 52)) >> 1) + (1l << 61));
}
public static float invSqrt(float x) {

View File

@ -1,261 +0,0 @@
package com.intellectualcrafters.plot.util;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.PlotBlock;
import com.intellectualcrafters.plot.object.PlotManager;
import com.intellectualcrafters.plot.object.PseudoRandom;
import com.intellectualcrafters.plot.object.RunnableVal3;
import com.intellectualcrafters.plot.util.SetQueue.ChunkWrapper;
/**
* The PlotChunk class is primarily used for world generation and mass block placement.<br>
* - With mass block placement, it is associated with a queue<br>
* - World Generation has no queue, so don't use those methods in that case
* @param <T>
*/
public abstract class PlotChunk<T> implements Cloneable {
private ChunkWrapper chunk;
private T objChunk;
/**
* A FaweSections object represents a chunk and the blocks that you wish to change in it.
*/
public PlotChunk(final ChunkWrapper chunk) {
this.chunk = chunk;
}
public ChunkWrapper getChunkWrapper() {
return this.chunk;
}
public void setChunkWrapper(final ChunkWrapper loc) {
this.chunk = loc;
this.objChunk = null;
}
public int getX() {
return chunk.x;
}
public int getZ() {
return chunk.z;
}
/**
* Adds this PlotChunk to the SetQueue for later block placement<br>
* - Will cause issues if not the right type for the implementation
*/
public void addToQueue() {
if (chunk == null) {
throw new IllegalArgumentException("Chunk location cannot be null!");
}
((PlotQueue<T>) SetQueue.IMP.queue).setChunk(this);
}
/**
* Force the queue to finish processing this chunk
* @param fixLighting
*/
public void flush(boolean fixLighting) {
((PlotQueue<T>) SetQueue.IMP.queue).next(getChunkWrapper(), fixLighting);
}
/**
* Force the queue to fix lighting for this chunk
*/
public void fixLighting() {
((PlotQueue<T>) SetQueue.IMP.queue).fixLighting(this, true);
}
/**
* Fill this chunk with a block
* @param id
* @param data
*/
public void fill(int id, byte data) {
fillCuboid(0, 15, 0, 255, 0, 15, id, data);
}
/**
* Fill this chunk with blocks (random)
* @param blocks
*/
public void fill(PlotBlock[] blocks) {
fillCuboid(0, 15, 0, 255, 0, 15, blocks);
}
/**
* Fill a cuboid in this chunk with a block
* @param x1
* @param x2
* @param y1
* @param y2
* @param z1
* @param z2
* @param id
* @param data
*/
public void fillCuboid(int x1, int x2, int y1, int y2, int z1, int z2, int id, byte data) {
for (int x = x1; x <= x2; x++) {
for (int y = y1; y <= y2; y++) {
for (int z = z1; z <= z2; z++) {
setBlock(x, y, z, id, data);
}
}
}
}
/**
* Fill a cuboid in this chunk with blocks
* @param x1
* @param x2
* @param y1
* @param y2
* @param z1
* @param z2
* @param blocks
*/
public void fillCuboid(int x1, int x2, int y1, int y2, int z1, int z2, PlotBlock[] blocks) {
if (blocks.length == 1) {
fillCuboid(x1, x2, y1, y2, z1, z2, blocks[0]);
return;
}
if (chunk != null) {
PseudoRandom.random.state = (chunk.x << 16) | (chunk.z & 0xFFFF);
}
for (int x = x1; x <= x2; x++) {
for (int y = y1; y <= y2; y++) {
for (int z = z1; z <= z2; z++) {
setBlock(x, y, z, blocks[PseudoRandom.random.random(blocks.length)]);
}
}
}
}
/**
* Run a task for each x,z value corresponding to the plot at that location<br>
* - Plot: The plot at the x,z (may be null)<br>
* - Location: The location in the chunk (y = 0)<br>
* - PlotChunk: Reference to this chunk object<br>
* @param task
*/
public void mapByType2D(RunnableVal3<Plot, Integer, Integer> task) {
int bx = getX() << 4;
int bz = getZ() << 4;
String world = getChunkWrapper().world;
PlotArea area = PS.get().getPlotArea(world, null);
Location loc = new Location(world, bx, 0, bz);
if (area != null) {
PlotManager manager = area.getPlotManager();
for (int x = 0; x < 16; x++) {
loc.setX(bx + x);
for (int z = 0; z < 16; z++) {
loc.setZ(bz + z);
task.run(area.getPlotAbs(loc), x, z);
}
}
} else {
for (int x = 0; x < 16; x++) {
loc.setX(bx + x);
for (int z = 0; z < 16; z++) {
loc.setZ(bz + z);
task.run(loc.getPlotAbs(), x, z);
}
}
}
}
/**
* Fill a cuboid in this chunk with a block
* @param x1
* @param x2
* @param y1
* @param y2
* @param z1
* @param z2
* @param block
*/
public void fillCuboid(int x1, int x2, int y1, int y2, int z1, int z2, PlotBlock block) {
fillCuboid(x1, x2, y1, y2, z1, z2, block.id, block.data);
}
/**
* Get the implementation specific chunk
* @Nullable If no location is tied to this container
* @return Chunk
*/
public T getChunk() {
return objChunk != null ? objChunk : getChunkAbs();
}
/**
* Get the implementation specific chunk (no caching)
* @return
*/
public abstract T getChunkAbs();
/**
* Set a block in this container
* @param x
* @param y
* @param z
* @param id
* @param data
*/
public abstract void setBlock(final int x, final int y, final int z, final int id, final byte data);
/**
* Set a block in this container
* @param x
* @param y
* @param z
* @param block
*/
public void setBlock(int x, int y, int z, PlotBlock block) {
setBlock(x, y, z, block.id, block.data);
}
/**
* Set a biome in this container
* @param x
* @param z
* @param biome
*/
public abstract void setBiome(int x, int z, int biome);
@Override
public int hashCode() {
return chunk.hashCode();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof PlotChunk)) {
return false;
}
return chunk.equals(((PlotChunk) obj).chunk);
}
@Override
public String toString() {
return getChunkWrapper().toString();
}
/**
* Attempt to clone this PlotChunk object<br>
* - Depending on the implementation, this may not work
* @return
*/
@Override
public abstract PlotChunk clone();
/**
* Attempt a shallow clone i.e. block mappings share the same reference<br>
* - Depending on the implementation, this may not work
* @return
*/
public abstract PlotChunk shallowClone();
}

View File

@ -1,32 +0,0 @@
package com.intellectualcrafters.plot.util;
import com.intellectualcrafters.plot.object.ChunkLoc;
import com.intellectualcrafters.plot.util.SetQueue.ChunkWrapper;
import java.util.Collection;
public interface PlotQueue<T> {
boolean setBlock(String world, int x, int y, int z, short id, byte data);
PlotChunk<T> getChunk(ChunkWrapper wrap);
void setChunk(PlotChunk<T> chunk);
boolean fixLighting(PlotChunk<T> chunk, boolean fixAll);
void sendChunk(String world, Collection<ChunkLoc> locs);
/**
* Gets the {@link PlotChunk} and sets the requested blocks.
* @return
*/
PlotChunk<T> next();
PlotChunk<T> next(ChunkWrapper wrap, boolean fixLighting);
void clear();
void regenerateChunk(String world, ChunkLoc loc);
}

View File

@ -24,7 +24,7 @@ import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.PlotBlock;
import com.intellectualcrafters.plot.object.RegionWrapper;
import com.intellectualcrafters.plot.object.RunnableVal;
import com.intellectualcrafters.plot.util.block.LocalBlockQueue;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
@ -136,8 +136,7 @@ public abstract class SchematicHandler {
*
* @return boolean true if succeeded
*/
public void paste(final Schematic schematic, final Plot plot, final int xOffset, final int yOffset, final int zOffset, final boolean autoHeight,
final RunnableVal<Boolean> whenDone) {
public void paste(final Schematic schematic, final Plot plot, final int xOffset, final int yOffset, final int zOffset, final boolean autoHeight, final RunnableVal<Boolean> whenDone) {
TaskManager.runTask(new Runnable() {
@Override
public void run() {
@ -160,7 +159,7 @@ public abstract class SchematicHandler {
}
}
final LocalBlockQueue queue = plot.getArea().getQueue(false);
Dimension dimension = schematic.getSchematicDimension();
final int WIDTH = dimension.getX();
final int LENGTH = dimension.getZ();
@ -322,10 +321,10 @@ public abstract class SchematicHandler {
case 190:
case 191:
case 192:
SetQueue.IMP.setBlock(plot.getArea().worldname, xx, yy, zz, id);
queue.setBlock(xx, yy, zz, id);
break;
default:
SetQueue.IMP.setBlock(plot.getArea().worldname, xx, yy, zz, PlotBlock.get((short) id, datas[i]));
queue.setBlock(xx, yy, zz, PlotBlock.get((short) id, datas[i]));
break;
}
}
@ -333,31 +332,17 @@ public abstract class SchematicHandler {
}
}
if (!chunks.isEmpty()) {
final Runnable task = this;
// Run when the queue is free
SetQueue.IMP.addTask(new Runnable() {
@Override
public void run() {
System.gc();
TaskManager.runTaskLaterAsync(task, 80);
}
});
this.run();
} else {
System.gc();
// Finished
SetQueue.IMP.addTask(new Runnable() {
@Override
public void run() {
for (Map.Entry<BlockLoc, CompoundTag> entry : schematic.getTiles().entrySet()) {
BlockLoc loc = entry.getKey();
restoreTile(plot.getArea().worldname, entry.getValue(), p1x + xOffset + loc.x, loc.y + y_offset_actual, p1z + zOffset + loc.z);
}
if (whenDone != null) {
whenDone.value = true;
whenDone.run();
}
}
});
queue.flush();
for (Map.Entry<BlockLoc, CompoundTag> entry : schematic.getTiles().entrySet()) {
BlockLoc loc = entry.getKey();
restoreTile(plot.getArea().worldname, entry.getValue(), p1x + xOffset + loc.x, loc.y + y_offset_actual, p1z + zOffset + loc.z);
}
if (whenDone != null) {
whenDone.value = true;
whenDone.run();
}
}
}
});

View File

@ -1,197 +0,0 @@
package com.intellectualcrafters.plot.util;
import com.intellectualcrafters.plot.object.ChunkLoc;
import com.intellectualcrafters.plot.object.PlotBlock;
import java.util.ArrayDeque;
import java.util.concurrent.atomic.AtomicInteger;
public class SetQueue {
public static final SetQueue IMP = new SetQueue();
private final AtomicInteger time_waiting = new AtomicInteger(2);
private final AtomicInteger time_current = new AtomicInteger(0);
private final ArrayDeque<Runnable> runnables = new ArrayDeque<>();
public PlotQueue<?> queue;
private long last;
private long last2;
public SetQueue() {
TaskManager.runTaskRepeat(new Runnable() {
@Override
public void run() {
long free = 50 + Math.min(50 + SetQueue.this.last - (SetQueue.this.last = System.currentTimeMillis()),
SetQueue.this.last2 - System.currentTimeMillis());
SetQueue.this.time_current.incrementAndGet();
do {
if (isWaiting()) {
return;
}
PlotChunk<?> current = SetQueue.this.queue.next();
if (current == null) {
SetQueue.this.time_waiting.set(Math.max(SetQueue.this.time_waiting.get(), SetQueue.this.time_current.get() - 2));
tasks();
return;
}
} while ((SetQueue.this.last2 = System.currentTimeMillis()) - SetQueue.this.last < free);
SetQueue.this.time_waiting.set(SetQueue.this.time_current.get() - 1);
}
}, 1);
}
public boolean forceChunkSet() {
PlotChunk<?> set = this.queue.next();
return set != null;
}
public boolean isWaiting() {
return this.time_waiting.get() >= this.time_current.get();
}
public boolean isDone() {
return (this.time_waiting.get() + 1) < this.time_current.get();
}
public void setWaiting() {
this.time_waiting.set(this.time_current.get() + 1);
}
public boolean addTask(Runnable whenDone) {
if (isDone()) {
// Run
tasks();
if (whenDone != null) {
whenDone.run();
}
return true;
}
if (whenDone != null) {
this.runnables.add(whenDone);
}
return false;
}
public boolean tasks() {
if (this.runnables.isEmpty()) {
return false;
}
ArrayDeque<Runnable> tmp = this.runnables.clone();
this.runnables.clear();
for (Runnable runnable : tmp) {
runnable.run();
}
return true;
}
/**
* @param world
* @param x
* @param y
* @param z
* @param id
* @param data
* @return
*/
public boolean setBlock(String world, int x, int y, int z, short id, byte data) {
if ((y > 255) || (y < 0)) {
return false;
}
SetQueue.IMP.setWaiting();
return this.queue.setBlock(world, x, y, z, id, data);
}
/**
*
* @param world
* @param x
* @param y
* @param z
* @param block
* @return
*/
public boolean setBlock(String world, int x, int y, int z, PlotBlock block) {
if ((y > 255) || (y < 0)) {
return false;
}
SetQueue.IMP.setWaiting();
return this.queue.setBlock(world, x, y, z, block.id, block.data);
}
/**
* @param world The world
* @param x The x coordinate
* @param y The y coordinate
* @param z The z coordinate
* @param id
* @return
*/
public boolean setBlock(String world, int x, int y, int z, short id) {
if ((y > 255) || (y < 0)) {
return false;
}
SetQueue.IMP.setWaiting();
return this.queue.setBlock(world, x, y, z, id, (byte) 0);
}
/**
*
* @param world The world
* @param x The x coordinate
* @param y The y coordinate
* @param z The z coordinate
* @param id
* @return
*/
public boolean setBlock(String world, int x, int y, int z, int id) {
if (y > 255 || y < 0) {
return false;
}
SetQueue.IMP.setWaiting();
return this.queue.setBlock(world, x, y, z, (short) id, (byte) 0);
}
public void regenerateChunk(String world, ChunkLoc loc) {
this.queue.regenerateChunk(world, loc);
}
public class ChunkWrapper {
public final int x;
public final int z;
public final String world;
public ChunkWrapper(String world, int x, int z) {
this.world = world;
this.x = x;
this.z = z;
}
@Override
public int hashCode() {
return (this.x << 16) | (this.z & 0xFFFF);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (this.hashCode() != obj.hashCode()) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
ChunkWrapper other = (ChunkWrapper) obj;
return (this.x == other.x) && (this.z == other.z) && StringMan.isEqual(this.world, other.world);
}
@Override
public String toString() {
return this.world + ":" + this.x + "," + this.z;
}
}
}

View File

@ -7,51 +7,97 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
public abstract class TaskManager {
public static TaskManager IMP;
public static final HashSet<String> TELEPORT_QUEUE = new HashSet<>();
public static final HashMap<Integer, Integer> tasks = new HashMap<>();
public static AtomicInteger index = new AtomicInteger(0);
public <T> T sync(final RunnableVal<T> function) {
return sync(function, Integer.MAX_VALUE);
}
public <T> T sync(final RunnableVal<T> function, int timeout) {
if (PS.get().isMainThread(Thread.currentThread())) {
function.run();
return function.value;
}
final AtomicBoolean running = new AtomicBoolean(true);
RunnableVal<RuntimeException> run = new RunnableVal<RuntimeException>() {
@Override
public void run(RuntimeException value) {
try {
function.run();
} catch (RuntimeException e) {
this.value = e;
} catch (Throwable neverHappens) {
neverHappens.printStackTrace();
} finally {
running.set(false);
}
synchronized (function) {
function.notifyAll();
}
}
};
TaskManager.IMP.task(run);
try {
synchronized (function) {
while (running.get()) {
function.wait(timeout);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
if (run.value != null) {
throw run.value;
}
return function.value;
}
public static int runTaskRepeat(Runnable runnable, int interval) {
if (runnable != null) {
if (PS.get().TASK == null) {
if (IMP == null) {
throw new IllegalArgumentException("disabled");
}
return PS.get().TASK.taskRepeat(runnable, interval);
return IMP.taskRepeat(runnable, interval);
}
return -1;
}
public static int runTaskRepeatAsync(Runnable runnable, int interval) {
if (runnable != null) {
if (PS.get().TASK == null) {
if (IMP == null) {
throw new IllegalArgumentException("disabled");
}
return PS.get().TASK.taskRepeat(runnable, interval);
return IMP.taskRepeat(runnable, interval);
}
return -1;
}
public static void runTaskAsync(Runnable runnable) {
if (runnable != null) {
if (PS.get().TASK == null) {
if (IMP == null) {
runnable.run();
return;
}
PS.get().TASK.taskAsync(runnable);
IMP.taskAsync(runnable);
}
}
public static void runTask(Runnable runnable) {
if (runnable != null) {
if (PS.get().TASK == null) {
if (IMP == null) {
runnable.run();
return;
}
PS.get().TASK.task(runnable);
IMP.task(runnable);
}
}
@ -62,21 +108,21 @@ public abstract class TaskManager {
*/
public static void runTaskLater(Runnable runnable, int delay) {
if (runnable != null) {
if (PS.get().TASK == null) {
if (IMP == null) {
runnable.run();
return;
}
PS.get().TASK.taskLater(runnable, delay);
IMP.taskLater(runnable, delay);
}
}
public static void runTaskLaterAsync(Runnable runnable, int delay) {
if (runnable != null) {
if (PS.get().TASK == null) {
if (IMP == null) {
runnable.run();
return;
}
PS.get().TASK.taskLaterAsync(runnable, delay);
IMP.taskLaterAsync(runnable, delay);
}
}

View File

@ -0,0 +1,282 @@
package com.intellectualcrafters.plot.util.block;
import com.intellectualcrafters.plot.object.PlotBlock;
import com.intellectualcrafters.plot.object.RunnableVal;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.MathMan;
import com.intellectualcrafters.plot.util.TaskManager;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedDeque;
public abstract class BasicLocalBlockQueue<T> extends LocalBlockQueue {
private final String world;
private long modified;
private final ConcurrentHashMap<Long, LocalChunk> blocks = new ConcurrentHashMap<>();
private final ConcurrentLinkedDeque<LocalChunk> chunks = new ConcurrentLinkedDeque<>();
public BasicLocalBlockQueue(String world) {
super(world);
this.world = world;
this.modified = System.currentTimeMillis();
}
public abstract LocalChunk getLocalChunk(int x, int z);
@Override
public abstract PlotBlock getBlock(int x, int y, int z);
public abstract void setComponents(LocalChunk<T> lc);
@Override
public final String getWorld() {
return world;
}
private LocalChunk lastWrappedChunk;
private int lastX = Integer.MIN_VALUE;
private int lastZ = Integer.MIN_VALUE;
@Override
public final boolean next() {
lastX = Integer.MIN_VALUE;
lastZ = Integer.MIN_VALUE;
try {
if (this.blocks.size() == 0) {
return false;
}
synchronized (blocks) {
LocalChunk chunk = chunks.poll();
if (chunk != null) {
blocks.remove(chunk.longHash());
this.execute(chunk);
return true;
}
}
} catch (Throwable e) {
e.printStackTrace();
}
return false;
}
public final boolean execute(final LocalChunk<T> lc) {
if (lc == null) {
return false;
}
this.setComponents(lc);
return true;
}
@Override
public void startSet(boolean parallel) {
// Do nothing
}
@Override
public void endSet(boolean parallel) {
// Do nothing
}
@Override
public final int size() {
return chunks.size();
}
@Override
public final void setModified(long modified) {
this.modified = modified;
}
@Override
public final long getModified() {
return modified;
}
@Override
public final boolean setBlock(int x, int y, int z, int id, int data) {
if ((y > 255) || (y < 0)) {
return false;
}
int cx = x >> 4;
int cz = z >> 4;
if (cx != lastX || cz != lastZ) {
lastX = cx;
lastZ = cz;
long pair = (long) (cx) << 32 | (cz) & 0xFFFFFFFFL;
lastWrappedChunk = this.blocks.get(pair);
if (lastWrappedChunk == null) {
lastWrappedChunk = this.getLocalChunk(x >> 4, z >> 4);
lastWrappedChunk.setBlock(x & 15, y, z & 15, id, data);
LocalChunk previous = this.blocks.put(pair, lastWrappedChunk);
if (previous == null) {
chunks.add(lastWrappedChunk);
return true;
}
this.blocks.put(pair, previous);
lastWrappedChunk = previous;
}
}
lastWrappedChunk.setBlock(x & 15, y, z & 15, id, data);
return true;
}
@Override
public final boolean setBiome(int x, int z, String biome) {
long pair = (long) (x >> 4) << 32 | (z >> 4) & 0xFFFFFFFFL;
LocalChunk result = this.blocks.get(pair);
if (result == null) {
result = this.getLocalChunk(x >> 4, z >> 4);
LocalChunk previous = this.blocks.put(pair, result);
if (previous != null) {
this.blocks.put(pair, previous);
result = previous;
} else {
chunks.add(result);
}
}
result.setBiome(x & 15, z & 15, biome);
return true;
}
public final void setChunk(LocalChunk<T> chunk) {
LocalChunk previous = this.blocks.put(chunk.longHash(), (LocalChunk) chunk);
if (previous != null) {
chunks.remove(previous);
}
chunks.add((LocalChunk) chunk);
}
public abstract class LocalChunk<T> {
public final BasicLocalBlockQueue parent;
public final int z;
public final int x;
public T[] blocks;
public String[][] biomes;
public LocalChunk(BasicLocalBlockQueue<T> parent, int x, int z) {
this.parent = parent;
this.x = x;
this.z = z;
}
/**
* Get the parent queue this chunk belongs to
* @return
*/
public BasicLocalBlockQueue getParent() {
return parent;
}
public int getX() {
return x;
}
public int getZ() {
return z;
}
/**
* Add the chunk to the queue
*/
public void addToQueue() {
parent.setChunk(this);
}
public void fill(int id, int data) {
fillCuboid(0, 15, 0, 255, 0, 15, id, data);
}
/**
* Fill a cuboid in this chunk with a block
* @param x1
* @param x2
* @param y1
* @param y2
* @param z1
* @param z2
* @param id
* @param data
*/
public void fillCuboid(int x1, int x2, int y1, int y2, int z1, int z2, int id, int data) {
for (int x = x1; x <= x2; x++) {
for (int y = y1; y <= y2; y++) {
for (int z = z1; z <= z2; z++) {
setBlock(x, y, z, id, data);
}
}
}
}
public abstract void setBlock(final int x, final int y, final int z, final int id, final int data);
public void setBiome(int x, int z, String biome) {
if (this.biomes == null) {
this.biomes = new String[16][];
}
String[] index = this.biomes[x];
if (index == null) {
index = this.biomes[x] = new String[16];
}
index[z] = biome;
}
public long longHash() {
return MathMan.pairInt(x, z);
}
@Override
public int hashCode() {
return MathMan.pair((short) x, (short) z);
}
}
public class BasicLocalChunk extends LocalChunk<PlotBlock[]> {
public BasicLocalChunk(BasicLocalBlockQueue parent, int x, int z) {
super(parent, x, z);
blocks = new PlotBlock[16][];
}
public void setBlock(final int x, final int y, final int z, final int id, final int data) {
PlotBlock block = PlotBlock.get(id, data);
int i = MainUtil.CACHE_I[y][x][z];
int j = MainUtil.CACHE_J[y][x][z];
PlotBlock[] array = blocks[i];
if (array == null) {
array = (blocks[i] = new PlotBlock[4096]);
}
array[j] = block;
}
}
public class CharLocalChunk extends LocalChunk<char[]> {
public CharLocalChunk(BasicLocalBlockQueue parent, int x, int z) {
super(parent, x, z);
blocks = new char[16][];
}
public void setBlock(final int x, final int y, final int z, final int id, final int data) {
PlotBlock block = PlotBlock.get(id, data);
int i = MainUtil.CACHE_I[y][x][z];
int j = MainUtil.CACHE_J[y][x][z];
char[] array = blocks[i];
if (array == null) {
array = (blocks[i] = new char[4096]);
}
array[j] = (char) ((block.id << 4) + block.data);
}
}
@Override
public void flush() {
GlobalBlockQueue.IMP.dequeue(this);
TaskManager.IMP.sync(new RunnableVal<Object>() {
@Override
public void run(Object value) {
while (next());
}
});
}
}

View File

@ -0,0 +1,121 @@
package com.intellectualcrafters.plot.util.block;
import com.intellectualcrafters.plot.object.PlotBlock;
public class DelegateLocalBlockQueue extends LocalBlockQueue {
private final LocalBlockQueue parent;
public LocalBlockQueue getParent() {
return parent;
}
@Override
public boolean next() {
return parent.next();
}
@Override
public void startSet(boolean parallel) {
if (parent != null) {
parent.startSet(parallel);
}
}
@Override
public void endSet(boolean parallel) {
if (parent != null) {
parent.endSet(parallel);
}
}
@Override
public int size() {
if (parent != null) {
return parent.size();
}
return 0;
}
@Override
public void optimize() {
if (parent != null) {
parent.optimize();
}
}
@Override
public void setModified(long modified) {
if (parent != null) {
parent.setModified(modified);
}
}
@Override
public long getModified() {
if (parent != null) {
return parent.getModified();
}
return 0;
}
@Override
public boolean setBlock(int x, int y, int z, int id, int data) {
return parent.setBlock(x, y, z, id, data);
}
@Override
public PlotBlock getBlock(int x, int y, int z) {
return parent.getBlock(x, y, z);
}
@Override
public boolean setBiome(int x, int y, String biome) {
return parent.setBiome(x, y, biome);
}
@Override
public String getWorld() {
return parent.getWorld();
}
@Override
public void flush() {
if (parent != null) {
parent.flush();
}
}
@Override
public void refreshChunk(int x, int z) {
if (parent != null) {
parent.refreshChunk(x, z);
}
}
@Override
public void fixChunkLighting(int x, int z) {
if (parent != null) {
parent.fixChunkLighting(x, z);
}
}
@Override
public void regenChunk(int x, int z) {
if (parent != null) {
parent.regenChunk(x, z);
}
}
@Override
public void enqueue() {
if (parent != null) {
parent.enqueue();
}
}
public DelegateLocalBlockQueue(LocalBlockQueue parent) {
super(parent == null ? null : parent.getWorld());
this.parent = parent;
}
}

View File

@ -0,0 +1,297 @@
package com.intellectualcrafters.plot.util.block;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.object.RunnableVal2;
import com.intellectualcrafters.plot.util.TaskManager;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.atomic.AtomicBoolean;
public class GlobalBlockQueue {
public static GlobalBlockQueue IMP;
private final int PARALLEL_THREADS;
private QueueProvider provider;
private final ConcurrentLinkedDeque<LocalBlockQueue> activeQueues;
private final ConcurrentLinkedDeque<LocalBlockQueue> inactiveQueues;
private final ConcurrentLinkedDeque<Runnable> runnables;
/**
* Used to calculate elapsed time in milliseconds and ensure block placement doesn't lag the server
*/
private long last;
private long secondLast;
private long lastSuccess;
private final AtomicBoolean running;
public enum QueueStage {
INACTIVE, ACTIVE, NONE;
}
public GlobalBlockQueue(QueueProvider provider, int threads) {
this.provider = provider;
activeQueues = new ConcurrentLinkedDeque<>();
inactiveQueues = new ConcurrentLinkedDeque<>();
runnables = new ConcurrentLinkedDeque<>();
running = new AtomicBoolean();
this.PARALLEL_THREADS = threads;
}
private final RunnableVal2<Long, LocalBlockQueue> SET_TASK = new RunnableVal2<Long, LocalBlockQueue>() {
@Override
public void run(Long free, LocalBlockQueue queue) {
do {
boolean more = queue.next();
if (!more) {
lastSuccess = last;
if (inactiveQueues.size() == 0 && activeQueues.size() == 0) {
tasks();
}
return;
}
} while (((GlobalBlockQueue.this.secondLast = System.currentTimeMillis()) - GlobalBlockQueue.this.last) < free);
}
};
public void GlobalBlockQueueProvider(QueueProvider provider) {
this.provider = provider;
}
public LocalBlockQueue getNewQueue(String world, boolean autoQueue) {
LocalBlockQueue queue = provider.getNewQueue(world);
if (autoQueue) {
inactiveQueues.add(queue);
}
return queue;
}
public boolean stop() {
if (!running.get()) {
return false;
}
running.set(false);
return true;
}
public boolean runTask() {
if (running.get()) {
return false;
}
running.set(true);
TaskManager.runTaskRepeat(new Runnable() {
@Override
public void run() {
if (inactiveQueues.isEmpty() && activeQueues.isEmpty()) {
lastSuccess = System.currentTimeMillis();
tasks();
return;
}
SET_TASK.value1 = 50 + Math.min((50 + GlobalBlockQueue.this.last) - (GlobalBlockQueue.this.last = System.currentTimeMillis()), GlobalBlockQueue.this.secondLast - System.currentTimeMillis());
SET_TASK.value2 = getNextQueue();
if (SET_TASK.value2 == null) {
return;
}
if (!PS.get().isMainThread(Thread.currentThread())) {
throw new IllegalStateException("This shouldn't be possible for placement to occur off the main thread");
}
// Disable the async catcher as it can't discern async vs parallel
SET_TASK.value2.startSet(true);
try {
if (PARALLEL_THREADS <= 1) {
SET_TASK.run();
} else {
ArrayList<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < PARALLEL_THREADS; i++) {
threads.add(new Thread(SET_TASK));
}
for (Thread thread : threads) {
thread.start();
}
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} catch (Throwable e) {
e.printStackTrace();
} finally {
// Enable it again (note that we are still on the main thread)
SET_TASK.value2.endSet(true);
}
}
}, 1);
return true;
}
public QueueStage getStage(LocalBlockQueue queue) {
if (activeQueues.contains(queue)) {
return QueueStage.ACTIVE;
} else if (inactiveQueues.contains(queue)) {
return QueueStage.INACTIVE;
}
return QueueStage.NONE;
}
public boolean isStage(LocalBlockQueue queue, QueueStage stage) {
switch (stage) {
case ACTIVE:
return activeQueues.contains(queue);
case INACTIVE:
return inactiveQueues.contains(queue);
case NONE:
return !activeQueues.contains(queue) && !inactiveQueues.contains(queue);
}
return false;
}
public void enqueue(LocalBlockQueue queue) {
inactiveQueues.remove(queue);
if (queue.size() > 0 && !activeQueues.contains(queue)) {
queue.optimize();
activeQueues.add(queue);
}
}
public void dequeue(LocalBlockQueue queue) {
inactiveQueues.remove(queue);
activeQueues.remove(queue);
}
public List<LocalBlockQueue> getAllQueues() {
ArrayList<LocalBlockQueue> list = new ArrayList<LocalBlockQueue>(activeQueues.size() + inactiveQueues.size());
list.addAll(inactiveQueues);
list.addAll(activeQueues);
return list;
}
public List<LocalBlockQueue> getActiveQueues() {
return new ArrayList<>(activeQueues);
}
public List<LocalBlockQueue> getInactiveQueues() {
return new ArrayList<>(inactiveQueues);
}
public void flush(LocalBlockQueue queue) {
SET_TASK.value1 = Long.MAX_VALUE;
SET_TASK.value2 = queue;
if (SET_TASK.value2 == null) {
return;
}
if (PS.get().isMainThread(Thread.currentThread())) {
throw new IllegalStateException("Must be flushed on the main thread!");
}
// Disable the async catcher as it can't discern async vs parallel
SET_TASK.value2.startSet(true);
try {
if (PARALLEL_THREADS <= 1) {
SET_TASK.run();
} else {
ArrayList<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < PARALLEL_THREADS; i++) {
threads.add(new Thread(SET_TASK));
}
for (Thread thread : threads) {
thread.start();
}
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} catch (Throwable e) {
e.printStackTrace();
} finally {
// Enable it again (note that we are still on the main thread)
SET_TASK.value2.endSet(true);
dequeue(queue);
}
}
public LocalBlockQueue getNextQueue() {
long now = System.currentTimeMillis();
while (activeQueues.size() > 0) {
LocalBlockQueue queue = activeQueues.peek();
if (queue != null && queue.size() > 0) {
queue.setModified(now);
return queue;
} else {
activeQueues.poll();
}
}
int size = inactiveQueues.size();
if (size > 0) {
Iterator<LocalBlockQueue> iter = inactiveQueues.iterator();
try {
int total = 0;
LocalBlockQueue firstNonEmpty = null;
while (iter.hasNext()) {
LocalBlockQueue queue = iter.next();
long age = now - queue.getModified();
total += queue.size();
if (queue.size() == 0) {
if (age > 1000) {
iter.remove();
}
continue;
}
if (firstNonEmpty == null) {
firstNonEmpty = queue;
}
if (total > 64) {
firstNonEmpty.setModified(now);
return firstNonEmpty;
}
if (age > 60000) {
queue.setModified(now);
return queue;
}
}
} catch (ConcurrentModificationException e) {
e.printStackTrace();
}
}
return null;
}
public boolean isDone() {
return activeQueues.size() == 0 && inactiveQueues.size() == 0;
}
public boolean addTask(final Runnable whenDone) {
if (this.isDone()) {
// Run
this.tasks();
if (whenDone != null) {
whenDone.run();
}
return true;
}
if (whenDone != null) {
this.runnables.add(whenDone);
}
return false;
}
public synchronized boolean tasks() {
if (this.runnables.isEmpty()) {
return false;
}
final ConcurrentLinkedDeque<Runnable> tmp = new ConcurrentLinkedDeque<>(this.runnables);
this.runnables.clear();
for (final Runnable runnable : tmp) {
runnable.run();
}
return true;
}
}

View File

@ -0,0 +1,105 @@
package com.intellectualcrafters.plot.util.block;
import com.intellectualcrafters.plot.object.ChunkLoc;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.PlotBlock;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.PseudoRandom;
import com.intellectualcrafters.plot.util.StringMan;
import com.intellectualcrafters.plot.util.UUIDHandler;
import com.intellectualcrafters.plot.util.WorldUtil;
import java.util.Map;
public abstract class LocalBlockQueue {
public LocalBlockQueue(String world) {
// Implement this elsewhere
}
public ScopedLocalBlockQueue getForChunk(int x, int z) {
return new ScopedLocalBlockQueue(this, new Location(getWorld(), x << 4, 0, z << 4), new Location(getWorld(), 15 + (x << 4), 255, 15 + (z << 4)));
}
public abstract boolean next();
public abstract void startSet(boolean parallel);
public abstract void endSet(boolean parallel);
public abstract int size();
public abstract void optimize();
public abstract void setModified(long modified);
public abstract long getModified();
public abstract boolean setBlock(final int x, final int y, final int z, final int id, final int data);
public final boolean setBlock(int x, int y, int z, int id) {
return setBlock(x, y, z, id, 0);
}
public final boolean setBlock(int x, int y, int z, PlotBlock block) {
return setBlock(x, y, z, block.id, block.data);
}
public abstract PlotBlock getBlock(int x, int y, int z);
public abstract boolean setBiome(int x, int z, String biome);
public abstract String getWorld();
public abstract void flush();
public final void setModified() {
setModified(System.currentTimeMillis());
}
public abstract void refreshChunk(int x, int z);
public abstract void fixChunkLighting(int x, int z);
public abstract void regenChunk(int x, int z);
public final void regenChunkSafe(int x, int z) {
regenChunk(x, z);
fixChunkLighting(x, z);
ChunkLoc loc = new ChunkLoc(x, z);
for (Map.Entry<String, PlotPlayer> entry : UUIDHandler.getPlayers().entrySet()) {
PlotPlayer pp = entry.getValue();
Location pLoc = pp.getLocation();
if (!StringMan.isEqual(getWorld(), pLoc.getWorld()) || !pLoc.getChunkLoc().equals(loc)) {
continue;
}
pLoc.setY(WorldUtil.IMP.getHighestBlock(getWorld(), pLoc.getX(), pLoc.getZ()));
pp.teleport(pLoc);
}
}
public void enqueue() {
GlobalBlockQueue.IMP.enqueue(this);
}
public final void setCuboid(Location pos1, Location pos2, PlotBlock block) {
for (int y = pos1.getY(); y <= Math.min(255, pos2.getY()); y++) {
for (int x = pos1.getX(); x <= pos2.getX(); x++) {
for (int z = pos1.getZ(); z <= pos2.getZ(); z++) {
setBlock(x, y, z, block);
}
}
}
}
public final void setCuboid(Location pos1, Location pos2, PlotBlock[] blocks) {
for (int y = pos1.getY(); y <= Math.min(255, pos2.getY()); y++) {
for (int x = pos1.getX(); x <= pos2.getX(); x++) {
for (int z = pos1.getZ(); z <= pos2.getZ(); z++) {
int i = PseudoRandom.random.random(blocks.length);
PlotBlock block = blocks[i];
setBlock(x, y, z, block);
}
}
}
}
}

View File

@ -0,0 +1,24 @@
package com.intellectualcrafters.plot.util.block;
public class OffsetLocalBlockQueue extends DelegateLocalBlockQueue {
private final int ox;
private final int oy;
private final int oz;
public OffsetLocalBlockQueue(LocalBlockQueue parent, int ox, int oy, int oz) {
super(parent);
this.ox = ox;
this.oy = oy;
this.oz = oz;
}
@Override
public boolean setBiome(int x, int y, String biome) {
return super.setBiome(ox + x, oy + y, biome);
}
@Override
public boolean setBlock(int x, int y, int z, int id, int data) {
return super.setBlock(ox + x, oy + y, oz + z, id, data);
}
}

View File

@ -0,0 +1,30 @@
package com.intellectualcrafters.plot.util.block;
public abstract class QueueProvider {
public abstract LocalBlockQueue getNewQueue(String world);
public static QueueProvider of(final Class<? extends LocalBlockQueue> primary, final Class<? extends LocalBlockQueue> fallback) {
return new QueueProvider() {
private boolean failed = false;
@Override
public LocalBlockQueue getNewQueue(String world) {
if (!failed) {
try {
return (LocalBlockQueue) primary.getConstructors()[0].newInstance(world);
} catch (Throwable e) {
e.printStackTrace();
failed = true;
}
}
try {
return (LocalBlockQueue) fallback.getConstructors()[0].newInstance(world);
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
};
}
}

View File

@ -0,0 +1,88 @@
package com.intellectualcrafters.plot.util.block;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.PlotManager;
import com.intellectualcrafters.plot.object.RunnableVal3;
public class ScopedLocalBlockQueue extends DelegateLocalBlockQueue {
private final int minX;
private final int minY;
private final int minZ;
private final int maxX;
private final int maxY;
private final int maxZ;
public ScopedLocalBlockQueue(LocalBlockQueue parent, Location min, Location max) {
super(parent);
this.minX = min.getX();
this.minY = min.getY();
this.minZ = min.getZ();
this.maxX = max.getX();
this.maxY = max.getY();
this.maxZ = max.getZ();
}
@Override
public boolean setBiome(int x, int z, String biome) {
return x >= minX && x <= maxX && z >= minZ && z <= maxZ && super.setBiome(x + minX, z + minZ, biome);
}
public void fillBiome(String biome) {
for (int x = minX; x <= maxX; x++) {
for (int z = minZ; z < maxZ; z++) {
setBiome(x, z, biome);
}
}
}
@Override
public boolean setBlock(int x, int y, int z, int id, int data) {
return x >= minX && x <= maxX && y >= minY && y <= maxY && z >= minZ && z <= maxZ && super.setBlock(x + minX, y + minY, z + minZ, id, data);
}
public Location getMin() {
return new Location(getWorld(), minX, minY, minZ);
}
public Location getMax() {
return new Location(getWorld(), maxX, maxY, maxZ);
}
/**
* Run a task for each x,z value corresponding to the plot at that location<br>
* - Plot: The plot at the x,z (may be null)<br>
* - Location: The location in the chunk (y = 0)<br>
* - PlotChunk: Reference to this chunk object<br>
* @param task
*/
public void mapByType2D(RunnableVal3<Plot, Integer, Integer> task) {
int bx = minX;
int bz = minZ;
PlotArea area = PS.get().getPlotArea(getWorld(), null);
Location loc = new Location(getWorld(), bx, 0, bz);
if (area != null) {
PlotManager manager = area.getPlotManager();
for (int x = 0; x < 16; x++) {
loc.setX(bx + x);
for (int z = 0; z < 16; z++) {
loc.setZ(bz + z);
task.run(area.getPlotAbs(loc), x, z);
}
}
} else {
for (int x = 0; x < 16; x++) {
loc.setX(bx + x);
for (int z = 0; z < 16; z++) {
loc.setZ(bz + z);
task.run(loc.getPlotAbs(), x, z);
}
}
}
}
}

View File

@ -215,17 +215,11 @@ public class ProcessedWEExtent extends AbstractDelegateExtent {
case 190:
case 191:
case 192:
// if (Settings.EXPERIMENTAL_FAST_ASYNC_WORLDEDIT) {
// SetQueue.IMP.setBlock(this.world, x, y, z, id);
// } else
{
super.setBlock(location, block);
}
break;
default:
// if (Settings.EXPERIMENTAL_FAST_ASYNC_WORLDEDIT) {
// SetQueue.IMP.setBlock(this.world, x, y, z, PlotBlock.get((short) id, (byte) block.getData()));
// } else
{
super.setBlock(location, block);
}