mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2024-12-23 09:47:38 +00:00
filter set
This commit is contained in:
parent
8dcc005ec1
commit
f5944fbcaf
@ -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();
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
|
@ -57,7 +57,7 @@ public interface Filter {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
default void join(Filter parent) {
|
default void join(final Filter parent) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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];
|
||||||
}
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
|
@ -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<>();
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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]",
|
||||||
|
Loading…
Reference in New Issue
Block a user