This commit is contained in:
Jesse Boyd 2016-04-28 15:00:49 +10:00
parent 4ec9ed3a8d
commit 3b9408d381
28 changed files with 419 additions and 188 deletions

View File

@ -10,7 +10,7 @@ buildscript {
} }
group = 'com.boydti.fawe' group = 'com.boydti.fawe'
version = '3.4.1' version = '3.4.2'
description = """FastAsyncWorldEdit""" description = """FastAsyncWorldEdit"""
subprojects { subprojects {

View File

@ -1,6 +1,6 @@
name: FastAsyncWorldEdit name: FastAsyncWorldEdit
main: com.boydti.fawe.bukkit.FaweBukkit main: com.boydti.fawe.bukkit.FaweBukkit
version: 3.4.1 version: 3.4.2
description: Fast Async WorldEdit plugin description: Fast Async WorldEdit plugin
authors: [Empire92] authors: [Empire92]
loadbefore: [WorldEdit] loadbefore: [WorldEdit]

View File

@ -13,6 +13,8 @@ import com.sk89q.worldedit.LocalWorld;
import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.bukkit.BukkitUtil; import com.sk89q.worldedit.bukkit.BukkitUtil;
import com.sk89q.worldedit.world.biome.BaseBiome; import com.sk89q.worldedit.world.biome.BaseBiome;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -56,6 +58,35 @@ public class BukkitQueue_All extends BukkitQueue_0 {
} }
} }
private volatile boolean timingsEnabled;
@Override
public void startSet(boolean parallel) {
if (parallel) {
try {
Field fieldEnabled = Class.forName("co.aikar.timings.Timings").getDeclaredField("timingsEnabled");
fieldEnabled.setAccessible(true);
timingsEnabled = (boolean) fieldEnabled.get(null);
if (timingsEnabled) {
fieldEnabled.set(null, false);
Method methodCheck = Class.forName("co.aikar.timings.TimingsManager").getDeclaredMethod("recheckEnabled");
methodCheck.setAccessible(true);
methodCheck.invoke(null);
}
} catch (Throwable ignore) {}
try { Class.forName("org.spigotmc.AsyncCatcher").getField("enabled").set(null, false); } catch (Throwable ignore) {}
}
}
@Override
public void endSet(boolean parallel) {
if (parallel) {
try {Field fieldEnabled = Class.forName("co.aikar.timings.Timings").getDeclaredField("timingsEnabled");fieldEnabled.setAccessible(true);fieldEnabled.set(null, timingsEnabled);
} catch (Throwable ignore) {ignore.printStackTrace();}
try { Class.forName("org.spigotmc.AsyncCatcher").getField("enabled").set(null, true); } catch (Throwable ignore) {}
}
}
@Override @Override
public Collection<FaweChunk<Chunk>> sendChunk(Collection<FaweChunk<Chunk>> fcs) { public Collection<FaweChunk<Chunk>> sendChunk(Collection<FaweChunk<Chunk>> fcs) {
return new ArrayList<>(); return new ArrayList<>();

View File

@ -129,7 +129,7 @@ public class BukkitQueue_1_8 extends BukkitQueue_All {
@Override @Override
public void run() { public void run() {
final boolean result = fixLighting(fc, Settings.FIX_ALL_LIGHTING) || !Settings.ASYNC_LIGHTING; final boolean result = fixLighting(fc, Settings.FIX_ALL_LIGHTING) || !Settings.ASYNC_LIGHTING;
TaskManager.IMP.task(new Runnable() { TaskManager.IMP.sync(new Runnable() {
@Override @Override
public void run() { public void run() {
if (!result) { if (!result) {

View File

@ -115,7 +115,7 @@ public class BukkitQueue_1_9 extends BukkitQueue_All {
@Override @Override
public void run() { public void run() {
final boolean result = fixLighting(fc, Settings.FIX_ALL_LIGHTING) || !Settings.ASYNC_LIGHTING; final boolean result = fixLighting(fc, Settings.FIX_ALL_LIGHTING) || !Settings.ASYNC_LIGHTING;
TaskManager.IMP.task(new Runnable() { TaskManager.IMP.sync(new Runnable() {
@Override @Override
public void run() { public void run() {
if (!result) { if (!result) {

View File

@ -45,8 +45,6 @@ import org.bukkit.generator.ChunkGenerator;
public class BukkitQueue_1_9_R1 extends BukkitQueue_All { public class BukkitQueue_1_9_R1 extends BukkitQueue_All {
private IBlockData air = Block.getByCombinedId(0);
public BukkitQueue_1_9_R1(final String world) throws NoSuchMethodException, RuntimeException { public BukkitQueue_1_9_R1(final String world) throws NoSuchMethodException, RuntimeException {
super(world); super(world);
} }
@ -87,7 +85,7 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_All {
@Override @Override
public void run() { public void run() {
final boolean result = fixLighting(fc, Settings.FIX_ALL_LIGHTING) || !Settings.ASYNC_LIGHTING; final boolean result = fixLighting(fc, Settings.FIX_ALL_LIGHTING) || !Settings.ASYNC_LIGHTING;
TaskManager.IMP.task(new Runnable() { TaskManager.IMP.sync(new Runnable() {
@Override @Override
public void run() { public void run() {
if (!result) { if (!result) {
@ -304,7 +302,6 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_All {
continue; continue;
} }
DataPaletteBlock nibble = section.getBlocks(); DataPaletteBlock nibble = section.getBlocks();
Field fieldBits = nibble.getClass().getDeclaredField("b"); Field fieldBits = nibble.getClass().getDeclaredField("b");
fieldBits.setAccessible(true); fieldBits.setAccessible(true);
DataBits bits = (DataBits) fieldBits.get(nibble); DataBits bits = (DataBits) fieldBits.get(nibble);
@ -424,12 +421,7 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_All {
} }
} }
} }
TaskManager.IMP.later(new Runnable() { sendChunk(fs);
@Override
public void run() {
sendChunk(fs);
}
}, 1);
return true; return true;
} }

View File

@ -1,6 +1,6 @@
name: FastAsyncWorldEdit name: FastAsyncWorldEdit
main: com.boydti.fawe.bukkit.FaweBukkit main: com.boydti.fawe.bukkit.FaweBukkit
version: 3.4.1 version: 3.4.2
description: Fast Async WorldEdit plugin description: Fast Async WorldEdit plugin
authors: [Empire92] authors: [Empire92]
loadbefore: [WorldEdit] loadbefore: [WorldEdit]

View File

@ -51,6 +51,7 @@ public class Cancel extends FaweCommand {
session.bypassReorderHistory = nullExtent; session.bypassReorderHistory = nullExtent;
session.faweExtent = nullExtent; session.faweExtent = nullExtent;
queue.clear(); queue.clear();
SetQueue.IMP.dequeue(queue);
} }
} }
} }

View File

@ -5,8 +5,10 @@ import com.boydti.fawe.FaweCache;
import com.boydti.fawe.config.Settings; import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.BufferedRandomAccessFile; import com.boydti.fawe.object.BufferedRandomAccessFile;
import com.boydti.fawe.object.IntegerTrio; import com.boydti.fawe.object.IntegerTrio;
import com.boydti.fawe.object.RunnableVal2;
import com.boydti.fawe.util.TaskManager; import com.boydti.fawe.util.TaskManager;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
@ -173,10 +175,11 @@ public class DiskOptimizedClipboard extends FaweClipboard {
if (raf != null) { if (raf != null) {
close(); close();
} }
lastAccessed = System.currentTimeMillis();
this.raf = new BufferedRandomAccessFile(file, "rw", Settings.BUFFER_SIZE); this.raf = new BufferedRandomAccessFile(file, "rw", Settings.BUFFER_SIZE);
long size = width * height * length * 2l; long size = width * height * length * 2l + HEADER_SIZE;
if (raf.length() != size) { if (raf.length() != size) {
raf.setLength(size + HEADER_SIZE); raf.setLength(size);
// write length etc // write length etc
raf.seek(0); raf.seek(0);
last = 0; last = 0;
@ -208,6 +211,54 @@ public class DiskOptimizedClipboard extends FaweClipboard {
private int zlast; private int zlast;
private int zlasti; private int zlasti;
@Override
public void forEach(final RunnableVal2<Vector,BaseBlock> task, boolean air) {
try {
if (raf == null) {
open();
}
raf.seek(HEADER_SIZE);
BlockVector pos = new BlockVector(0, 0, 0);
int x = 0;
int y = 0;
int z = 0;
long len = (raf.length());
for (long i = HEADER_SIZE; i < len; i+=2) {
pos.x = x;
pos.y = y;
pos.z = z;
if (++x >= width) {
x = 0;
if (++z >= length) {
z = 0;
++y;
}
}
raf.seek(i);
raf.read(buffer);
int id = ((((int) buffer[1] & 0xFF) << 4) + (((int) buffer[0] & 0xFF) >> 4));
if (id == 0 && !air) {
continue;
}
BaseBlock block;
if (!FaweCache.hasData(id)) {
block = FaweCache.CACHE_BLOCK[id << 4];
} else {
block = FaweCache.CACHE_BLOCK[(id << 4) + (buffer[0] & 0xF)];
}
if (FaweCache.hasNBT(id)) {
CompoundTag nbt = nbtMap.get(new IntegerTrio((int) pos.x, (int) pos.y, (int) pos.z));
if (nbt != null) {
block = new BaseBlock(block.getId(), block.getData());
block.setNbtData(nbt);
}
}
task.run(pos, block);
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override @Override
public BaseBlock getBlock(int x, int y, int z) { public BaseBlock getBlock(int x, int y, int z) {
@ -218,6 +269,7 @@ public class DiskOptimizedClipboard extends FaweClipboard {
int i = x + ((ylast == y) ? ylasti : (ylasti = ((ylast = y)) * area)) + ((zlast == z) ? zlasti : (zlasti = (zlast = z) * width)); int i = x + ((ylast == y) ? ylasti : (ylasti = ((ylast = y)) * area)) + ((zlast == z) ? zlasti : (zlasti = (zlast = z) * width));
if (i != last + 1) { if (i != last + 1) {
raf.seek((HEADER_SIZE) + (i << 1)); raf.seek((HEADER_SIZE) + (i << 1));
lastAccessed = System.currentTimeMillis();
} }
raf.read(buffer); raf.read(buffer);
last = i; last = i;
@ -248,10 +300,10 @@ public class DiskOptimizedClipboard extends FaweClipboard {
if (raf == null) { if (raf == null) {
open(); open();
} }
lastAccessed = System.currentTimeMillis();
int i = x + ((ylast == y) ? ylasti : (ylasti = ((ylast = y)) * area)) + ((zlast == z) ? zlasti : (zlasti = (zlast = z) * width)); int i = x + ((ylast == y) ? ylasti : (ylasti = ((ylast = y)) * area)) + ((zlast == z) ? zlasti : (zlasti = (zlast = z) * width));
if (i != last + 1) { if (i != last + 1) {
raf.seek((HEADER_SIZE) + (i << 1)); raf.seek((HEADER_SIZE) + (i << 1));
lastAccessed = System.currentTimeMillis();
} }
last = i; last = i;
final int id = block.getId(); final int id = block.getId();

View File

@ -1,5 +1,6 @@
package com.boydti.fawe.object.clipboard; package com.boydti.fawe.object.clipboard;
import com.boydti.fawe.object.RunnableVal2;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
@ -25,6 +26,8 @@ public abstract class FaweClipboard {
public void setOrigin(Vector offset) {} // Do nothing public void setOrigin(Vector offset) {} // Do nothing
public abstract void forEach(final RunnableVal2<Vector,BaseBlock> task, boolean air);
/** /**
* Stores entity data. * Stores entity data.
*/ */

View File

@ -8,6 +8,26 @@ import java.util.List;
public abstract class LazyClipboard extends FaweClipboard { public abstract class LazyClipboard extends FaweClipboard {
// private final int width, height, length;
//
// public LazyClipboard(int width, int height, int length) {
// this.width = width;
// this.height = height;
// this.length = length;
// }
//
// @Override
// public void forEach(RunnableVal2<Vector, BaseBlock> task, boolean air) {
// BlockVector pos = new BlockVector(0, 0, 0);
// for (pos.x = 0; pos.x < width; pos.x++) {
// for (pos.z = 0; pos.z < width; pos.z++) {
// for (pos.y = 0; pos.y < width; pos.y++) {
// task.run(pos, getBlock((int) pos.x, (int) pos.y, (int) pos.z));
// }
// }
// }
// }
@Override @Override
public abstract BaseBlock getBlock(int x, int y, int z); public abstract BaseBlock getBlock(int x, int y, int z);

View File

@ -2,7 +2,11 @@ package com.boydti.fawe.object.clipboard;
import com.boydti.fawe.FaweCache; import com.boydti.fawe.FaweCache;
import com.boydti.fawe.object.IntegerTrio; import com.boydti.fawe.object.IntegerTrio;
import com.boydti.fawe.object.RunnableVal2;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
@ -69,6 +73,63 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
return block; return block;
} }
@Override
public void forEach(final RunnableVal2<Vector,BaseBlock> task, boolean air) {
BlockVector pos = new BlockVector(0, 0, 0);
int y1max = ((height + 15) >> 4);
for (int x = 0; x < width; x++) {
int i1 = x;
for (int z = 0; z < length; z++) {
int i2 = i1 + z * width;
for (int y = 0; y < y1max; y++) {
int y1 = y << 4;
int i = i2 + y * area;
byte[] idArray = ids[i];
if (idArray == null) {
if (!air) {
continue;
}
for (int y2 = 0; y2 < 16; y2++) {
pos.x = x;
pos.z = z;
pos.y = y1 + y2;
task.run(pos, EditSession.nullBlock);
}
continue;
}
for (int y2 = 0; y2 < idArray.length; y2++) {
int id = idArray[y2] & 0xFF;
if (id == 0 && !air) {
continue;
}
pos.x = x;
pos.z = z;
pos.y = y1 + y2;
BaseBlock block;
if (!FaweCache.hasData(id) || datas == null) {
block = FaweCache.CACHE_BLOCK[id << 4];
} else {
byte[] dataArray = datas[i];
if (dataArray == null) {
block = FaweCache.CACHE_BLOCK[id << 4];
} else {
block = FaweCache.CACHE_BLOCK[(id << 4) + dataArray[y2]];
}
}
if (FaweCache.hasNBT(id)) {
CompoundTag nbt = nbtMap.get(new IntegerTrio((int) pos.x, (int) pos.y, (int) pos.z));
if (nbt != null) {
block = new BaseBlock(block.getId(), block.getData());
block.setNbtData(nbt);
}
}
task.run(pos, block);
}
}
}
}
}
@Override @Override
public boolean setBlock(int x, int y, int z, BaseBlock block) { public boolean setBlock(int x, int y, int z, BaseBlock block) {
final int id = block.getId(); final int id = block.getId();

View File

@ -14,6 +14,7 @@ public abstract class FaweQueue {
public final String world; public final String world;
public LinkedBlockingDeque<EditSession> sessions; public LinkedBlockingDeque<EditSession> sessions;
public long modified = System.currentTimeMillis();
public FaweQueue(String world) { public FaweQueue(String world) {
this.world = world; this.world = world;
@ -47,6 +48,10 @@ public abstract class FaweQueue {
public abstract boolean regenerateChunk(int x, int z); public abstract boolean regenerateChunk(int x, int z);
public void startSet(boolean parallel) {}
public void endSet(boolean parallel) {}
/** /**
* Gets the FaweChunk and sets the requested blocks * Gets the FaweChunk and sets the requested blocks
* @return * @return

View File

@ -4,8 +4,6 @@ import com.boydti.fawe.Fawe;
import com.boydti.fawe.config.Settings; import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.FaweChunk; import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.RunnableVal2; import com.boydti.fawe.object.RunnableVal2;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.LinkedBlockingDeque;
@ -55,6 +53,7 @@ public class SetQueue {
@Override @Override
public void run() { public void run() {
if (inactiveQueues.size() == 0 && activeQueues.size() == 0) { if (inactiveQueues.size() == 0 && activeQueues.size() == 0) {
lastSuccess = System.currentTimeMillis();
tasks(); tasks();
return; return;
} }
@ -81,21 +80,11 @@ public class SetQueue {
return; return;
} }
if (Settings.UNSAFE_PARALLEL_THREADS <= 1) { if (Settings.UNSAFE_PARALLEL_THREADS <= 1) {
SET_TASK.value2.startSet(false);
SET_TASK.run(); SET_TASK.run();
SET_TASK.value2.endSet(false);
} else { } else {
boolean timingsEnabled = true; SET_TASK.value2.startSet(true);
try {
Field fieldEnabled = Class.forName("co.aikar.timings.Timings").getDeclaredField("timingsEnabled");
fieldEnabled.setAccessible(true);
timingsEnabled = (boolean) fieldEnabled.get(null);
if (timingsEnabled) {
fieldEnabled.set(null, false);
Method methodCheck = Class.forName("co.aikar.timings.TimingsManager").getDeclaredMethod("recheckEnabled");
methodCheck.setAccessible(true);
methodCheck.invoke(null);
}
} catch (Throwable ignore) {ignore.printStackTrace();}
try { Class.forName("org.spigotmc.AsyncCatcher").getField("enabled").set(null, false); } catch (Throwable ignore) {}
ArrayList<Thread> threads = new ArrayList<Thread>(); ArrayList<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < Settings.UNSAFE_PARALLEL_THREADS; i++) { for (int i = 0; i < Settings.UNSAFE_PARALLEL_THREADS; i++) {
threads.add(new Thread(SET_TASK)); threads.add(new Thread(SET_TASK));
@ -110,9 +99,7 @@ public class SetQueue {
e.printStackTrace(); e.printStackTrace();
} }
} }
try {Field fieldEnabled = Class.forName("co.aikar.timings.Timings").getDeclaredField("timingsEnabled");fieldEnabled.setAccessible(true);fieldEnabled.set(null, timingsEnabled); SET_TASK.value2.endSet(true);
} catch (Throwable ignore) {ignore.printStackTrace();}
try { Class.forName("org.spigotmc.AsyncCatcher").getField("enabled").set(null, true); } catch (Throwable ignore) {}
} }
} }
}, 1); }, 1);
@ -120,7 +107,14 @@ public class SetQueue {
public void enqueue(FaweQueue queue) { public void enqueue(FaweQueue queue) {
inactiveQueues.remove(queue); inactiveQueues.remove(queue);
activeQueues.add(queue); if (queue.size() > 0 && !activeQueues.contains(queue)) {
activeQueues.add(queue);
}
}
public void dequeue(FaweQueue queue) {
inactiveQueues.remove(queue);
activeQueues.remove(queue);
} }
public List<FaweQueue> getAllQueues() { public List<FaweQueue> getAllQueues() {
@ -150,6 +144,7 @@ public class SetQueue {
while (activeQueues.size() > 0) { while (activeQueues.size() > 0) {
FaweQueue queue = activeQueues.peek(); FaweQueue queue = activeQueues.peek();
if (queue != null && queue.size() > 0) { if (queue != null && queue.size() > 0) {
queue.modified = System.currentTimeMillis();
return queue; return queue;
} else { } else {
activeQueues.poll(); activeQueues.poll();
@ -157,25 +152,21 @@ public class SetQueue {
} }
if (inactiveQueues.size() > 0) { if (inactiveQueues.size() > 0) {
ArrayList<FaweQueue> tmp = new ArrayList<>(inactiveQueues); ArrayList<FaweQueue> tmp = new ArrayList<>(inactiveQueues);
if (Settings.QUEUE_MAX_WAIT != -1) { if (Settings.QUEUE_MAX_WAIT >= 0) {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
if (lastSuccess == 0) { if (lastSuccess != 0) {
lastSuccess = now; long diff = now - lastSuccess;
} if (diff > Settings.QUEUE_MAX_WAIT) {
long diff = now - lastSuccess; for (FaweQueue queue : tmp) {
if (diff > Settings.QUEUE_MAX_WAIT) { if (queue != null && queue.size() > 0) {
for (FaweQueue queue : tmp) { queue.modified = now;
if (queue != null && queue.size() > 0) { return queue;
return queue; } else if (now - queue.modified > Settings.QUEUE_DISCARD_AFTER) {
} else { inactiveQueues.remove(queue);
activeQueues.poll(); }
} }
return null;
} }
if (diff > Settings.QUEUE_DISCARD_AFTER) {
// These edits never finished
inactiveQueues.clear();
}
return null;
} }
} }
if (Settings.QUEUE_SIZE != -1) { if (Settings.QUEUE_SIZE != -1) {
@ -186,9 +177,8 @@ public class SetQueue {
if (total > Settings.QUEUE_SIZE) { if (total > Settings.QUEUE_SIZE) {
for (FaweQueue queue : tmp) { for (FaweQueue queue : tmp) {
if (queue != null && queue.size() > 0) { if (queue != null && queue.size() > 0) {
queue.modified = System.currentTimeMillis();
return queue; return queue;
} else {
activeQueues.poll();
} }
} }
} }

View File

@ -48,16 +48,21 @@ public abstract class TaskManager {
if (async) { if (async) {
async(r); async(r);
} else { } else {
if (Fawe.get().getMainThread() == Thread.currentThread()) { r.run();
if (r != null) {
r.run();
}
} else {
task(r);
}
} }
} }
public void sync(final Runnable r, boolean async) {
if (async) {
async(r);
} else if (r != null && Thread.currentThread() == Fawe.get().getMainThread()){
r.run();
} else {
task(r);
}
}
/** /**
* Run a task later on the main thread * Run a task later on the main thread
* @param r * @param r

View File

@ -19,6 +19,7 @@
package com.sk89q.worldedit.command; package com.sk89q.worldedit.command;
import com.boydti.fawe.object.RunnableVal2;
import com.boydti.fawe.object.clipboard.LazyClipboard; import com.boydti.fawe.object.clipboard.LazyClipboard;
import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.minecraft.util.commands.CommandPermissions;
@ -26,6 +27,7 @@ import com.sk89q.minecraft.util.commands.Logging;
import com.sk89q.worldedit.BlockVector; import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
@ -38,11 +40,13 @@ import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.block.BlockReplace; import com.sk89q.worldedit.function.block.BlockReplace;
import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy; import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.Operations; import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.internal.annotation.Direction; import com.sk89q.worldedit.internal.annotation.Direction;
import com.sk89q.worldedit.internal.annotation.Selection; import com.sk89q.worldedit.internal.annotation.Selection;
import com.sk89q.worldedit.math.transform.AffineTransform; import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.math.transform.Transform;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionSelector; import com.sk89q.worldedit.regions.RegionSelector;
@ -110,6 +114,19 @@ public class ClipboardCommands {
public List<? extends Entity> getEntities() { public List<? extends Entity> getEntities() {
return editSession.getEntities(region); return editSession.getEntities(region);
} }
@Override
public void forEach(RunnableVal2<Vector, BaseBlock> task, boolean air) {
Iterator<BlockVector> iter = region.iterator();
while (iter.hasNext()) {
BlockVector pos = iter.next();
BaseBlock block = getBlock((int) pos.x, (int) pos.y, (int) pos.z);
if (!air && block == EditSession.nullBlock) {
continue;
}
task.run(pos, block);
}
}
}; };
BlockArrayClipboard clipboard = new BlockArrayClipboard(region, lazyClipboard); BlockArrayClipboard clipboard = new BlockArrayClipboard(region, lazyClipboard);
@ -198,13 +215,63 @@ public class ClipboardCommands {
) )
@CommandPermissions("worldedit.clipboard.paste") @CommandPermissions("worldedit.clipboard.paste")
@Logging(PLACEMENT) @Logging(PLACEMENT)
public void paste(Player player, LocalSession session, EditSession editSession, public void paste(Player player, LocalSession session, final EditSession editSession,
@Switch('a') boolean ignoreAirBlocks, @Switch('o') boolean atOrigin,
@Switch('s') boolean selectPasted) throws WorldEditException {
ClipboardHolder holder = session.getClipboard();
if (holder.getTransform().isIdentity()) {
place(player, session, editSession, ignoreAirBlocks, atOrigin, selectPasted);
return;
}
Clipboard clipboard = holder.getClipboard();
Region region = clipboard.getRegion();
Vector to = atOrigin ? clipboard.getOrigin() : session.getPlacementPosition(player);
Operation operation = holder
.createPaste(editSession, editSession.getWorld().getWorldData())
.to(to)
.ignoreAirBlocks(ignoreAirBlocks)
.build();
Operations.completeLegacy(operation);
if (selectPasted) {
Vector max = to.add(region.getMaximumPoint().subtract(region.getMinimumPoint()));
RegionSelector selector = new CuboidRegionSelector(player.getWorld(), to, max);
session.setRegionSelector(player.getWorld(), selector);
selector.learnChanges();
selector.explainRegionAdjust(player, session);
}
player.print("The clipboard has been pasted at " + to);
}
@Command(
aliases = { "/place" },
usage = "",
flags = "sao",
desc = "Place the clipboard's contents",
help =
"Places the clipboard's contents.\n" +
"Flags:\n" +
" -a skips air blocks\n" +
" -o pastes at the original position\n" +
" -s selects the region after pasting",
min = 0,
max = 0
)
// Skips all transforms
@CommandPermissions("worldedit.clipboard.place")
@Logging(PLACEMENT)
public void place(Player player, LocalSession session, final EditSession editSession,
@Switch('a') boolean ignoreAirBlocks, @Switch('o') boolean atOrigin, @Switch('a') boolean ignoreAirBlocks, @Switch('o') boolean atOrigin,
@Switch('s') boolean selectPasted) throws WorldEditException { @Switch('s') boolean selectPasted) throws WorldEditException {
ClipboardHolder holder = session.getClipboard(); ClipboardHolder holder = session.getClipboard();
Clipboard clipboard = holder.getClipboard(); Clipboard clipboard = holder.getClipboard();
Region region = clipboard.getRegion().clone(); Region region = clipboard.getRegion().clone();
Vector origin = clipboard.getOrigin(); Vector origin = clipboard.getOrigin();
final Transform transform = holder.getTransform();
// Optimize for CuboidRegion
if (region instanceof CuboidRegion) { if (region instanceof CuboidRegion) {
CuboidRegion cuboid = (CuboidRegion) region; CuboidRegion cuboid = (CuboidRegion) region;
Vector min = cuboid.getMinimumPoint(); Vector min = cuboid.getMinimumPoint();
@ -213,30 +280,28 @@ public class ClipboardCommands {
cuboid.setPos1(new Vector(0, 0, 0)); cuboid.setPos1(new Vector(0, 0, 0));
} }
Vector to = atOrigin ? origin : session.getPlacementPosition(player); Vector to = atOrigin ? origin : session.getPlacementPosition(player);
int mx = region.getMinimumPoint().getBlockX(); final int tx = to.getBlockX() - origin.getBlockX();
int my = region.getMinimumPoint().getBlockY(); final int ty = to.getBlockY() - origin.getBlockY();
int mz = region.getMinimumPoint().getBlockZ(); final int tz = to.getBlockZ() - origin.getBlockZ();
int tx = to.getBlockX() - origin.getBlockX(); // Optimize for BlockArrayClipboard
int ty = to.getBlockY() - origin.getBlockY();
int tz = to.getBlockZ() - origin.getBlockZ();
Iterator<BlockVector> iter = region.iterator();
if (clipboard instanceof BlockArrayClipboard) { if (clipboard instanceof BlockArrayClipboard) {
BlockArrayClipboard bac = (BlockArrayClipboard) clipboard; BlockArrayClipboard bac = (BlockArrayClipboard) clipboard;
while (iter.hasNext()) { bac.IMP.forEach(new RunnableVal2<Vector, BaseBlock>() {
BlockVector loc = iter.next(); @Override
int x = (int) loc.x; public void run(Vector pos, BaseBlock block) {
int y = (int) loc.y; pos.x += tx;
int z = (int) loc.z; pos.y += ty;
BaseBlock block = bac.getBlockAbs(x, y, z); pos.z += tz;
if (block == EditSession.nullBlock && ignoreAirBlocks) { try {
continue; editSession.setBlock(pos, block);
} catch (MaxChangedBlocksException e) {
throw new RuntimeException(e);
}
} }
loc.x += tx; }, !ignoreAirBlocks);
loc.y += ty;
loc.z += tz;
editSession.setBlock(loc, block);
}
} else { } else {
// Generic optimization for unknown region type
Iterator<BlockVector> iter = region.iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
BlockVector loc = iter.next(); BlockVector loc = iter.next();
BaseBlock block = clipboard.getBlock(loc); BaseBlock block = clipboard.getBlock(loc);
@ -246,7 +311,7 @@ public class ClipboardCommands {
loc.x += tx; loc.x += tx;
loc.y += ty; loc.y += ty;
loc.z += tz; loc.z += tz;
editSession.setBlock(loc, block); editSession.setBlock(transform.apply(loc), block);
} }
} }
// entities // entities
@ -260,7 +325,7 @@ public class ClipboardCommands {
selector.learnChanges(); selector.learnChanges();
selector.explainRegionAdjust(player, session); selector.explainRegionAdjust(player, session);
} }
player.print("The clipboard has been pasted at " + to); player.print("The clipboard has been placed at " + to);
} }
@Command( @Command(

View File

@ -98,48 +98,37 @@ public class SchematicCommands {
player.printError("Unknown schematic format: " + formatName); player.printError("Unknown schematic format: " + formatName);
return; return;
} }
final Closer closer = Closer.create();
try {
final String filePath = f.getCanonicalPath();
final String dirPath = dir.getCanonicalPath();
SetQueue.IMP.addTask(new Runnable() { if (!filePath.substring(0, dirPath.length()).equals(dirPath)) {
@Override player.printError("Clipboard file could not read or it does not exist.");
public void run() { } else {
TaskManager.IMP.async(new Runnable() { final FileInputStream fis = closer.register(new FileInputStream(f));
@Override final BufferedInputStream bis = closer.register(new BufferedInputStream(fis));
public void run() { final ClipboardReader reader = format.getReader(bis);
final Closer closer = Closer.create();
try {
final String filePath = f.getCanonicalPath();
final String dirPath = dir.getCanonicalPath();
if (!filePath.substring(0, dirPath.length()).equals(dirPath)) { final WorldData worldData = player.getWorld().getWorldData();
player.printError("Clipboard file could not read or it does not exist."); final Clipboard clipboard;
} else { if (reader instanceof SchematicReader) {
final FileInputStream fis = closer.register(new FileInputStream(f)); clipboard = ((SchematicReader) reader).read(player.getWorld().getWorldData(), player.getUniqueId());
final BufferedInputStream bis = closer.register(new BufferedInputStream(fis)); } else {
final ClipboardReader reader = format.getReader(bis); clipboard = reader.read(player.getWorld().getWorldData());
}
final WorldData worldData = player.getWorld().getWorldData(); session.setClipboard(new ClipboardHolder(clipboard, worldData));
final Clipboard clipboard; log.info(player.getName() + " loaded " + filePath);
if (reader instanceof SchematicReader) { player.print(filename + " loaded. Paste it with //paste");
clipboard = ((SchematicReader) reader).read(player.getWorld().getWorldData(), player.getUniqueId());
} else {
clipboard = reader.read(player.getWorld().getWorldData());
}
session.setClipboard(new ClipboardHolder(clipboard, worldData));
log.info(player.getName() + " loaded " + filePath);
player.print(filename + " loaded. Paste it with //paste");
}
} catch (final IOException e) {
player.printError("Schematic could not read or it does not exist: " + e.getMessage());
log.log(Level.WARNING, "Failed to load a saved clipboard", e);
} finally {
try {
closer.close();
} catch (final IOException ignored) {}
}
}
});
} }
}); } catch (final IOException e) {
player.printError("Schematic could not read or it does not exist: " + e.getMessage());
log.log(Level.WARNING, "Failed to load a saved clipboard", e);
} finally {
try {
closer.close();
} catch (final IOException ignored) {}
}
} }
@Command(aliases = { "save" }, usage = "[<format>] <filename>", desc = "Save a schematic into your clipboard") @Command(aliases = { "save" }, usage = "[<format>] <filename>", desc = "Save a schematic into your clipboard")

View File

@ -19,6 +19,14 @@
package com.sk89q.worldedit.command.composition; package com.sk89q.worldedit.command.composition;
import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.NullChangeSet;
import com.boydti.fawe.object.RegionWrapper;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.util.FaweQueue;
import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.WEManager;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.sk89q.minecraft.util.commands.CommandException; import com.sk89q.minecraft.util.commands.CommandException;
@ -28,16 +36,25 @@ import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.IncompleteRegionException; import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.function.Contextual; import com.sk89q.worldedit.function.Contextual;
import com.sk89q.worldedit.function.EditContext; import com.sk89q.worldedit.function.EditContext;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.block.BlockReplace;
import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.Operations; import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.visitor.RegionVisitor;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.command.argument.CommandArgs; import com.sk89q.worldedit.util.command.argument.CommandArgs;
import com.sk89q.worldedit.util.command.composition.CommandExecutor; import com.sk89q.worldedit.util.command.composition.CommandExecutor;
import com.sk89q.worldedit.util.command.composition.SimpleCommand; import com.sk89q.worldedit.util.command.composition.SimpleCommand;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.List; import java.util.List;
@ -82,60 +99,60 @@ public class SelectionCommand extends SimpleCommand<Operation> {
Operation operation = operationFactory.createFromContext(editContext); Operation operation = operationFactory.createFromContext(editContext);
// Shortcut // Shortcut
// if (selection instanceof CuboidRegion && editSession.hasFastMode() && operation instanceof RegionVisitor) { if (selection instanceof CuboidRegion && editSession.hasFastMode() && operation instanceof RegionVisitor) {
// CuboidRegion cuboid = (CuboidRegion) selection; CuboidRegion cuboid = (CuboidRegion) selection;
// RegionFunction function = ((RegionVisitor) operation).function; RegionFunction function = ((RegionVisitor) operation).function;
// RegionWrapper current = new RegionWrapper(cuboid.getMinimumPoint(), cuboid.getMaximumPoint()); RegionWrapper current = new RegionWrapper(cuboid.getMinimumPoint(), cuboid.getMaximumPoint());
// FawePlayer fp = FawePlayer.wrap(player); FawePlayer fp = FawePlayer.wrap(player);
// HashSet<RegionWrapper> mask = WEManager.IMP.getMask(fp); HashSet<RegionWrapper> mask = WEManager.IMP.getMask(fp);
//
// if (function instanceof BlockReplace && mask.size() == 1 && mask.iterator().next().contains(current)) { if (function instanceof BlockReplace && mask.size() == 1 && mask.iterator().next().contains(current)) {
// try { try {
// BlockReplace replace = ((BlockReplace) function); BlockReplace replace = ((BlockReplace) function);
// Field field = replace.getClass().getDeclaredField("pattern"); Field field = replace.getClass().getDeclaredField("pattern");
// field.setAccessible(true); field.setAccessible(true);
// Pattern pattern = (Pattern) field.get(replace); Pattern pattern = (Pattern) field.get(replace);
// if (pattern instanceof BlockPattern) { if (pattern instanceof BlockPattern) {
// BaseBlock block = ((BlockPattern) pattern).getBlock(); BaseBlock block = ((BlockPattern) pattern).getBlock();
// final FaweQueue queue = editSession.getQueue(); final FaweQueue queue = editSession.getQueue();
// final int minY = cuboid.getMinimumY(); final int minY = cuboid.getMinimumY();
// final int maxY = cuboid.getMaximumY(); final int maxY = cuboid.getMaximumY();
//
// final int id = block.getId(); final int id = block.getId();
// final byte data = (byte) block.getData(); final byte data = (byte) block.getData();
// final FaweChunk<?> fc = queue.getChunk(0, 0); final FaweChunk<?> fc = queue.getChunk(0, 0);
// fc.fillCuboid(0, 15, minY, maxY, 0, 15, id, data); fc.fillCuboid(0, 15, minY, maxY, 0, 15, id, data);
//
// int bcx = (current.minX) >> 4; int bcx = (current.minX) >> 4;
// int bcz = (current.minZ) >> 4; int bcz = (current.minZ) >> 4;
//
// int tcx = (current.maxX) >> 4; int tcx = (current.maxX) >> 4;
// int tcz = (current.maxZ) >> 4; int tcz = (current.maxZ) >> 4;
// // [chunkx, chunkz, pos1x, pos1z, pos2x, pos2z, isedge] // [chunkx, chunkz, pos1x, pos1z, pos2x, pos2z, isedge]
// MainUtil.chunkTaskSync(current, new RunnableVal<int[]>() { MainUtil.chunkTaskSync(current, new RunnableVal<int[]>() {
// @Override @Override
// public void run(int[] value) { public void run(int[] value) {
// FaweChunk newChunk; FaweChunk newChunk;
// if (value[6] == 0) { if (value[6] == 0) {
// newChunk = fc.copy(true); newChunk = fc.copy(true);
// newChunk.setLoc(queue, value[0], value[1]); newChunk.setLoc(queue, value[0], value[1]);
// } else { } else {
// newChunk = queue.getChunk(value[0], value[1]); newChunk = queue.getChunk(value[0], value[1]);
// newChunk.fillCuboid(value[2] & 15, value[4] & 15, minY, maxY, value[3] & 15, value[5] & 15, id, data); newChunk.fillCuboid(value[2] & 15, value[4] & 15, minY, maxY, value[3] & 15, value[5] & 15, id, data);
// } }
// newChunk.addToQueue(); newChunk.addToQueue();
// } }
// }); });
// queue.enqueue(); queue.enqueue();
// editSession.setChangeSet(new NullChangeSet()); editSession.setChangeSet(new NullChangeSet());
// actor.print("[FAWE] Finished queueing " + cuboid.getArea() + " blocks."); actor.print("[FAWE] Finished queueing " + cuboid.getArea() + " blocks.");
// return null; return null;
// } }
// } catch (Throwable e) { } catch (Throwable e) {
// e.printStackTrace(); e.printStackTrace();
// } }
// } }
// } }
Operations.completeBlindly(operation); Operations.completeBlindly(operation);
List<String> messages = Lists.newArrayList(); List<String> messages = Lists.newArrayList();

View File

@ -130,7 +130,7 @@ public class FaweForge implements IFawe {
@Override @Override
public void startMetrics() { public void startMetrics() {
try { try {
ForgeMetrics metrics = new ForgeMetrics("FastAsyncWorldEdit", "3.4.1"); ForgeMetrics metrics = new ForgeMetrics("FastAsyncWorldEdit", "3.4.2");
metrics.start(); metrics.start();
debug("[FAWE] &6Metrics enabled."); debug("[FAWE] &6Metrics enabled.");
} catch (Throwable e) { } catch (Throwable e) {

View File

@ -19,7 +19,7 @@ import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.EntityJoinWorldEvent; import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@Mod(modid = "com.boydti.fawe", name = "FastAsyncWorldEdit", version = "3.4.1", acceptableRemoteVersions = "*") @Mod(modid = "com.boydti.fawe", name = "FastAsyncWorldEdit", version = "3.4.2", acceptableRemoteVersions = "*")
public class ForgeMain { public class ForgeMain {
private static FaweForge IMP; private static FaweForge IMP;
private Logger logger; private Logger logger;

View File

@ -335,7 +335,7 @@ public class ForgeQueue_All extends FaweQueue {
@Override @Override
public void run() { public void run() {
final boolean result = fixLighting(fc, Settings.FIX_ALL_LIGHTING) || !Settings.ASYNC_LIGHTING; final boolean result = fixLighting(fc, Settings.FIX_ALL_LIGHTING) || !Settings.ASYNC_LIGHTING;
TaskManager.IMP.task(new Runnable() { TaskManager.IMP.sync(new Runnable() {
@Override @Override
public void run() { public void run() {
if (!result) { if (!result) {

View File

@ -2,7 +2,7 @@
"modid": "com.boydti.fawe", "modid": "com.boydti.fawe",
"name": "FastAsyncWorldEdit", "name": "FastAsyncWorldEdit",
"description": "Extreme WorldEdit optimizations, no lag, low memory usage, area + tile + entity limits, block logging + rollback", "description": "Extreme WorldEdit optimizations, no lag, low memory usage, area + tile + entity limits, block logging + rollback",
"version": "3.4.1", "version": "3.4.2",
"mcVersion": "1.7.10", "mcVersion": "1.7.10",
"dependencies": [ "dependencies": [
"WorldEdit" "WorldEdit"

View File

@ -131,7 +131,7 @@ public class FaweForge implements IFawe {
@Override @Override
public void startMetrics() { public void startMetrics() {
try { try {
com.boydti.fawe.forge.ForgeMetrics metrics = new com.boydti.fawe.forge.ForgeMetrics("FastAsyncWorldEdit", "3.4.1"); com.boydti.fawe.forge.ForgeMetrics metrics = new com.boydti.fawe.forge.ForgeMetrics("FastAsyncWorldEdit", "3.4.2");
metrics.start(); metrics.start();
debug("[FAWE] &6Metrics enabled."); debug("[FAWE] &6Metrics enabled.");
} catch (Throwable e) { } catch (Throwable e) {

View File

@ -19,7 +19,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.PlayerEvent; import net.minecraftforge.fml.common.gameevent.PlayerEvent;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@Mod(modid = "com.boydti.fawe", name = "FastAsyncWorldEdit", version = "3.4.1", acceptableRemoteVersions = "*") @Mod(modid = "com.boydti.fawe", name = "FastAsyncWorldEdit", version = "3.4.2", acceptableRemoteVersions = "*")
public class ForgeMain { public class ForgeMain {
private static com.boydti.fawe.forge.FaweForge IMP; private static com.boydti.fawe.forge.FaweForge IMP;
private Logger logger; private Logger logger;

View File

@ -290,7 +290,7 @@ public class ForgeQueue_All extends FaweQueue {
@Override @Override
public void run() { public void run() {
final boolean result = fixLighting(fc, Settings.FIX_ALL_LIGHTING) || !Settings.ASYNC_LIGHTING; final boolean result = fixLighting(fc, Settings.FIX_ALL_LIGHTING) || !Settings.ASYNC_LIGHTING;
TaskManager.IMP.task(new Runnable() { TaskManager.IMP.sync(new Runnable() {
@Override @Override
public void run() { public void run() {
if (!result) { if (!result) {

View File

@ -8,7 +8,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
<artifactId>FastAsyncWorldEdit</artifactId> <artifactId>FastAsyncWorldEdit</artifactId>
<version>3.4.1</version> <version>3.4.2</version>
<name>FastAsyncWorldEdit</name> <name>FastAsyncWorldEdit</name>
<packaging>jar</packaging> <packaging>jar</packaging>
<build> <build>

View File

@ -18,7 +18,7 @@ import org.spongepowered.api.plugin.PluginContainer;
import org.spongepowered.api.profile.GameProfileManager; import org.spongepowered.api.profile.GameProfileManager;
import org.spongepowered.api.world.World; import org.spongepowered.api.world.World;
@Plugin(id = "com.boydti.fawe", name = "FastAsyncWorldEdit", description = "Lagless WorldEdit, Area restrictions, Memory mangement, Block logging", url = "https://github.com/boy0001/FastAsyncWorldedit", version = "3.4.1", authors = "Empire92") @Plugin(id = "com.boydti.fawe", name = "FastAsyncWorldEdit", description = "Lagless WorldEdit, Area restrictions, Memory mangement, Block logging", url = "https://github.com/boy0001/FastAsyncWorldedit", version = "3.4.2", authors = "Empire92")
public class SpongeMain { public class SpongeMain {
public PluginContainer plugin; public PluginContainer plugin;

View File

@ -119,7 +119,7 @@ public class SpongeQueue_1_8 extends SpongeQueue_0 {
@Override @Override
public void run() { public void run() {
final boolean result = fixLighting(fc, Settings.FIX_ALL_LIGHTING) || !Settings.ASYNC_LIGHTING; final boolean result = fixLighting(fc, Settings.FIX_ALL_LIGHTING) || !Settings.ASYNC_LIGHTING;
TaskManager.IMP.task(new Runnable() { TaskManager.IMP.sync(new Runnable() {
@Override @Override
public void run() { public void run() {
if (!result) { if (!result) {