Dieser Commit ist enthalten in:
Jesse Boyd 2019-05-03 00:45:03 +10:00
Ursprung 8dcc005ec1
Commit f5944fbcaf
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 59F1DE6293AF6E1F
26 geänderte Dateien mit 617 neuen und 480 gelöschten Zeilen

Datei anzeigen

@ -56,6 +56,7 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
@ -147,6 +148,11 @@ public class FaweBukkit implements IFawe, Listener {
}); });
} }
@EventHandler
public static void onChunkUnload(ChunkUnloadEvent event) {
event.setCancelled(true);
}
@Override @Override
public QueueHandler getQueueHandler() { public QueueHandler getQueueHandler() {
return new BukkitQueueHandler(); return new BukkitQueueHandler();

Datei anzeigen

@ -94,7 +94,7 @@ public final class Spigot_v1_13_R2 extends CachedBukkitAdapter implements Bukkit
public char[] idbToStateOrdinal; public char[] idbToStateOrdinal;
private boolean init() { private synchronized boolean init() {
if (idbToStateOrdinal != null) return false; if (idbToStateOrdinal != null) return false;
idbToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size idbToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size
for (int i = 0; i < idbToStateOrdinal.length; i++) { for (int i = 0; i < idbToStateOrdinal.length; i++) {
@ -527,8 +527,8 @@ public final class Spigot_v1_13_R2 extends CachedBukkitAdapter implements Bukkit
int id = Block.REGISTRY_ID.getId(ibd); int id = Block.REGISTRY_ID.getId(ibd);
return idbToStateOrdinal[id]; return idbToStateOrdinal[id];
} catch (NullPointerException e) { } catch (NullPointerException e) {
if (init()) return adaptToInt(ibd); init();
throw e; return adaptToInt(ibd);
} }
} }
@ -537,8 +537,8 @@ public final class Spigot_v1_13_R2 extends CachedBukkitAdapter implements Bukkit
int id = Block.REGISTRY_ID.getId(ibd); int id = Block.REGISTRY_ID.getId(ibd);
return idbToStateOrdinal[id]; return idbToStateOrdinal[id];
} catch (NullPointerException e) { } catch (NullPointerException e) {
if (init()) return adaptToChar(ibd); init();
throw e; return adaptToChar(ibd);
} }
} }

Datei anzeigen

@ -20,6 +20,7 @@ import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.internal.Constants; import com.sk89q.worldedit.internal.Constants;
import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockTypes;
import net.jpountz.util.UnsafeUtils; import net.jpountz.util.UnsafeUtils;
import net.minecraft.server.v1_13_R2.BiomeBase; import net.minecraft.server.v1_13_R2.BiomeBase;
import net.minecraft.server.v1_13_R2.BlockPosition; import net.minecraft.server.v1_13_R2.BlockPosition;
@ -69,7 +70,7 @@ public class BukkitChunkHolder<T extends Future<T>> extends ChunkHolder {
get.reset(); get.reset();
} }
if (get.sections == null) { if (get.sections == null) {
get.sections = sections; get.sections = sections.clone();
} }
if (get.sections[layer] != section) { if (get.sections[layer] != section) {
get.sections[layer] = section; get.sections[layer] = section;
@ -79,271 +80,274 @@ public class BukkitChunkHolder<T extends Future<T>> extends ChunkHolder {
} }
@Override @Override
public T call() { public synchronized T call() {
BukkitQueue extent = (BukkitQueue) getExtent(); try {
BukkitGetBlocks get = (BukkitGetBlocks) getOrCreateGet(); int X = getX();
CharSetBlocks set = (CharSetBlocks) getOrCreateSet(); int Z = getZ();
int X = getX(); BukkitQueue extent = (BukkitQueue) getExtent();
int Z = getZ(); BukkitGetBlocks get = (BukkitGetBlocks) getOrCreateGet();
CharSetBlocks set = (CharSetBlocks) getOrCreateSet();
Chunk nmsChunk = extent.ensureLoaded(X, Z); Chunk nmsChunk = extent.ensureLoaded(X, Z);
// Remove existing tiles // Remove existing tiles
{ {
Map<BlockPosition, TileEntity> tiles = nmsChunk.getTileEntities(); Map<BlockPosition, TileEntity> tiles = nmsChunk.getTileEntities();
if (!tiles.isEmpty()) { if (!tiles.isEmpty()) {
final Iterator<Map.Entry<BlockPosition, TileEntity>> iterator = tiles.entrySet().iterator(); final Iterator<Map.Entry<BlockPosition, TileEntity>> iterator = tiles.entrySet().iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
final Map.Entry<BlockPosition, TileEntity> entry = iterator.next(); final Map.Entry<BlockPosition, TileEntity> entry = iterator.next();
final BlockPosition pos = entry.getKey(); final BlockPosition pos = entry.getKey();
final int lx = pos.getX() & 15; final int lx = pos.getX() & 15;
final int ly = pos.getY(); final int ly = pos.getY();
final int lz = pos.getZ() & 15; final int lz = pos.getZ() & 15;
final int layer = ly >> 4; final int layer = ly >> 4;
final char[] array = set.blocks[layer]; final char[] array = set.blocks[layer];
if (array == null) { if (array == null) {
continue; continue;
} }
final int index = (((ly & 0xF) << 8) | (lz << 4) | lx); final int index = (((ly & 0xF) << 8) | (lz << 4) | lx);
if (array[index] != 0) { if (array[index] != 0) {
TileEntity tile = entry.getValue(); TileEntity tile = entry.getValue();
tile.z(); tile.z();
tile.invalidateBlockCache(); tile.invalidateBlockCache();
}
} }
} }
} }
}
int bitMask = 0; int bitMask = 0;
synchronized (nmsChunk) { synchronized (nmsChunk) {
ChunkSection[] sections = nmsChunk.getSections(); ChunkSection[] sections = nmsChunk.getSections();
World world = extent.getBukkitWorld(); World world = extent.getBukkitWorld();
boolean hasSky = world.getEnvironment() == World.Environment.NORMAL; boolean hasSky = world.getEnvironment() == World.Environment.NORMAL;
for (int layer = 0; layer < 16; layer++) { for (int layer = 0; layer < 16; layer++) {
if (!set.hasSection(layer)) continue; if (!set.hasSection(layer)) continue;
bitMask |= 1 << layer; bitMask |= 1 << layer;
char[] setArr = set.blocks[layer]; char[] setArr = set.blocks[layer];
ChunkSection newSection; ChunkSection newSection;
ChunkSection existingSection = sections[layer]; ChunkSection existingSection = sections[layer];
if (existingSection == null) { if (existingSection == null) {
newSection = extent.newChunkSection(layer, hasSky, setArr); newSection = extent.newChunkSection(layer, hasSky, setArr);
if (BukkitQueue.setSectionAtomic(sections, null, newSection, layer)) { if (BukkitQueue.setSectionAtomic(sections, null, newSection, layer)) {
updateGet(get, nmsChunk, sections, newSection, setArr, layer);
continue;
} else {
existingSection = sections[layer];
if (existingSection == null) {
System.out.println("Skipping invalid null section. chunk:" + X + "," + Z + " layer: " + layer);
continue;
}
}
}
DelegateLock lock = BukkitQueue.applyLock(existingSection);
synchronized (lock) {
lock.untilFree();
synchronized (get) {
ChunkSection getSection;
if (get.nmsChunk != nmsChunk) {
if (get.nmsChunk != null) System.out.println("chunk doesn't match");
get.nmsChunk = nmsChunk;
get.sections = null;
get.reset();
} else {
getSection = get.getSections()[layer];
if (getSection != existingSection) {
get.sections[layer] = existingSection;
get.reset();
System.out.println("Section doesn't match");
} else if (lock.isModified()) {
System.out.println("lock is outdated");
get.reset(layer);
}
}
char[] getArr = get.load(layer);
for (int i = 0; i < 4096; i++) {
char value = setArr[i];
if (value != 0) {
getArr[i] = value;
}
}
newSection = extent.newChunkSection(layer, hasSky, getArr);
if (!BukkitQueue.setSectionAtomic(sections, existingSection, newSection, layer)) {
System.out.println("Failed to set chunk section:" + X + "," + Z + " layer: " + layer);
continue;
} else {
updateGet(get, nmsChunk, sections, newSection, setArr, layer); updateGet(get, nmsChunk, sections, newSection, setArr, layer);
} continue;
} } else {
} existingSection = sections[layer];
} if (existingSection == null) {
System.out.println("Skipping invalid null section. chunk:" + X + "," + Z + " layer: " + layer);
// Biomes
if (set.biomes != null) {
// set biomes
final BiomeBase[] currentBiomes = nmsChunk.getBiomeIndex();
for (int i = 0; i < set.biomes.length; i++) {
final BiomeType biome = set.biomes[i];
if (biome != null) {
final Biome craftBiome = BukkitAdapter.adapt(biome);
currentBiomes[i] = CraftBlock.biomeToBiomeBase(craftBiome);
}
}
}
Runnable[] syncTasks = null;
net.minecraft.server.v1_13_R2.World nmsWorld = nmsChunk.getWorld();
int bx = X << 4;
int bz = Z << 4;
if (set.entityRemoves != null && !set.entityRemoves.isEmpty()) {
if (syncTasks == null) syncTasks = new Runnable[3];
HashSet<UUID> entsToRemove = set.entityRemoves;
syncTasks[2] = new Runnable() {
@Override
public void run() {
final List<Entity>[] entities = nmsChunk.getEntitySlices();
for (int i = 0; i < entities.length; i++) {
final Collection<Entity> ents = entities[i];
if (!ents.isEmpty()) {
final Iterator<Entity> iter = ents.iterator();
while (iter.hasNext()) {
final Entity entity = iter.next();
if (entsToRemove.contains(entity.getUniqueID())) {
iter.remove();
entity.b(false);
entity.die();
entity.valid = false;
}
}
}
}
}
};
}
if (set.entities != null && !set.entities.isEmpty()) {
if (syncTasks == null) syncTasks = new Runnable[2];
HashSet<CompoundTag> entitiesToSpawn = set.entities;
syncTasks[1] = new Runnable() {
@Override
public void run() {
for (final CompoundTag nativeTag : entitiesToSpawn) {
final Map<String, Tag> entityTagMap = ReflectionUtils.getMap(nativeTag.getValue());
final StringTag idTag = (StringTag) entityTagMap.get("Id");
final ListTag posTag = (ListTag) entityTagMap.get("Pos");
final ListTag rotTag = (ListTag) entityTagMap.get("Rotation");
if (idTag == null || posTag == null || rotTag == null) {
Fawe.debug("Unknown entity tag: " + nativeTag);
continue; continue;
} }
final double x = posTag.getDouble(0); }
final double y = posTag.getDouble(1); }
final double z = posTag.getDouble(2); DelegateLock lock = BukkitQueue.applyLock(existingSection);
final float yaw = rotTag.getFloat(0); synchronized (get) {
final float pitch = rotTag.getFloat(1); synchronized (lock) {
final String id = idTag.getValue(); lock.untilFree();
final Entity entity = EntityTypes.a(nmsWorld, new MinecraftKey(id));
if (entity != null) { ChunkSection getSection;
final UUID uuid = entity.getUniqueID(); if (get.nmsChunk != nmsChunk) {
entityTagMap.put("UUIDMost", new LongTag(uuid.getMostSignificantBits())); get.nmsChunk = nmsChunk;
entityTagMap.put("UUIDLeast", new LongTag(uuid.getLeastSignificantBits())); get.sections = null;
if (nativeTag != null) { get.reset();
final NBTTagCompound tag = (NBTTagCompound) BukkitQueue_1_13.fromNative(nativeTag); } else {
for (final String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) { getSection = get.getSections()[layer];
tag.remove(name); if (getSection != existingSection) {
} get.sections[layer] = existingSection;
entity.f(tag); get.reset();
} else if (lock.isModified()) {
get.reset(layer);
} }
entity.setLocation(x, y, z, yaw, pitch); }
nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM); char[] getArr = get.load(layer);
for (int i = 0; i < 4096; i++) {
char value = setArr[i];
if (value != 0) {
getArr[i] = value;
}
}
newSection = extent.newChunkSection(layer, hasSky, getArr);
if (!BukkitQueue.setSectionAtomic(sections, existingSection, newSection, layer)) {
System.out.println("Failed to set chunk section:" + X + "," + Z + " layer: " + layer);
continue;
} else {
updateGet(get, nmsChunk, sections, newSection, setArr, layer);
} }
} }
} }
};
}
// set tiles
if (set.tiles != null && !set.tiles.isEmpty()) {
if (syncTasks == null) syncTasks = new Runnable[1];
HashMap<Short, CompoundTag> tiles = set.tiles;
syncTasks[0] = new Runnable() {
@Override
public void run() {
for (final Map.Entry<Short, CompoundTag> entry : tiles.entrySet()) {
final CompoundTag nativeTag = entry.getValue();
final short blockHash = entry.getKey();
final int x = (blockHash >> 12 & 0xF) + bx;
final int y = (blockHash & 0xFF);
final int z = (blockHash >> 8 & 0xF) + bz;
final BlockPosition pos = new BlockPosition(x, y, z);
synchronized (BukkitQueue_0.class) {
TileEntity tileEntity = nmsWorld.getTileEntity(pos);
if (tileEntity == null || tileEntity.x()) {
nmsWorld.n(pos);
tileEntity = nmsWorld.getTileEntity(pos);
}
if (tileEntity != null) {
final NBTTagCompound tag = (NBTTagCompound) BukkitQueue_1_13.fromNative(nativeTag);
tag.set("x", new NBTTagInt(x));
tag.set("y", new NBTTagInt(y));
tag.set("z", new NBTTagInt(z));
tileEntity.load(tag);
}
}
}
}
};
}
int finalMask = bitMask;
Runnable callback = () -> {
if (finalMask != 0) {
// Set Modified
nmsChunk.f(true);
nmsChunk.mustSave = true;
nmsChunk.markDirty();
// send to player
extent.sendChunk(X, Z, finalMask);
} }
extent.returnToPool(BukkitChunkHolder.this); // Biomes
}; if (set.biomes != null) {
if (syncTasks != null) { // set biomes
QueueHandler queueHandler = Fawe.get().getQueueHandler(); final BiomeBase[] currentBiomes = nmsChunk.getBiomeIndex();
Runnable[] finalSyncTasks = syncTasks; for (int i = 0; i < set.biomes.length; i++) {
final BiomeType biome = set.biomes[i];
if (biome != null) {
final Biome craftBiome = BukkitAdapter.adapt(biome);
currentBiomes[i] = CraftBlock.biomeToBiomeBase(craftBiome);
}
}
}
// Chain the sync tasks and the callback Runnable[] syncTasks = null;
Callable<Future> chain = new Callable<Future>() {
@Override net.minecraft.server.v1_13_R2.World nmsWorld = nmsChunk.getWorld();
public Future call() { int bx = X << 4;
// Run the sync tasks int bz = Z << 4;
for (int i = 1; i < finalSyncTasks.length; i++) {
Runnable task = finalSyncTasks[i]; if (set.entityRemoves != null && !set.entityRemoves.isEmpty()) {
if (task != null) { if (syncTasks == null) syncTasks = new Runnable[3];
task.run();
HashSet<UUID> entsToRemove = set.entityRemoves;
syncTasks[2] = new Runnable() {
@Override
public void run() {
final List<Entity>[] entities = nmsChunk.getEntitySlices();
for (int i = 0; i < entities.length; i++) {
final Collection<Entity> ents = entities[i];
if (!ents.isEmpty()) {
final Iterator<Entity> iter = ents.iterator();
while (iter.hasNext()) {
final Entity entity = iter.next();
if (entsToRemove.contains(entity.getUniqueID())) {
iter.remove();
entity.b(false);
entity.die();
entity.valid = false;
}
}
}
} }
} }
return queueHandler.async(callback, null); };
}
if (set.entities != null && !set.entities.isEmpty()) {
if (syncTasks == null) syncTasks = new Runnable[2];
HashSet<CompoundTag> entitiesToSpawn = set.entities;
syncTasks[1] = new Runnable() {
@Override
public void run() {
for (final CompoundTag nativeTag : entitiesToSpawn) {
final Map<String, Tag> entityTagMap = ReflectionUtils.getMap(nativeTag.getValue());
final StringTag idTag = (StringTag) entityTagMap.get("Id");
final ListTag posTag = (ListTag) entityTagMap.get("Pos");
final ListTag rotTag = (ListTag) entityTagMap.get("Rotation");
if (idTag == null || posTag == null || rotTag == null) {
Fawe.debug("Unknown entity tag: " + nativeTag);
continue;
}
final double x = posTag.getDouble(0);
final double y = posTag.getDouble(1);
final double z = posTag.getDouble(2);
final float yaw = rotTag.getFloat(0);
final float pitch = rotTag.getFloat(1);
final String id = idTag.getValue();
final Entity entity = EntityTypes.a(nmsWorld, new MinecraftKey(id));
if (entity != null) {
final UUID uuid = entity.getUniqueID();
entityTagMap.put("UUIDMost", new LongTag(uuid.getMostSignificantBits()));
entityTagMap.put("UUIDLeast", new LongTag(uuid.getLeastSignificantBits()));
if (nativeTag != null) {
final NBTTagCompound tag = (NBTTagCompound) BukkitQueue_1_13.fromNative(nativeTag);
for (final String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
tag.remove(name);
}
entity.f(tag);
}
entity.setLocation(x, y, z, yaw, pitch);
nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM);
}
}
}
};
}
// set tiles
if (set.tiles != null && !set.tiles.isEmpty()) {
if (syncTasks == null) syncTasks = new Runnable[1];
HashMap<Short, CompoundTag> tiles = set.tiles;
syncTasks[0] = new Runnable() {
@Override
public void run() {
for (final Map.Entry<Short, CompoundTag> entry : tiles.entrySet()) {
final CompoundTag nativeTag = entry.getValue();
final short blockHash = entry.getKey();
final int x = (blockHash >> 12 & 0xF) + bx;
final int y = (blockHash & 0xFF);
final int z = (blockHash >> 8 & 0xF) + bz;
final BlockPosition pos = new BlockPosition(x, y, z);
synchronized (BukkitQueue_0.class) {
TileEntity tileEntity = nmsWorld.getTileEntity(pos);
if (tileEntity == null || tileEntity.x()) {
nmsWorld.n(pos);
tileEntity = nmsWorld.getTileEntity(pos);
}
if (tileEntity != null) {
final NBTTagCompound tag = (NBTTagCompound) BukkitQueue_1_13.fromNative(nativeTag);
tag.set("x", new NBTTagInt(x));
tag.set("y", new NBTTagInt(y));
tag.set("z", new NBTTagInt(z));
tileEntity.load(tag);
}
}
}
}
};
}
int finalMask = bitMask;
Runnable callback = () -> {
if (finalMask != 0) {
// Set Modified
nmsChunk.f(true);
nmsChunk.mustSave = true;
nmsChunk.markDirty();
// send to player
extent.sendChunk(X, Z, finalMask);
} }
extent.returnToPool(BukkitChunkHolder.this);
}; };
return (T) queueHandler.sync(chain); if (syncTasks != null) {
} else { QueueHandler queueHandler = Fawe.get().getQueueHandler();
callback.run(); Runnable[] finalSyncTasks = syncTasks;
// Chain the sync tasks and the callback
Callable<Future> chain = new Callable<Future>() {
@Override
public Future call() {
// Run the sync tasks
for (int i = 1; i < finalSyncTasks.length; i++) {
Runnable task = finalSyncTasks[i];
if (task != null) {
task.run();
}
}
return queueHandler.async(callback, null);
}
};
return (T) (Future) queueHandler.sync(chain);
} else {
callback.run();
}
} }
return null;
} catch (Throwable e) {
e.printStackTrace();
return null;
} }
return null;
} }
@Override @Override

Datei anzeigen

@ -21,6 +21,8 @@ import net.minecraft.server.v1_13_R2.DataPaletteLinear;
import net.minecraft.server.v1_13_R2.IBlockData; import net.minecraft.server.v1_13_R2.IBlockData;
import net.minecraft.server.v1_13_R2.World; import net.minecraft.server.v1_13_R2.World;
import java.util.Arrays;
import static com.boydti.fawe.bukkit.v0.BukkitQueue_0.getAdapter; import static com.boydti.fawe.bukkit.v0.BukkitQueue_0.getAdapter;
public class BukkitGetBlocks extends CharGetBlocks { public class BukkitGetBlocks extends CharGetBlocks {
@ -29,7 +31,7 @@ public class BukkitGetBlocks extends CharGetBlocks {
public World nmsWorld; public World nmsWorld;
public int X, Z; public int X, Z;
public BukkitGetBlocks(World nmsWorld, int X, int Z) {/*d*/ public BukkitGetBlocks(World nmsWorld, int X, int Z) {
this.nmsWorld = nmsWorld; this.nmsWorld = nmsWorld;
this.X = X; this.X = X;
this.Z = Z; this.Z = Z;
@ -71,9 +73,10 @@ public class BukkitGetBlocks extends CharGetBlocks {
final DataPaletteBlock<IBlockData> blocks = section.getBlocks(); final DataPaletteBlock<IBlockData> blocks = section.getBlocks();
final DataBits bits = (DataBits) BukkitQueue_1_13.fieldBits.get(blocks); final DataBits bits = (DataBits) BukkitQueue_1_13.fieldBits.get(blocks);
final DataPalette<IBlockData> palette = (DataPalette<IBlockData>) BukkitQueue_1_13.fieldPalette.get(blocks); final DataPalette<IBlockData> palette = (DataPalette<IBlockData>) BukkitQueue_1_13.fieldPalette.get(blocks);
final int bitsPerEntry = bits.c();
final int bitsPerEntry = bits.c();
final long[] blockStates = bits.a(); final long[] blockStates = bits.a();
new BitArray4096(blockStates, bitsPerEntry).toRaw(data); new BitArray4096(blockStates, bitsPerEntry).toRaw(data);
int num_palette; int num_palette;
@ -112,23 +115,20 @@ public class BukkitGetBlocks extends CharGetBlocks {
char[] paletteToBlockChars = FaweCache.PALETTE_TO_BLOCK_CHAR.get(); char[] paletteToBlockChars = FaweCache.PALETTE_TO_BLOCK_CHAR.get();
try { try {
for (int i = 0; i < num_palette; i++) { final int size = num_palette;
IBlockData ibd = palette.a(i); if (size != 1) {
char ordinal; for (int i = 0; i < size; i++) {
if (ibd == null) { char ordinal = ordinal(palette.a(i));
ordinal = BlockTypes.AIR.getDefaultState().getOrdinalChar(); paletteToBlockChars[i] = ordinal;
System.out.println("Invalid palette");
} else {
ordinal = ((Spigot_v1_13_R2) getAdapter()).adaptToChar(ibd);
} }
paletteToBlockChars[i] = ordinal; for (int i = 0; i < 4096; i++) {
} char paletteVal = data[i];
for (int i = 0; i < 4096; i++) { char val = paletteToBlockChars[paletteVal];
char paletteVal = data[i]; data[i] = val;
data[i] = paletteToBlockChars[paletteVal];
if (data[i] == Character.MAX_VALUE) {
System.out.println("Invalid " + paletteVal + " | " + num_palette);
} }
} else {
char ordinal = ordinal(palette.a(0));
Arrays.fill(data, ordinal);
} }
} finally { } finally {
for (int i = 0; i < num_palette; i++) { for (int i = 0; i < num_palette; i++) {
@ -143,6 +143,14 @@ public class BukkitGetBlocks extends CharGetBlocks {
} }
} }
private final char ordinal(IBlockData ibd) {
if (ibd == null) {
return BlockTypes.AIR.getDefaultState().getOrdinalChar();
} else {
return ((Spigot_v1_13_R2) getAdapter()).adaptToChar(ibd);
}
}
public ChunkSection[] getSections() { public ChunkSection[] getSections() {
ChunkSection[] tmp = sections; ChunkSection[] tmp = sections;
if (tmp == null) { if (tmp == null) {

Datei anzeigen

@ -1,40 +1,58 @@
package com.boydti.fawe.beta; package com.boydti.fawe.beta;
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks; import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
import com.boydti.fawe.beta.implementation.blocks.CharSetBlocks;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.registry.BlockMaterial; import com.sk89q.worldedit.world.registry.BlockMaterial;
import javax.annotation.Nullable;
import static com.sk89q.worldedit.world.block.BlockTypes.states; import static com.sk89q.worldedit.world.block.BlockTypes.states;
public class CharFilterBlock implements FilterBlock { public class CharFilterBlock implements FilterBlock {
private IQueueExtent queue; private IQueueExtent queue;
private CharGetBlocks chunk; private CharGetBlocks get;
private char[] section; private CharSetBlocks set;
@Override private char[] getArr;
public final void init(IQueueExtent queue) { private @Nullable char[] setArr;
this.queue = queue; private SetDelegate delegate;
}
@Override
public final void init(int X, int Z, IGetBlocks chunk) {
this.chunk = (CharGetBlocks) chunk;
this.X = X;
this.Z = Z;
this.xx = X << 4;
this.zz = Z << 4;
}
// local // local
private int layer, index, x, y, z, xx, yy, zz, X, Z; private int layer, index, x, y, z, xx, yy, zz, X, Z;
public final void filter(CharGetBlocks blocks, Filter filter) { @Override
for (int layer = 0; layer < 16; layer++) { public final FilterBlock init(final IQueueExtent queue) {
if (!blocks.hasSection(layer)) continue; this.queue = queue;
char[] arr = blocks.sections[layer].get(blocks, layer); return this;
}
this.section = arr; @Override
public final FilterBlock init(final int X, final int Z, final IGetBlocks chunk) {
this.get = (CharGetBlocks) chunk;
this.X = X;
this.Z = Z;
this.xx = X << 4;
this.zz = Z << 4;
return this;
}
public final void filter(final IGetBlocks iget, final ISetBlocks iset, final Filter filter) {
final CharSetBlocks set = (CharSetBlocks) iset;
final CharGetBlocks get = (CharGetBlocks) iget;
for (int layer = 0; layer < 16; layer++) {
if (!get.hasSection(layer)) continue;
this.set = set;
getArr = get.sections[layer].get(get, layer);
if (set.hasSection(layer)) {
setArr = set.blocks[layer];
delegate = FULL;
} else {
delegate = NULL;
setArr = null;
}
this.layer = layer; this.layer = layer;
this.yy = layer << 4; this.yy = layer << 4;
@ -48,6 +66,25 @@ public class CharFilterBlock implements FilterBlock {
} }
} }
@Override
public void setOrdinal(final int ordinal) {
delegate.set(this, (char) ordinal);
}
@Override
public void setState(final BlockState state) {
delegate.set(this, state.getOrdinalChar());
}
@Override
public void setFullBlock(final BaseBlock block) {
delegate.set(this, block.getOrdinalChar());
final CompoundTag nbt = block.getNbtData();
if (nbt != null) { // TODO optimize check via ImmutableBaseBlock
set.setTile(x, yy + y, z, nbt);
}
}
@Override @Override
public final int getX() { public final int getX() {
return xx + x; return xx + x;
@ -89,26 +126,26 @@ public class CharFilterBlock implements FilterBlock {
} }
public final char getOrdinalChar() { public final char getOrdinalChar() {
return section[index]; return getArr[index];
} }
@Override @Override
public final int getOrdinal() { public final int getOrdinal() {
return section[index]; return getArr[index];
} }
@Override @Override
public final BlockState getState() { public final BlockState getState() {
int ordinal = section[index]; final int ordinal = getArr[index];
return BlockTypes.states[ordinal]; return BlockTypes.states[ordinal];
} }
@Override @Override
public final BaseBlock getBaseBlock() { public final BaseBlock getBaseBlock() {
BlockState state = getState(); final BlockState state = getState();
BlockMaterial material = state.getMaterial(); final BlockMaterial material = state.getMaterial();
if (material.hasContainer()) { if (material.hasContainer()) {
CompoundTag tag = chunk.getTag(x, y + (layer << 4), z); final CompoundTag tag = get.getTag(x, y + (layer << 4), z);
return state.toBaseBlock(tag); return state.toBaseBlock(tag);
} }
return state.toBaseBlock(); return state.toBaseBlock();
@ -121,11 +158,11 @@ public class CharFilterBlock implements FilterBlock {
public final BlockState getOrdinalBelow() { public final BlockState getOrdinalBelow() {
if (y > 0) { if (y > 0) {
return states[section[index - 256]]; return states[getArr[index - 256]];
} }
if (layer > 0) { if (layer > 0) {
final int newLayer = layer - 1; final int newLayer = layer - 1;
final CharGetBlocks chunk = this.chunk; final CharGetBlocks chunk = this.get;
return states[chunk.sections[newLayer].get(chunk, newLayer, index + 3840)]; return states[chunk.sections[newLayer].get(chunk, newLayer, index + 3840)];
} }
return BlockTypes.__RESERVED__.getDefaultState(); return BlockTypes.__RESERVED__.getDefaultState();
@ -133,22 +170,22 @@ public class CharFilterBlock implements FilterBlock {
public final BlockState getStateAbove() { public final BlockState getStateAbove() {
if (y < 16) { if (y < 16) {
return states[section[index + 256]]; return states[getArr[index + 256]];
} }
if (layer < 16) { if (layer < 16) {
final int newLayer = layer + 1; final int newLayer = layer + 1;
final CharGetBlocks chunk = this.chunk; final CharGetBlocks chunk = this.get;
return states[chunk.sections[newLayer].get(chunk, newLayer, index - 3840)]; return states[chunk.sections[newLayer].get(chunk, newLayer, index - 3840)];
} }
return BlockTypes.__RESERVED__.getDefaultState(); return BlockTypes.__RESERVED__.getDefaultState();
} }
public final BlockState getStateRelativeY(int y) { public final BlockState getStateRelativeY(final int y) {
int newY = this.y + y; final int newY = this.y + y;
int layerAdd = newY >> 4; final int layerAdd = newY >> 4;
switch (layerAdd) { switch (layerAdd) {
case 0: case 0:
return states[section[this.index + (y << 8)]]; return states[getArr[this.index + (y << 8)]];
case 1: case 1:
case 2: case 2:
case 3: case 3:
@ -164,10 +201,10 @@ public class CharFilterBlock implements FilterBlock {
case 13: case 13:
case 14: case 14:
case 15: { case 15: {
int newLayer = layer + layerAdd; final int newLayer = layer + layerAdd;
if (newLayer < 16) { if (newLayer < 16) {
int index = this.index + ((y & 15) << 8); final int index = this.index + ((y & 15) << 8);
return states[chunk.sections[newLayer].get(chunk, newLayer, index)]; return states[get.sections[newLayer].get(get, newLayer, index)];
} }
break; break;
} }
@ -186,10 +223,10 @@ public class CharFilterBlock implements FilterBlock {
case -13: case -13:
case -14: case -14:
case -15: { case -15: {
int newLayer = layer + layerAdd; final int newLayer = layer + layerAdd;
if (newLayer >= 0) { if (newLayer >= 0) {
int index = this.index + ((y & 15) << 8); final int index = this.index + ((y & 15) << 8);
return states[chunk.sections[newLayer].get(chunk, newLayer, index)]; return states[get.sections[newLayer].get(get, newLayer, index)];
} }
break; break;
} }
@ -198,15 +235,15 @@ public class CharFilterBlock implements FilterBlock {
} }
public final BlockState getStateRelative(final int x, final int y, final int z) { public final BlockState getStateRelative(final int x, final int y, final int z) {
int newX = this.x + x; final int newX = this.x + x;
if (newX >> 4 == 0) { if (newX >> 4 == 0) {
int newZ = this.z + z; final int newZ = this.z + z;
if (newZ >> 4 == 0) { if (newZ >> 4 == 0) {
int newY = this.y + y; final int newY = this.y + y;
int layerAdd = newY >> 4; final int layerAdd = newY >> 4;
switch (layerAdd) { switch (layerAdd) {
case 0: case 0:
return states[section[this.index + ((y << 8) + (z << 4) + x)]]; return states[getArr[this.index + ((y << 8) + (z << 4) + x)]];
case 1: case 1:
case 2: case 2:
case 3: case 3:
@ -222,10 +259,10 @@ public class CharFilterBlock implements FilterBlock {
case 13: case 13:
case 14: case 14:
case 15: { case 15: {
int newLayer = layer + layerAdd; final int newLayer = layer + layerAdd;
if (newLayer < 16) { if (newLayer < 16) {
int index = ((newY & 15) << 8) + (newZ << 4) + newX; final int index = ((newY & 15) << 8) + (newZ << 4) + newX;
return states[chunk.sections[newLayer].get(chunk, newLayer, index)]; return states[get.sections[newLayer].get(get, newLayer, index)];
} }
break; break;
} }
@ -244,10 +281,10 @@ public class CharFilterBlock implements FilterBlock {
case -13: case -13:
case -14: case -14:
case -15: { case -15: {
int newLayer = layer + layerAdd; final int newLayer = layer + layerAdd;
if (newLayer >= 0) { if (newLayer >= 0) {
int index = ((newY & 15) << 8) + (newZ << 4) + newX; final int index = ((newY & 15) << 8) + (newZ << 4) + newX;
return states[chunk.sections[newLayer].get(chunk, newLayer, index)]; return states[get.sections[newLayer].get(get, newLayer, index)];
} }
break; break;
} }
@ -257,10 +294,36 @@ public class CharFilterBlock implements FilterBlock {
} }
// queue.get // queue.get
// TODO return normal get block // TODO return normal get block
int newY = this.y + y + yy; final int newY = this.y + y + yy;
if (newY >= 0 && newY <= 256) { if (newY >= 0 && newY <= 256) {
return queue.getBlock(xx + newX, newY, this.zz + this.z + z); return queue.getBlock(xx + newX, newY, this.zz + this.z + z);
} }
return BlockTypes.__RESERVED__.getDefaultState(); return BlockTypes.__RESERVED__.getDefaultState();
} }
/*
Set delegate
*/
private SetDelegate initSet() {
setArr = set.sections[layer].get(set, layer);
return delegate = FULL;
}
private interface SetDelegate {
void set(CharFilterBlock block, char value);
}
private static final SetDelegate NULL = new SetDelegate() {
@Override
public void set(final CharFilterBlock block, final char value) {
block.initSet().set(block, value);
}
};
private static final SetDelegate FULL = new SetDelegate() {
@Override
public final void set(final CharFilterBlock block, final char value) {
block.setArr[block.index] = value;
}
};
} }

Datei anzeigen

@ -10,7 +10,7 @@ public class ChunkFuture implements Future<Void> {
private volatile boolean cancelled; private volatile boolean cancelled;
private volatile boolean done; private volatile boolean done;
public ChunkFuture(IChunk chunk) { public ChunkFuture(final IChunk chunk) {
this.chunk = chunk; this.chunk = chunk;
} }
@ -19,7 +19,7 @@ public class ChunkFuture implements Future<Void> {
} }
@Override @Override
public boolean cancel(boolean mayInterruptIfRunning) { public boolean cancel(final boolean mayInterruptIfRunning) {
cancelled = true; cancelled = true;
if (done) return false; if (done) return false;
return true; return true;
@ -46,7 +46,7 @@ public class ChunkFuture implements Future<Void> {
} }
@Override @Override
public Void get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { public Void get(final long timeout, final TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
synchronized (chunk) { synchronized (chunk) {
if (!done) { if (!done) {
this.wait(unit.toMillis(timeout)); this.wait(unit.toMillis(timeout));

Datei anzeigen

@ -57,7 +57,7 @@ public interface Filter {
return this; return this;
} }
default void join(Filter parent) { default void join(final Filter parent) {
} }
} }

Datei anzeigen

@ -1,14 +1,23 @@
package com.boydti.fawe.beta; package com.boydti.fawe.beta;
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks; import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
import com.boydti.fawe.beta.implementation.blocks.CharSetBlocks;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
public interface FilterBlock { public interface FilterBlock {
void init(IQueueExtent queue); FilterBlock init(IQueueExtent queue);
void init(int X, int Z, IGetBlocks chunk); FilterBlock init(int X, int Z, IGetBlocks chunk);
void filter(IGetBlocks get, ISetBlocks set, Filter filter);
void setOrdinal(int ordinal);
void setState(BlockState state);
void setFullBlock(BaseBlock block);
int getOrdinal(); int getOrdinal();
@ -26,7 +35,7 @@ public interface FilterBlock {
return getStateRelative(0, 1, 0); return getStateRelative(0, 1, 0);
} }
default BlockState getStateRelativeY(int y) { default BlockState getStateRelativeY(final int y) {
return getStateRelative(0, y, 0); return getStateRelative(0, y, 0);
} }

Datei anzeigen

@ -65,7 +65,7 @@ public interface IDelegateChunk<U extends IChunk> extends IChunk {
@Override @Override
default boolean trim(boolean aggressive) { default boolean trim(final boolean aggressive) {
return getParent().trim(aggressive); return getParent().trim(aggressive);
} }
@ -80,7 +80,7 @@ public interface IDelegateChunk<U extends IChunk> extends IChunk {
} }
@Override @Override
default void filter(Filter filter, FilterBlock mutable) { default void filter(final Filter filter, final FilterBlock mutable) {
getParent().filter(filter, mutable); getParent().filter(filter, mutable);
} }
@ -100,7 +100,7 @@ public interface IDelegateChunk<U extends IChunk> extends IChunk {
} }
@Override @Override
default void set(Filter filter) { default void set(final Filter filter) {
getParent().set(filter); getParent().set(filter);
} }
} }

Datei anzeigen

@ -11,27 +11,27 @@ public interface IDelegateQueueExtent extends IQueueExtent {
IQueueExtent getParent(); IQueueExtent getParent();
@Override @Override
default void init(WorldChunkCache cache) { default void init(final WorldChunkCache cache) {
getParent().init(cache); getParent().init(cache);
} }
@Override @Override
default IChunk getCachedChunk(int X, int Z) { default IChunk getCachedChunk(final int X, final int Z) {
return getParent().getCachedChunk(X, Z); return getParent().getCachedChunk(X, Z);
} }
@Override @Override
default Future<?> submit(IChunk chunk) { default Future<?> submit(final IChunk chunk) {
return getParent().submit(chunk); return getParent().submit(chunk);
} }
@Override @Override
default IChunk create(boolean full) { default IChunk create(final boolean full) {
return getParent().create(full); return getParent().create(full);
} }
@Override @Override
default IChunk wrap(IChunk root) { default IChunk wrap(final IChunk root) {
return getParent().wrap(root); return getParent().wrap(root);
} }
@ -41,7 +41,7 @@ public interface IDelegateQueueExtent extends IQueueExtent {
} }
@Override @Override
default boolean trim(boolean aggressive) { default boolean trim(final boolean aggressive) {
return getParent().trim(aggressive); return getParent().trim(aggressive);
} }
} }

Datei anzeigen

@ -20,8 +20,6 @@ public interface IGetBlocks extends IBlocks, Trimable {
@Override @Override
boolean trim(boolean aggressive); boolean trim(boolean aggressive);
void filter(Filter filter, FilterBlock block);
default void optimize() { default void optimize() {
} }

Datei anzeigen

@ -70,7 +70,7 @@ public interface IQueueExtent extends Flushable, Trimable {
* @param root * @param root
* @return wrapped chunk * @return wrapped chunk
*/ */
default IChunk wrap(IChunk root) { default IChunk wrap(final IChunk root) {
return root; return root;
} }

Datei anzeigen

@ -1,4 +1,4 @@
package com.boydti.fawe.beta.test; package com.boydti.fawe.beta.filters;
import com.boydti.fawe.beta.Filter; import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.FilterBlock; import com.boydti.fawe.beta.FilterBlock;
@ -13,17 +13,17 @@ import java.util.Collections;
import java.util.List; import java.util.List;
public class CountFilter implements Filter { public class CountFilter implements Filter {
private int[] counter = new int[BlockTypes.states.length]; private final int[] counter = new int[BlockTypes.states.length];
@Override @Override
public void applyBlock(FilterBlock block) { public void applyBlock(final FilterBlock block) {
counter[block.getOrdinal()]++; counter[block.getOrdinal()]++;
} }
public List<Countable<BlockState>> getDistribution() { public List<Countable<BlockState>> getDistribution() {
List<Countable<BlockState>> distribution = new ArrayList<>(); final List<Countable<BlockState>> distribution = new ArrayList<>();
for (int i = 0; i < counter.length; i++) { for (int i = 0; i < counter.length; i++) {
int count = counter[i]; final int count = counter[i];
if (count != 0) { if (count != 0) {
distribution.add(new Countable<>(BlockTypes.states[i], count)); distribution.add(new Countable<>(BlockTypes.states[i], count));
} }
@ -32,10 +32,10 @@ public class CountFilter implements Filter {
return distribution; return distribution;
} }
public void print(Actor actor, long size) { public void print(final Actor actor, final long size) {
for (Countable c : getDistribution()) { for (final Countable c : getDistribution()) {
String name = c.getID().toString(); final String name = c.getID().toString();
String str = String.format("%-7s (%.3f%%) %s", final String str = String.format("%-7s (%.3f%%) %s",
String.valueOf(c.getAmount()), String.valueOf(c.getAmount()),
c.getAmount() / (double) size * 100, c.getAmount() / (double) size * 100,
name); name);
@ -49,8 +49,8 @@ public class CountFilter implements Filter {
} }
@Override @Override
public void join(Filter parent) { public void join(final Filter parent) {
CountFilter other = (CountFilter) parent; final CountFilter other = (CountFilter) parent;
for (int i = 0; i < counter.length; i++) { for (int i = 0; i < counter.length; i++) {
other.counter[i] += this.counter[i]; other.counter[i] += this.counter[i];
} }

Datei anzeigen

@ -0,0 +1,18 @@
package com.boydti.fawe.beta.filters;
import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.FilterBlock;
import com.sk89q.worldedit.world.block.BlockState;
public class SetFilter implements Filter {
private final BlockState state;
public SetFilter(final BlockState state) {
this.state = state;
}
@Override
public void applyBlock(final FilterBlock block) {
block.setState(state);
}
}

Datei anzeigen

@ -1,5 +1,6 @@
package com.boydti.fawe.beta.implementation; package com.boydti.fawe.beta.implementation;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache; import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.Filter; import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.FilterBlock; import com.boydti.fawe.beta.FilterBlock;
@ -9,6 +10,7 @@ import com.boydti.fawe.beta.Trimable;
import com.boydti.fawe.config.Settings; import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.collection.IterableThreadLocal; import com.boydti.fawe.object.collection.IterableThreadLocal;
import com.boydti.fawe.util.MemUtil; import com.boydti.fawe.util.MemUtil;
import com.boydti.fawe.util.TaskManager;
import com.boydti.fawe.wrappers.WorldWrapper; import com.boydti.fawe.wrappers.WorldWrapper;
import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.Futures;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
@ -32,7 +34,7 @@ import java.util.concurrent.ThreadPoolExecutor;
/** /**
* Class which handles all the queues {@link IQueueExtent} * Class which handles all the queues {@link IQueueExtent}
*/ */
public abstract class QueueHandler implements Trimable { public abstract class QueueHandler implements Trimable, Runnable {
private ForkJoinPool forkJoinPoolPrimary = new ForkJoinPool(); private ForkJoinPool forkJoinPoolPrimary = new ForkJoinPool();
private ForkJoinPool forkJoinPoolSecondary = new ForkJoinPool(); private ForkJoinPool forkJoinPoolSecondary = new ForkJoinPool();
private ThreadPoolExecutor blockingExecutor = FaweCache.newBlockingExecutor(); private ThreadPoolExecutor blockingExecutor = FaweCache.newBlockingExecutor();
@ -46,38 +48,52 @@ public abstract class QueueHandler implements Trimable {
} }
}; };
public <T> Future<T> async(Runnable run, T value) { public QueueHandler() {
TaskManager.IMP.repeat(this, 1);
}
@Override
public void run() {
if (!Fawe.isMainThread()) {
throw new IllegalStateException("Not main thread");
}
while (!syncTasks.isEmpty()) {
final FutureTask task = syncTasks.poll();
if (task != null) task.run();
}
}
public <T> Future<T> async(final Runnable run, final T value) {
return forkJoinPoolSecondary.submit(run, value); return forkJoinPoolSecondary.submit(run, value);
} }
public <T> Future<T> async(Callable<T> call) { public <T> Future<T> async(final Callable<T> call) {
return forkJoinPoolSecondary.submit(call); return forkJoinPoolSecondary.submit(call);
} }
public <T> Future<T> sync(Runnable run, T value) { public <T> Future<T> sync(final Runnable run, final T value) {
FutureTask<T> result = new FutureTask<>(run, value); final FutureTask<T> result = new FutureTask<>(run, value);
syncTasks.add(result); syncTasks.add(result);
return result; return result;
} }
public <T> Future<T> sync(Runnable run) { public <T> Future<T> sync(final Runnable run) {
FutureTask<T> result = new FutureTask<>(run, null); final FutureTask<T> result = new FutureTask<>(run, null);
syncTasks.add(result); syncTasks.add(result);
return result; return result;
} }
public <T> Future<T> sync(Callable<T> call) { public <T> Future<T> sync(final Callable<T> call) {
FutureTask<T> result = new FutureTask<>(call); final FutureTask<T> result = new FutureTask<>(call);
syncTasks.add(result); syncTasks.add(result);
return result; return result;
} }
public <T extends Future<T>> T submit(IChunk<T> chunk) { public <T extends Future<T>> T submit(final IChunk<T> chunk) {
if (MemUtil.isMemoryFree()) { if (MemUtil.isMemoryFree()) {
// return (T) forkJoinPoolSecondary.submit(chunk); // return (T) forkJoinPoolSecondary.submit(chunk);
} }
return (T) blockingExecutor.submit(chunk); return (T) blockingExecutor.submit(chunk);
} }
/** /**
@ -104,8 +120,8 @@ public abstract class QueueHandler implements Trimable {
public abstract IQueueExtent create(); public abstract IQueueExtent create();
public IQueueExtent getQueue(World world) { public IQueueExtent getQueue(final World world) {
IQueueExtent queue = queuePool.get(); final IQueueExtent queue = queuePool.get();
queue.init(getOrCreate(world)); queue.init(getOrCreate(world));
return queue; return queue;
} }
@ -136,30 +152,31 @@ public abstract class QueueHandler implements Trimable {
// Get a pool, to operate on the chunks in parallel // Get a pool, to operate on the chunks in parallel
final int size = Math.min(chunks.size(), Settings.IMP.QUEUE.PARALLEL_THREADS); final int size = Math.min(chunks.size(), Settings.IMP.QUEUE.PARALLEL_THREADS);
ForkJoinTask[] tasks = new ForkJoinTask[size]; final ForkJoinTask[] tasks = new ForkJoinTask[size];
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
tasks[i] = forkJoinPoolPrimary.submit(new Runnable() { tasks[i] = forkJoinPoolPrimary.submit(new Runnable() {
@Override @Override
public void run() { public void run() {
Filter newFilter = filter.fork(); final Filter newFilter = filter.fork();
// Create a chunk that we will reuse/reset for each operation // Create a chunk that we will reuse/reset for each operation
IQueueExtent queue = getQueue(world); final IQueueExtent queue = getQueue(world);
synchronized (queue) { synchronized (queue) {
FilterBlock block = null; FilterBlock block = null;
while (true) { try {
// Get the next chunk pos while (true) {
final BlockVector2 pos; // Get the next chunk pos
synchronized (chunksIter) { final int X, Z;
if (!chunksIter.hasNext()) break; synchronized (chunksIter) {
pos = chunksIter.next(); if (!chunksIter.hasNext()) break;
} final BlockVector2 pos = chunksIter.next();
final int X = pos.getX(); X = pos.getX();
final int Z = pos.getZ(); Z = pos.getZ();
IChunk chunk = queue.getCachedChunk(X, Z); }
// Initialize IChunk chunk = queue.getCachedChunk(X, Z);
chunk.init(queue, X, Z); // Initialize
try { chunk.init(queue, X, Z);
if (!newFilter.appliesChunk(X, Z)) { if (!newFilter.appliesChunk(X, Z)) {
continue; continue;
} }
@ -173,11 +190,11 @@ public abstract class QueueHandler implements Trimable {
newFilter.finishChunk(chunk); newFilter.finishChunk(chunk);
queue.submit(chunk); queue.submit(chunk);
} finally { }
if (filter != newFilter) { } finally {
synchronized (filter) { if (filter != newFilter) {
newFilter.join(filter); synchronized (filter) {
} newFilter.join(filter);
} }
} }
} }
@ -188,7 +205,7 @@ public abstract class QueueHandler implements Trimable {
} }
// Join filters // Join filters
for (int i = 0; i < tasks.length; i++) { for (int i = 0; i < tasks.length; i++) {
ForkJoinTask task = tasks[i]; final ForkJoinTask task = tasks[i];
if (task != null) { if (task != null) {
task.quietlyJoin(); task.quietlyJoin();
} }

Datei anzeigen

@ -6,8 +6,8 @@ import com.boydti.fawe.beta.FilterBlock;
public abstract class SimpleCharQueueExtent extends SingleThreadQueueExtent { public abstract class SimpleCharQueueExtent extends SingleThreadQueueExtent {
@Override @Override
public FilterBlock initFilterBlock() { public FilterBlock initFilterBlock() {
CharFilterBlock filter = new CharFilterBlock(); FilterBlock filter = new CharFilterBlock();
filter.init(this); filter = filter.init(this);
return filter; return filter;
} }
} }

Datei anzeigen

@ -5,6 +5,7 @@ import com.boydti.fawe.beta.IChunk;
import com.boydti.fawe.beta.IQueueExtent; import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.beta.implementation.holder.ReferenceChunk; import com.boydti.fawe.beta.implementation.holder.ReferenceChunk;
import com.boydti.fawe.config.Settings; import com.boydti.fawe.config.Settings;
import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.MemUtil; import com.boydti.fawe.util.MemUtil;
import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.Futures;
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
@ -78,12 +79,28 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
// Pool discarded chunks for reuse (can safely be cleared by another thread) // Pool discarded chunks for reuse (can safely be cleared by another thread)
private static final ConcurrentLinkedQueue<IChunk> CHUNK_POOL = new ConcurrentLinkedQueue<>(); private static final ConcurrentLinkedQueue<IChunk> CHUNK_POOL = new ConcurrentLinkedQueue<>();
public void returnToPool(IChunk chunk) { public void returnToPool(final IChunk chunk) {
CHUNK_POOL.add(chunk); CHUNK_POOL.add(chunk);
} }
@Override @Override
public <T extends Future<T>> T submit(final IChunk<T> chunk) { public <T extends Future<T>> T submit(final IChunk<T> chunk) {
if (lastChunk == chunk) {
lastPair = Long.MAX_VALUE;
lastChunk = null;
}
final long index = MathMan.pairInt(chunk.getX(), chunk.getZ());
chunks.remove(index, chunk);
return submitUnchecked(chunk);
}
/**
* Submit without first checking that it has been removed from the chunk map
* @param chunk
* @param <T>
* @return
*/
private <T extends Future<T>> T submitUnchecked(final IChunk<T> chunk) {
if (chunk.isEmpty()) { if (chunk.isEmpty()) {
CHUNK_POOL.add(chunk); CHUNK_POOL.add(chunk);
return (T) (Future) Futures.immediateFuture(null); return (T) (Future) Futures.immediateFuture(null);
@ -97,7 +114,7 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
} }
@Override @Override
public synchronized boolean trim(boolean aggressive) { public synchronized boolean trim(final boolean aggressive) {
// TODO trim individial chunk sections // TODO trim individial chunk sections
CHUNK_POOL.clear(); CHUNK_POOL.clear();
if (Thread.currentThread() == currentThread) { if (Thread.currentThread() == currentThread) {
@ -152,12 +169,12 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
checkThread(); checkThread();
final int size = chunks.size(); final int size = chunks.size();
boolean lowMem = MemUtil.isMemoryLimited(); final boolean lowMem = MemUtil.isMemoryLimited();
if (lowMem || size > Settings.IMP.QUEUE.TARGET_SIZE) { if (lowMem || size > Settings.IMP.QUEUE.TARGET_SIZE) {
chunk = chunks.removeFirst(); chunk = chunks.removeFirst();
Future future = submit(chunk); final Future future = submitUnchecked(chunk);
if (future != null && !future.isDone()) { if (future != null && !future.isDone()) {
int targetSize; final int targetSize;
if (lowMem) { if (lowMem) {
targetSize = Settings.IMP.QUEUE.PARALLEL_THREADS; targetSize = Settings.IMP.QUEUE.PARALLEL_THREADS;
} else { } else {
@ -177,14 +194,14 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
return chunk; return chunk;
} }
private void pollSubmissions(int targetSize, boolean aggressive) { private void pollSubmissions(final int targetSize, final boolean aggressive) {
int overflow = submissions.size() - targetSize; final int overflow = submissions.size() - targetSize;
if (aggressive) { if (aggressive) {
for (int i = 0; i < overflow; i++) { for (int i = 0; i < overflow; i++) {
Future first = submissions.poll(); Future first = submissions.poll();
try { try {
while ((first = (Future) first.get()) != null) ; while ((first = (Future) first.get()) != null) ;
} catch (InterruptedException | ExecutionException e) { } catch (final InterruptedException | ExecutionException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@ -195,7 +212,7 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
if (next.isDone()) { if (next.isDone()) {
try { try {
next = (Future) next.get(); next = (Future) next.get();
} catch (InterruptedException | ExecutionException e) { } catch (final InterruptedException | ExecutionException e) {
e.printStackTrace(); e.printStackTrace();
} }
} else { } else {
@ -212,8 +229,8 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
checkThread(); checkThread();
if (!chunks.isEmpty()) { if (!chunks.isEmpty()) {
if (MemUtil.isMemoryLimited()) { if (MemUtil.isMemoryLimited()) {
for (IChunk chunk : chunks.values()) { for (final IChunk chunk : chunks.values()) {
Future future = submit(chunk); final Future future = submitUnchecked(chunk);
if (future != null && !future.isDone()) { if (future != null && !future.isDone()) {
pollSubmissions(Settings.IMP.QUEUE.PARALLEL_THREADS, true); pollSubmissions(Settings.IMP.QUEUE.PARALLEL_THREADS, true);
submissions.add(future); submissions.add(future);
@ -221,7 +238,7 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
} }
} else { } else {
for (final IChunk chunk : chunks.values()) { for (final IChunk chunk : chunks.values()) {
Future future = submit(chunk); final Future future = submitUnchecked(chunk);
if (future != null && !future.isDone()) { if (future != null && !future.isDone()) {
submissions.add(future); submissions.add(future);
} }

Datei anzeigen

@ -13,7 +13,7 @@ public class CharBlocks implements IBlocks {
} }
@Override @Override
public boolean trim(boolean aggressive) { public boolean trim(final boolean aggressive) {
boolean result = true; boolean result = true;
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
if (sections[i] == NULL) { if (sections[i] == NULL) {
@ -30,34 +30,42 @@ public class CharBlocks implements IBlocks {
for (int i = 0; i < 16; i++) sections[i] = NULL; for (int i = 0; i < 16; i++) sections[i] = NULL;
} }
public void reset(int layer) { public void reset(final int layer) {
sections[layer] = NULL; sections[layer] = NULL;
} }
protected char[] load(int layer) { public char[] load(final int layer) {
return new char[4096]; return new char[4096];
} }
protected char[] load(int layer, char[] data) { public char[] load(final int layer, final char[] data) {
for (int i = 0; i < 4096; i++) data[i] = 0; for (int i = 0; i < 4096; i++) data[i] = 0;
return data; return data;
} }
@Override @Override
public boolean hasSection(int layer) { public boolean hasSection(final int layer) {
return sections[layer] == FULL; return sections[layer] == FULL;
} }
public char get(int x, int y, int z) { public char get(final int x, final int y, final int z) {
int layer = y >> 4; final int layer = y >> 4;
int index = ((y & 15) << 8) | (z << 4) | (x & 15); final int index = ((y & 15) << 8) | (z << 4) | (x & 15);
return sections[layer].get(this, layer, index); return sections[layer].get(this, layer, index);
} }
public char set(int x, int y, int z, char value) { public void set(final int x, final int y, final int z, final char value) {
int layer = y >> 4; final int layer = y >> 4;
int index = ((y & 15) << 8) | (z << 4) | (x & 15); final int index = ((y & 15) << 8) | (z << 4) | (x & 15);
return sections[layer].set(this, layer, index, value); set(layer, index, value);
}
public final char get(final int layer, final int index) {
return sections[layer].get(this, layer, index);
}
public final void set(final int layer, final int index, final char value) {
sections[layer].set(this, layer, index, value);
} }
/* /*
@ -67,18 +75,18 @@ public class CharBlocks implements IBlocks {
public static abstract class Section { public static abstract class Section {
public abstract char[] get(CharBlocks blocks, int layer); public abstract char[] get(CharBlocks blocks, int layer);
public final char get(CharBlocks blocks, int layer, int index) { public final char get(final CharBlocks blocks, final int layer, final int index) {
return get(blocks, layer)[index]; return get(blocks, layer)[index];
} }
public final char set(CharBlocks blocks, int layer, int index, char value) { public final void set(final CharBlocks blocks, final int layer, final int index, final char value) {
return get(blocks, layer)[index] = value; get(blocks, layer)[index] = value;
} }
} }
public static final Section NULL = new Section() { public static final Section NULL = new Section() {
@Override @Override
public final char[] get(CharBlocks blocks, int layer) { public final char[] get(final CharBlocks blocks, final int layer) {
blocks.sections[layer] = FULL; blocks.sections[layer] = FULL;
char[] arr = blocks.blocks[layer]; char[] arr = blocks.blocks[layer];
if (arr == null) { if (arr == null) {
@ -92,7 +100,7 @@ public class CharBlocks implements IBlocks {
public static final Section FULL = new Section() { public static final Section FULL = new Section() {
@Override @Override
public final char[] get(CharBlocks blocks, int layer) { public final char[] get(final CharBlocks blocks, final int layer) {
return blocks.blocks[layer]; return blocks.blocks[layer];
} }
}; };

Datei anzeigen

@ -20,13 +20,7 @@ public abstract class CharGetBlocks extends CharBlocks implements IGetBlocks {
} }
@Override @Override
public void filter(Filter filter, FilterBlock block) { public boolean trim(final boolean aggressive) {
CharFilterBlock b = (CharFilterBlock) block;
b.filter(this, filter);
}
@Override
public boolean trim(boolean aggressive) {
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
sections[i] = NULL; sections[i] = NULL;
blocks[i] = null; blocks[i] = null;

Datei anzeigen

@ -17,7 +17,7 @@ public class CharSetBlocks extends CharBlocks implements ISetBlocks {
public HashSet<UUID> entityRemoves; public HashSet<UUID> entityRemoves;
@Override @Override
public boolean setBiome(int x, int y, int z, BiomeType biome) { public boolean setBiome(final int x, final int y, final int z, final BiomeType biome) {
if (biomes == null) { if (biomes == null) {
biomes = new BiomeType[256]; biomes = new BiomeType[256];
} }
@ -26,22 +26,22 @@ public class CharSetBlocks extends CharBlocks implements ISetBlocks {
} }
@Override @Override
public boolean setBlock(int x, int y, int z, BlockStateHolder holder) { public boolean setBlock(final int x, final int y, final int z, final BlockStateHolder holder) {
set(x, y, z, holder.getOrdinalChar()); set(x, y, z, holder.getOrdinalChar());
return true; return true;
} }
@Override @Override
public void setTile(int x, int y, int z, CompoundTag tile) { public void setTile(final int x, final int y, final int z, final CompoundTag tile) {
if (tiles == null) { if (tiles == null) {
tiles = new HashMap<>(); tiles = new HashMap<>();
} }
short pair = MathMan.tripleBlockCoord(x, y, z); final short pair = MathMan.tripleBlockCoord(x, y, z);
tiles.put(pair, tile); tiles.put(pair, tile);
} }
@Override @Override
public void setEntity(CompoundTag tag) { public void setEntity(final CompoundTag tag) {
if (entities == null) { if (entities == null) {
entities = new HashSet<>(); entities = new HashSet<>();
} }
@ -49,7 +49,7 @@ public class CharSetBlocks extends CharBlocks implements ISetBlocks {
} }
@Override @Override
public void removeEntity(UUID uuid) { public void removeEntity(final UUID uuid) {
if (entityRemoves == null) { if (entityRemoves == null) {
entityRemoves = new HashSet<>(); entityRemoves = new HashSet<>();
} }

Datei anzeigen

@ -8,7 +8,7 @@ public class FullCharBlocks implements IBlocks {
public final char[] blocks = new char[65536]; public final char[] blocks = new char[65536];
@Override @Override
public boolean hasSection(int layer) { public boolean hasSection(final int layer) {
return false; return false;
} }
@ -18,7 +18,7 @@ public class FullCharBlocks implements IBlocks {
} }
@Override @Override
public boolean trim(boolean aggressive) { public boolean trim(final boolean aggressive) {
return false; return false;
} }
} }

Datei anzeigen

@ -31,21 +31,22 @@ public abstract class ChunkHolder implements IChunk, Supplier<IGetBlocks> {
this.delegate = NULL; this.delegate = NULL;
} }
public ChunkHolder(IBlockDelegate delegate) { public ChunkHolder(final IBlockDelegate delegate) {
this.delegate = delegate; this.delegate = delegate;
} }
@Override @Override
public void filter(Filter filter, FilterBlock block) { public void filter(final Filter filter, FilterBlock block) {
block.init(X, Z, get); final IGetBlocks get = getOrCreateGet();
IGetBlocks get = getOrCreateGet(); final ISetBlocks set = getOrCreateSet();
get.filter(filter, block); block = block.init(X, Z, get);
block.filter(get, set, filter);
} }
@Override @Override
public boolean trim(boolean aggressive) { public boolean trim(final boolean aggressive) {
if (set != null) { if (set != null) {
boolean result = set.trim(aggressive); final boolean result = set.trim(aggressive);
if (result) { if (result) {
delegate = NULL; delegate = NULL;
get = null; get = null;
@ -87,7 +88,7 @@ public abstract class ChunkHolder implements IChunk, Supplier<IGetBlocks> {
private IGetBlocks newGet() { private IGetBlocks newGet() {
if (extent instanceof SingleThreadQueueExtent) { if (extent instanceof SingleThreadQueueExtent) {
WorldChunkCache cache = ((SingleThreadQueueExtent) extent).getCache(); final WorldChunkCache cache = ((SingleThreadQueueExtent) extent).getCache();
return cache.get(MathMan.pairInt(X, Z), this); return cache.get(MathMan.pairInt(X, Z), this);
} }
return get(); return get();
@ -101,7 +102,7 @@ public abstract class ChunkHolder implements IChunk, Supplier<IGetBlocks> {
} }
@Override @Override
public void init(IQueueExtent extent, final int X, final int Z) { public void init(final IQueueExtent extent, final int X, final int Z) {
this.extent = extent; this.extent = extent;
this.X = X; this.X = X;
this.Z = Z; this.Z = Z;

Datei anzeigen

@ -10,7 +10,7 @@ import com.boydti.fawe.beta.IChunk;
public class FinalizedChunk extends DelegateChunk { public class FinalizedChunk extends DelegateChunk {
private final IQueueExtent queueExtent; private final IQueueExtent queueExtent;
public FinalizedChunk(final IChunk parent, IQueueExtent queueExtent) { public FinalizedChunk(final IChunk parent, final IQueueExtent queueExtent) {
super(parent); super(parent);
this.queueExtent = queueExtent; this.queueExtent = queueExtent;
} }

Datei anzeigen

@ -14,7 +14,7 @@ import java.lang.ref.Reference;
public abstract class ReferenceChunk implements IDelegateChunk { public abstract class ReferenceChunk implements IDelegateChunk {
private final Reference<FinalizedChunk> ref; private final Reference<FinalizedChunk> ref;
public ReferenceChunk(final IChunk parent, IQueueExtent queueExtent) { public ReferenceChunk(final IChunk parent, final IQueueExtent queueExtent) {
this.ref = toRef(new FinalizedChunk(parent, queueExtent)); this.ref = toRef(new FinalizedChunk(parent, queueExtent));
} }

Datei anzeigen

@ -49,7 +49,6 @@ public class InspectBrush extends BrushTool implements DoubleActionTraceTool {
} }
public Vector3 getTarget(Player player, boolean adjacent) { public Vector3 getTarget(Player player, boolean adjacent) {
Location target = null;
int range = this.range > -1 ? getRange() : MAX_RANGE; int range = this.range > -1 ? getRange() : MAX_RANGE;
if (adjacent) { if (adjacent) {
Location face = player.getBlockTraceFace(range, true); Location face = player.getBlockTraceFace(range, true);

Datei anzeigen

@ -22,9 +22,9 @@ package com.sk89q.worldedit.command;
import com.boydti.fawe.Fawe; import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweAPI; import com.boydti.fawe.FaweAPI;
import com.boydti.fawe.beta.IQueueExtent; import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.beta.filters.SetFilter;
import com.boydti.fawe.beta.implementation.QueueHandler; import com.boydti.fawe.beta.implementation.QueueHandler;
import com.boydti.fawe.beta.implementation.WorldChunkCache; import com.boydti.fawe.beta.filters.CountFilter;
import com.boydti.fawe.beta.test.CountFilter;
import com.boydti.fawe.config.BBC; import com.boydti.fawe.config.BBC;
import com.boydti.fawe.example.NMSMappedFaweQueue; import com.boydti.fawe.example.NMSMappedFaweQueue;
import com.boydti.fawe.object.FaweLimit; import com.boydti.fawe.object.FaweLimit;
@ -48,7 +48,6 @@ import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.function.GroundFunction; import com.sk89q.worldedit.function.GroundFunction;
import com.sk89q.worldedit.function.generator.FloraGenerator; import com.sk89q.worldedit.function.generator.FloraGenerator;
import com.sk89q.worldedit.function.generator.ForestGenerator;
import com.sk89q.worldedit.function.mask.ExistingBlockMask; import com.sk89q.worldedit.function.mask.ExistingBlockMask;
import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.NoiseFilter2D; import com.sk89q.worldedit.function.mask.NoiseFilter2D;
@ -66,7 +65,6 @@ import com.sk89q.worldedit.math.convolution.HeightMap;
import com.sk89q.worldedit.math.convolution.HeightMapFilter; import com.sk89q.worldedit.math.convolution.HeightMapFilter;
import com.sk89q.worldedit.math.noise.RandomNoise; import com.sk89q.worldedit.math.noise.RandomNoise;
import com.sk89q.worldedit.regions.*; import com.sk89q.worldedit.regions.*;
import com.sk89q.worldedit.util.Countable;
import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.TreeGenerator.TreeType; import com.sk89q.worldedit.util.TreeGenerator.TreeType;
import com.sk89q.worldedit.util.command.binding.Range; import com.sk89q.worldedit.util.command.binding.Range;
@ -79,12 +77,12 @@ import com.sk89q.worldedit.world.biome.BiomeTypes;
import com.sk89q.worldedit.world.biome.Biomes; import com.sk89q.worldedit.world.biome.Biomes;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.registry.BiomeRegistry; import com.sk89q.worldedit.world.registry.BiomeRegistry;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -116,6 +114,41 @@ public class RegionCommands extends MethodCommands {
this.worldEdit = worldEdit; this.worldEdit = worldEdit;
} }
@Command(
aliases = {"debugtest"},
usage = "",
desc = "debugtest",
help = "debugtest"
)
public void debugtest(Player player, @Selection Region region) throws WorldEditException {
QueueHandler queueHandler = Fawe.get().getQueueHandler();
World world = player.getWorld();
CountFilter filter = new CountFilter();
long start = System.currentTimeMillis();
queueHandler.apply(world, region, filter);
long diff = System.currentTimeMillis() - start;
System.out.println(diff);
}
@Command(
aliases = {"db2"},
usage = "",
desc = "db2",
help = "db2"
)
public void db2(Player player, @Selection Region region, String blockStr) throws WorldEditException {
QueueHandler queueHandler = Fawe.get().getQueueHandler();
World world = player.getWorld();
BlockState block = BlockState.get(blockStr);
SetFilter filter = new SetFilter(block);
long start = System.currentTimeMillis();
queueHandler.apply(world, region, filter);
long diff = System.currentTimeMillis() - start;
System.out.println(diff);
}
@Command( @Command(
aliases = {"/fixlighting"}, aliases = {"/fixlighting"},
desc = "Get the light at a position", desc = "Get the light at a position",
@ -271,44 +304,6 @@ public class RegionCommands extends MethodCommands {
BBC.VISITOR_BLOCK.send(player, blocksChanged); BBC.VISITOR_BLOCK.send(player, blocksChanged);
} }
@Command(
aliases = {"debugtest"},
usage = "",
desc = "debugtest",
help = "debugtest"
)
public void debugtest(Player player, @Selection Region region) throws WorldEditException {
QueueHandler queueHandler = Fawe.get().getQueueHandler();
World world = player.getWorld();
CountFilter filter = new CountFilter();
long start = System.currentTimeMillis();
queueHandler.apply(world, region, filter);
long diff = System.currentTimeMillis() - start;
System.out.println(diff);
}
@Command(
aliases = {"db2"},
usage = "",
desc = "db2",
help = "db2"
)
public void db2(Player player, @Selection Region region) throws WorldEditException {
QueueHandler queueHandler = Fawe.get().getQueueHandler();
World world = player.getWorld();
IQueueExtent queue = queueHandler.getQueue(world);
BlockState block = BlockTypes.STONE.getDefaultState();
long start = System.currentTimeMillis();
for (BlockVector3 p : region) {
queue.setBlock(p.getX(), p.getY(), p.getZ(), block);
}
long start2 = System.currentTimeMillis();
queue.flush();
long diff = System.currentTimeMillis() - start;
long diff2 = System.currentTimeMillis() - start2;
System.out.println(diff + " | " + diff2);
}
@Command( @Command(
aliases = {"/curve", "/spline"}, aliases = {"/curve", "/spline"},
usage = "<pattern> [thickness]", usage = "<pattern> [thickness]",