Revert "Upstream, generics, formatting"

This reverts commit cd88e513a8.
This commit is contained in:
NotMyFault 2019-06-12 15:45:41 +02:00
parent 6f9fa018b2
commit ec001b8d3b
126 changed files with 3093 additions and 2490 deletions

View File

@ -15,13 +15,12 @@ import org.bukkit.ChatColor;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.command.ConsoleCommandSender; import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class BukkitPlayer extends FawePlayer<Player> { public class BukkitPlayer extends FawePlayer<Player> {
private static ConsoleCommandSender console; private static ConsoleCommandSender console;
public BukkitPlayer(@NotNull final Player parent) { public BukkitPlayer(final Player parent) {
super(parent); super(parent);
} }

View File

@ -81,7 +81,7 @@ public class FaweBukkit implements IFawe, Listener {
return this.vault; return this.vault;
} }
public FaweBukkit(WorldEditPlugin plugin) { public FaweBukkit(Plugin plugin) {
this.plugin = plugin; this.plugin = plugin;
try { try {
Settings.IMP.TICK_LIMITER.ENABLED = !Bukkit.hasWhitelist(); Settings.IMP.TICK_LIMITER.ENABLED = !Bukkit.hasWhitelist();

View File

@ -217,10 +217,10 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
super(width, length, regionFolder); super(width, length, regionFolder);
blocks = new DifferentialBlockBuffer(width, length); blocks = new DifferentialBlockBuffer(width, length);
heights = new DifferentialArray<>(new byte[getArea()]); heights = new DifferentialArray(new byte[getArea()]);
biomes = new DifferentialArray<>(new byte[getArea()]); biomes = new DifferentialArray(new byte[getArea()]);
floor = new DifferentialArray<>(new int[getArea()]); floor = new DifferentialArray(new int[getArea()]);
main = new DifferentialArray<>(new int[getArea()]); main = new DifferentialArray(new int[getArea()]);
int stone = BlockID.STONE; int stone = BlockID.STONE;
int grass = BlockTypes.GRASS_BLOCK.getDefaultState().with(PropertyKey.SNOWY, false).getInternalId(); int grass = BlockTypes.GRASS_BLOCK.getDefaultState().with(PropertyKey.SNOWY, false).getInternalId();

View File

@ -6,6 +6,7 @@ import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.FaweQueue; import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.io.FastByteArrayOutputStream; import com.boydti.fawe.object.io.FastByteArrayOutputStream;
import com.boydti.fawe.object.number.MutableLong; import com.boydti.fawe.object.number.MutableLong;
import com.boydti.fawe.util.ArrayUtil;
import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.ReflectionUtils; import com.boydti.fawe.util.ReflectionUtils;
@ -190,8 +191,8 @@ public class MCAChunk extends FaweChunk<Void> {
setNibble(endIndex, thisSkyLight, (byte) 0); setNibble(endIndex, thisSkyLight, (byte) 0);
setNibble(endIndex, thisBlockLight, (byte) 0); setNibble(endIndex, thisBlockLight, (byte) 0);
} }
Arrays.fill(thisBlockLight, startIndexShift, endIndex + 1, (byte) 0); ArrayUtil.fill(thisSkyLight, startIndexShift, endIndexShift + 1, (byte) 0);
Arrays.fill(thisBlockLight, startIndexShift, endIndexShift + 1, (byte) 0); ArrayUtil.fill(thisBlockLight, startIndexShift, endIndexShift + 1, (byte) 0);
} }
} }
continue; continue;
@ -291,8 +292,8 @@ public class MCAChunk extends FaweChunk<Void> {
if (otherIds == null) { if (otherIds == null) {
if (currentIds != null) { if (currentIds != null) {
Arrays.fill(currentIds, indexStart, indexEnd, 0); Arrays.fill(currentIds, indexStart, indexEnd, 0);
Arrays.fill(skyLight[thisLayer], indexStartShift, indexEndShift, (byte) 0); ArrayUtil.fill(skyLight[thisLayer], indexStartShift, indexEndShift, (byte) 0);
Arrays.fill(blockLight[thisLayer], indexStartShift, indexEndShift, (byte) 0); ArrayUtil.fill(blockLight[thisLayer], indexStartShift, indexEndShift, (byte) 0);
} }
} else { } else {
if (currentIds == null) { if (currentIds == null) {
@ -319,8 +320,8 @@ public class MCAChunk extends FaweChunk<Void> {
continue; continue;
} }
Arrays.fill(thisIds, thisStartIndex, thisStartIndex + 256, 0); Arrays.fill(thisIds, thisStartIndex, thisStartIndex + 256, 0);
Arrays.fill(this.skyLight[thisLayer], thisStartIndexShift, thisStartIndexShift + 128, (byte) 0); ArrayUtil.fill(this.skyLight[thisLayer], thisStartIndexShift, thisStartIndexShift + 128, (byte) 0);
Arrays.fill(this.blockLight[thisLayer], thisStartIndexShift, thisStartIndexShift + 128, (byte) 0); ArrayUtil.fill(this.blockLight[thisLayer], thisStartIndexShift, thisStartIndexShift + 128, (byte) 0);
continue; continue;
} else if (thisIds == null) { } else if (thisIds == null) {
ids[thisLayer] = thisIds = new int[4096]; ids[thisLayer] = thisIds = new int[4096];

View File

@ -56,9 +56,24 @@ public class MCAFile {
private final int X, Z; private final int X, Z;
private final Int2ObjectOpenHashMap<MCAChunk> chunks = new Int2ObjectOpenHashMap<>(); private final Int2ObjectOpenHashMap<MCAChunk> chunks = new Int2ObjectOpenHashMap<>();
final ThreadLocal<byte[]> byteStore1 = ThreadLocal.withInitial(() -> new byte[4096]); final ThreadLocal<byte[]> byteStore1 = new ThreadLocal<byte[]>() {
final ThreadLocal<byte[]> byteStore2 = ThreadLocal.withInitial(() -> new byte[4096]); @Override
final ThreadLocal<byte[]> byteStore3 = ThreadLocal.withInitial(() -> new byte[1024]); protected byte[] initialValue() {
return new byte[4096];
}
};
final ThreadLocal<byte[]> byteStore2 = new ThreadLocal<byte[]>() {
@Override
protected byte[] initialValue() {
return new byte[4096];
}
};
final ThreadLocal<byte[]> byteStore3 = new ThreadLocal<byte[]>() {
@Override
protected byte[] initialValue() {
return new byte[1024];
}
};
public MCAFile(FaweQueue parent, File file) { public MCAFile(FaweQueue parent, File file) {
this.queue = parent; this.queue = parent;
@ -189,10 +204,9 @@ public class MCAFile {
if (offset == 0) { if (offset == 0) {
return null; return null;
} }
MCAChunk chunk; NBTInputStream nis = getChunkIS(offset);
try (NBTInputStream nis = getChunkIS(offset)) { MCAChunk chunk = new MCAChunk(nis, queue, cx, cz, false);
chunk = new MCAChunk(nis, queue, cx, cz, false); nis.close();
}
int pair = MathMan.pair((short) (cx & 31), (short) (cz & 31)); int pair = MathMan.pair((short) (cx & 31), (short) (cz & 31));
synchronized (chunks) { synchronized (chunks) {
chunks.put(pair, chunk); chunks.put(pair, chunk);
@ -333,6 +347,7 @@ public class MCAFile {
public void streamChunk(byte[] data, RunnableVal<NBTStreamer> withStream) throws IOException { public void streamChunk(byte[] data, RunnableVal<NBTStreamer> withStream) throws IOException {
if (data != null) { if (data != null) {
try { try {
FastByteArrayInputStream nbtIn = new FastByteArrayInputStream(data);
FastByteArrayInputStream bais = new FastByteArrayInputStream(data); FastByteArrayInputStream bais = new FastByteArrayInputStream(data);
InflaterInputStream iis = new InflaterInputStream(bais, new Inflater(), 1); InflaterInputStream iis = new InflaterInputStream(bais, new Inflater(), 1);
fieldBuf2.set(iis, byteStore2.get()); fieldBuf2.set(iis, byteStore2.get());
@ -377,7 +392,8 @@ public class MCAFile {
return null; return null;
} }
byte[] uncompressed = chunk.toBytes(byteStore3.get()); byte[] uncompressed = chunk.toBytes(byteStore3.get());
return MainUtil.compress(uncompressed, byteStore2.get(), null); byte[] compressed = MainUtil.compress(uncompressed, byteStore2.get(), null);
return compressed;
} }
private byte[] getChunkBytes(int cx, int cz) throws Exception { private byte[] getChunkBytes(int cx, int cz) throws Exception {
@ -493,11 +509,13 @@ public class MCAFile {
modified = true; modified = true;
chunk.setLastUpdate(now); chunk.setLastUpdate(now);
if (!chunk.isDeleted()) { if (!chunk.isDeleted()) {
pool.submit(() -> { pool.submit(new Runnable() {
@Override
public void run() {
try { try {
byte[] compressed = toBytes(chunk); byte[] compressed = toBytes(chunk);
int pair = MathMan.pair((short) (chunk.getX() & 31), (short) (chunk.getZ() & 31)); int pair = MathMan.pair((short) (chunk.getX() & 31), (short) (chunk.getZ() & 31));
Int2ObjectOpenHashMap<byte[]> map; Int2ObjectOpenHashMap map;
if (getOffset(chunk.getX(), chunk.getZ()) == 0) { if (getOffset(chunk.getX(), chunk.getZ()) == 0) {
map = append; map = append;
} else { } else {
@ -509,6 +527,7 @@ public class MCAFile {
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
} }
}
}); });
} }
} }

View File

@ -1,6 +1,7 @@
package com.boydti.fawe.jnbt.anvil; package com.boydti.fawe.jnbt.anvil;
import com.boydti.fawe.Fawe; import com.boydti.fawe.Fawe;
import com.boydti.fawe.example.IntFaweChunk;
import com.boydti.fawe.example.NMSMappedFaweQueue; import com.boydti.fawe.example.NMSMappedFaweQueue;
import com.boydti.fawe.example.NullFaweChunk; import com.boydti.fawe.example.NullFaweChunk;
import com.boydti.fawe.jnbt.anvil.filters.DelegateMCAFilter; import com.boydti.fawe.jnbt.anvil.filters.DelegateMCAFilter;
@ -17,7 +18,6 @@ import com.boydti.fawe.util.MainUtil;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeType;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
@ -25,6 +25,11 @@ import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.StandardCopyOption; import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.BasicFileAttributes;
import java.util.Collection;
import java.util.Comparator;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -34,7 +39,12 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
private NMSMappedFaweQueue parentNMS; private NMSMappedFaweQueue parentNMS;
private final boolean hasSky; private final boolean hasSky;
private final File saveFolder; private final File saveFolder;
private final ThreadLocal<MutableMCABackedBaseBlock> blockStore = ThreadLocal.withInitial(MutableMCABackedBaseBlock::new); private final ThreadLocal<MutableMCABackedBaseBlock> blockStore = new ThreadLocal<MutableMCABackedBaseBlock>() {
@Override
protected MutableMCABackedBaseBlock initialValue() {
return new MutableMCABackedBaseBlock();
}
};
@Override @Override
protected void finalize() throws Throwable { protected void finalize() throws Throwable {
@ -114,7 +124,7 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
boolean changed = false; boolean changed = false;
for (int otherCZ = otherBCZ; otherCZ <= otherTCZ; otherCZ++) { for (int otherCZ = otherBCZ; otherCZ <= otherTCZ; otherCZ++) {
for (int otherCX = otherBCX; otherCX <= otherTCX; otherCX++) { for (int otherCX = otherBCX; otherCX <= otherTCX; otherCX++) {
FaweChunk<? extends Object> chunk; FaweChunk chunk;
synchronized (this) { synchronized (this) {
chunk = this.getFaweChunk(otherCX, otherCZ); chunk = this.getFaweChunk(otherCX, otherCZ);
} }
@ -192,7 +202,7 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
int tz = bz + 15; int tz = bz + 15;
if (oX == 0 && oZ == 0) { if (oX == 0 && oZ == 0) {
if (bx >= regionTo.minX && tx <= regionTo.maxX && bz >= regionTo.minZ && tz <= regionTo.maxZ) { if (bx >= regionTo.minX && tx <= regionTo.maxX && bz >= regionTo.minZ && tz <= regionTo.maxZ) {
FaweChunk<? extends Object> chunk = from.getFaweChunk(cx - oCX, cz - oCZ); FaweChunk chunk = from.getFaweChunk(cx - oCX, cz - oCZ);
if (!(chunk instanceof NullFaweChunk)) { if (!(chunk instanceof NullFaweChunk)) {
// if (regionTo.minY == 0 && regionTo.maxY == 255) { // if (regionTo.minY == 0 && regionTo.maxY == 255) {
// System.out.println("Vertical"); // System.out.println("Vertical");
@ -241,7 +251,7 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
int cbz = (cz << 4) - oZ; int cbz = (cz << 4) - oZ;
for (int otherCZ = otherBCZ; otherCZ <= otherTCZ; otherCZ++) { for (int otherCZ = otherBCZ; otherCZ <= otherTCZ; otherCZ++) {
for (int otherCX = otherBCX; otherCX <= otherTCX; otherCX++) { for (int otherCX = otherBCX; otherCX <= otherTCX; otherCX++) {
FaweChunk<? extends Object> chunk = from.getFaweChunk(otherCX, otherCZ); FaweChunk chunk = from.getFaweChunk(otherCX, otherCZ);
if (!(chunk instanceof NullFaweChunk)) { if (!(chunk instanceof NullFaweChunk)) {
MCAChunk other = (MCAChunk) chunk; MCAChunk other = (MCAChunk) chunk;
int ocbx = otherCX << 4; int ocbx = otherCX << 4;
@ -437,7 +447,7 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
final int minMCAZ = region.minZ >> 9; final int minMCAZ = region.minZ >> 9;
final int maxMCAX = region.maxX >> 9; final int maxMCAX = region.maxX >> 9;
final int maxMCAZ = region.maxZ >> 9; final int maxMCAZ = region.maxZ >> 9;
long mcaArea = (maxMCAX - minMCAX + 1L) * (maxMCAZ - minMCAZ + 1L); long mcaArea = (maxMCAX - minMCAX + 1l) * (maxMCAZ - minMCAZ + 1l);
if (mcaArea < 128) { if (mcaArea < 128) {
this.filterWorld(delegate, new RunnableVal2<Path, RunnableVal2<Path, BasicFileAttributes>>() { this.filterWorld(delegate, new RunnableVal2<Path, RunnableVal2<Path, BasicFileAttributes>>() {
@Override @Override
@ -504,7 +514,9 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
finalFile.forEachSortedChunk(new RunnableVal4<Integer, Integer, Integer, Integer>() { finalFile.forEachSortedChunk(new RunnableVal4<Integer, Integer, Integer, Integer>() {
@Override @Override
public void run(final Integer rcx, final Integer rcz, Integer offset, Integer size) { public void run(final Integer rcx, final Integer rcz, Integer offset, Integer size) {
pool.submit(() -> { pool.submit(new Runnable() {
@Override
public void run() {
try { try {
int cx = cbx + rcx; int cx = cbx + rcx;
int cz = cbz + rcz; int cz = cbz + rcz;
@ -545,6 +557,7 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
} }
}
}); });
} }
}); });
@ -555,8 +568,8 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
try { try {
original.close(pool); original.close(pool);
file.delete(); file.delete();
} catch (Throwable e) { } catch (Throwable ignore) {
e.printStackTrace(); ignore.printStackTrace();
} }
} }
pool.awaitQuiescence(Long.MAX_VALUE, TimeUnit.MILLISECONDS); pool.awaitQuiescence(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
@ -566,8 +579,8 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
file.delete(); file.delete();
} }
} }
} catch (Throwable e) { } catch (Throwable ignore) {
e.printStackTrace(); ignore.printStackTrace();
} }
} }
}; };
@ -597,6 +610,15 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
}); });
} }
public <G, T extends MCAFilter<G>> T filterWorld(final T filter, Comparator<File> comparator) {
return filterWorld(filter, new RunnableVal2<Path, RunnableVal2<Path, BasicFileAttributes>>() {
@Override
public void run(Path value1, RunnableVal2<Path, BasicFileAttributes> value2) {
MainUtil.forEachFile(value1, value2, comparator);
}
});
}
@Override @Override
public boolean supports(Capability capability) { public boolean supports(Capability capability) {
if (capability == Capability.CHANGE_TASKS) { if (capability == Capability.CHANGE_TASKS) {

View File

@ -3,6 +3,7 @@ package com.boydti.fawe.jnbt.anvil.filters;
import com.boydti.fawe.jnbt.anvil.MCAChunk; import com.boydti.fawe.jnbt.anvil.MCAChunk;
import com.boydti.fawe.jnbt.anvil.MCAFilterCounter; import com.boydti.fawe.jnbt.anvil.MCAFilterCounter;
import com.boydti.fawe.object.number.MutableLong; import com.boydti.fawe.object.number.MutableLong;
import com.boydti.fawe.util.ArrayUtil;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
import java.util.Arrays; import java.util.Arrays;

View File

@ -3,9 +3,9 @@ package com.boydti.fawe.object;
import java.util.function.Consumer; import java.util.function.Consumer;
public abstract class DelegateConsumer<T> implements Consumer<T> { public abstract class DelegateConsumer<T> implements Consumer<T> {
private final Consumer<T> parent; private final Consumer parent;
public DelegateConsumer(Consumer<T> parent) { public DelegateConsumer(Consumer parent) {
this.parent = parent; this.parent = parent;
} }

View File

@ -23,7 +23,7 @@ public class CFIChange implements Change {
} }
private HeightMapMCAGenerator getQueue(UndoContext context) { private HeightMapMCAGenerator getQueue(UndoContext context) {
ExtentTraverser found = new ExtentTraverser<>(context.getExtent()).find(HasFaweQueue.class); ExtentTraverser found = new ExtentTraverser(context.getExtent()).find(HasFaweQueue.class);
if (found != null) { if (found != null) {
FaweQueue queue = ((HasFaweQueue) found.get()).getQueue(); FaweQueue queue = ((HasFaweQueue) found.get()).getQueue();
if (queue instanceof HeightMapMCAGenerator) return (HeightMapMCAGenerator) queue; if (queue instanceof HeightMapMCAGenerator) return (HeightMapMCAGenerator) queue;

View File

@ -44,7 +44,7 @@ public class MutableBlockChange implements Change {
if (!checkedQueue) { if (!checkedQueue) {
checkedQueue = true; checkedQueue = true;
Extent extent = context.getExtent(); Extent extent = context.getExtent();
ExtentTraverser found = new ExtentTraverser<>(extent).find(HasFaweQueue.class); ExtentTraverser found = new ExtentTraverser(extent).find(HasFaweQueue.class);
if (found != null) { if (found != null) {
(queue = ((HasFaweQueue) found.get()).getQueue()).setBlock(x, y, z, combinedId); (queue = ((HasFaweQueue) found.get()).getQueue()).setBlock(x, y, z, combinedId);
} else { } else {

View File

@ -43,7 +43,7 @@ public class MutableChunkChange implements Change {
if (!checkedQueue) { if (!checkedQueue) {
checkedQueue = true; checkedQueue = true;
Extent extent = context.getExtent(); Extent extent = context.getExtent();
ExtentTraverser found = new ExtentTraverser<>(extent).find(HasFaweQueue.class); ExtentTraverser found = new ExtentTraverser(extent).find(HasFaweQueue.class);
if (found != null) { if (found != null) {
perform(queue = ((HasFaweQueue) found.get()).getQueue(), undo); perform(queue = ((HasFaweQueue) found.get()).getQueue(), undo);
} else { } else {

View File

@ -48,7 +48,7 @@ public class MutableEntityChange implements Change {
public void delete(UndoContext context) { public void delete(UndoContext context) {
Extent extent = context.getExtent(); Extent extent = context.getExtent();
ExtentTraverser<FastWorldEditExtent> find = new ExtentTraverser<>(extent).find(FastWorldEditExtent.class); ExtentTraverser<FastWorldEditExtent> find = new ExtentTraverser(extent).find(FastWorldEditExtent.class);
if (find != null) { if (find != null) {
FastWorldEditExtent fwee = find.get(); FastWorldEditExtent fwee = find.get();
Map<String, Tag> map = tag.getValue(); Map<String, Tag> map = tag.getValue();
@ -85,7 +85,7 @@ public class MutableEntityChange implements Change {
if (!checkedQueue) { if (!checkedQueue) {
checkedQueue = true; checkedQueue = true;
Extent extent = context.getExtent(); Extent extent = context.getExtent();
ExtentTraverser found = new ExtentTraverser<>(extent).find(HasFaweQueue.class); ExtentTraverser found = new ExtentTraverser(extent).find(HasFaweQueue.class);
if (found != null) { if (found != null) {
perform(queue = ((HasFaweQueue) found.get()).getQueue()); perform(queue = ((HasFaweQueue) found.get()).getQueue());
} else { } else {

View File

@ -51,7 +51,7 @@ public class MutableFullBlockChange implements Change {
if (!checkedQueue) { if (!checkedQueue) {
checkedQueue = true; checkedQueue = true;
Extent extent = context.getExtent(); Extent extent = context.getExtent();
ExtentTraverser found = new ExtentTraverser<>(extent).find(HasFaweQueue.class); ExtentTraverser found = new ExtentTraverser(extent).find(HasFaweQueue.class);
if (found != null) { if (found != null) {
perform(queue = ((HasFaweQueue) found.get()).getQueue()); perform(queue = ((HasFaweQueue) found.get()).getQueue());
} else { } else {

View File

@ -47,7 +47,7 @@ public class MutableTileChange implements Change {
if (!checkedQueue) { if (!checkedQueue) {
checkedQueue = true; checkedQueue = true;
Extent extent = context.getExtent(); Extent extent = context.getExtent();
ExtentTraverser found = new ExtentTraverser<>(extent).find(HasFaweQueue.class); ExtentTraverser found = new ExtentTraverser(extent).find(HasFaweQueue.class);
if (found != null) { if (found != null) {
perform(queue = ((HasFaweQueue) found.get()).getQueue()); perform(queue = ((HasFaweQueue) found.get()).getQueue());
} else { } else {

View File

@ -143,6 +143,10 @@ public class DiskStorageHistory extends FaweStreamChangeSet {
deleteFiles(); deleteFiles();
} }
public void undo(FawePlayer fp) {
undo(fp, null);
}
public void redo(FawePlayer fp, Region[] regions) { public void redo(FawePlayer fp, Region[] regions) {
EditSession session = toEditSession(fp, regions); EditSession session = toEditSession(fp, regions);
session.redo(session); session.redo(session);

View File

@ -34,7 +34,7 @@ public class MutableAnvilChange implements Change {
if (!checkedQueue) { if (!checkedQueue) {
checkedQueue = true; checkedQueue = true;
Extent extent = context.getExtent(); Extent extent = context.getExtent();
ExtentTraverser found = new ExtentTraverser<>(extent).find(HasFaweQueue.class); ExtentTraverser found = new ExtentTraverser(extent).find(HasFaweQueue.class);
if (found != null) { if (found != null) {
queue = ((HasFaweQueue) found.get()).getQueue(); queue = ((HasFaweQueue) found.get()).getQueue();
destDir = queue.getSaveFolder().toPath(); destDir = queue.getSaveFolder().toPath();
@ -51,12 +51,15 @@ public class MutableAnvilChange implements Change {
Files.move(source, dest, StandardCopyOption.ATOMIC_MOVE); Files.move(source, dest, StandardCopyOption.ATOMIC_MOVE);
} catch (IOException ignore) { } catch (IOException ignore) {
int[] coords = MainUtil.regionNameToCoords(source.toString()); int[] coords = MainUtil.regionNameToCoords(source.toString());
queue.setMCA(coords[0], coords[1], RegionWrapper.GLOBAL(), () -> { queue.setMCA(coords[0], coords[1], RegionWrapper.GLOBAL(), new Runnable() {
@Override
public void run() {
try { try {
Files.move(source, dest, StandardCopyOption.ATOMIC_MOVE); Files.move(source, dest, StandardCopyOption.ATOMIC_MOVE);
} catch (IOException e1) { } catch (IOException e1) {
e1.printStackTrace(); e1.printStackTrace();
} }
}
}, false, true); }, false, true);
} }
} }

View File

@ -5,231 +5,228 @@ import java.util.Arrays;
import static it.unimi.dsi.fastutil.HashCommon.arraySize; import static it.unimi.dsi.fastutil.HashCommon.arraySize;
public class ObjObjMap<K, V> { public class ObjObjMap<K, V>
{
private static final Object FREE_KEY = new Object(); private static final Object FREE_KEY = new Object();
private static final Object REMOVED_KEY = new Object(); private static final Object REMOVED_KEY = new Object();
/** /** Keys and values */
* Keys and values
*/
private Object[] m_data; private Object[] m_data;
/** /** Value for the null key (if inserted into a map) */
* Value for the null key (if inserted into a map)
*/
private Object m_nullValue; private Object m_nullValue;
private boolean m_hasNull; private boolean m_hasNull;
/** /** Fill factor, must be between (0 and 1) */
* Fill factor, must be between (0 and 1)
*/
private final float m_fillFactor; private final float m_fillFactor;
/** /** We will resize a map once it reaches this size */
* We will resize a map once it reaches this size
*/
private int m_threshold; private int m_threshold;
/** /** Current map size */
* Current map size
*/
private int m_size; private int m_size;
/** /** Mask to calculate the original position */
* Mask to calculate the original position
*/
private int m_mask; private int m_mask;
/** /** Mask to wrap the actual array pointer */
* Mask to wrap the actual array pointer
*/
private int m_mask2; private int m_mask2;
public ObjObjMap(final int size, final float fillFactor) { public ObjObjMap( final int size, final float fillFactor )
if (fillFactor <= 0 || fillFactor >= 1) { {
throw new IllegalArgumentException("FillFactor must be in (0, 1)"); if ( fillFactor <= 0 || fillFactor >= 1 )
} throw new IllegalArgumentException( "FillFactor must be in (0, 1)" );
if (size <= 0) { if ( size <= 0 )
throw new IllegalArgumentException("Size must be positive!"); throw new IllegalArgumentException( "Size must be positive!" );
}
final int capacity = arraySize(size, fillFactor); final int capacity = arraySize(size, fillFactor);
m_mask = capacity - 1; m_mask = capacity - 1;
m_mask2 = capacity * 2 - 1; m_mask2 = capacity * 2 - 1;
m_fillFactor = fillFactor; m_fillFactor = fillFactor;
m_data = new Object[capacity * 2]; m_data = new Object[capacity * 2];
Arrays.fill(m_data, FREE_KEY); Arrays.fill( m_data, FREE_KEY );
m_threshold = (int) (capacity * fillFactor); m_threshold = (int) (capacity * fillFactor);
} }
public V get(@Nonnull final K key) { public V get( @Nonnull final K key )
{
// if ( key == null ) // if ( key == null )
// return (V) m_nullValue; //we null it on remove, so safe not to check a flag here // return (V) m_nullValue; //we null it on remove, so safe not to check a flag here
int ptr = (key.hashCode() & m_mask) << 1; int ptr = (key.hashCode() & m_mask) << 1;
Object k = m_data[ptr]; Object k = m_data[ ptr ];
// if ( k == FREE_KEY ) // if ( k == FREE_KEY )
// return null; //end of chain already // return null; //end of chain already
if (k == (key)) //we check FREE and REMOVED prior to this call if ( k == ( key ) ) //we check FREE and REMOVED prior to this call
return (V) m_data[ ptr + 1 ];
while ( true )
{ {
return (V) m_data[ptr + 1];
}
while (true) {
ptr = (ptr + 2) & m_mask2; //that's next index ptr = (ptr + 2) & m_mask2; //that's next index
k = m_data[ptr]; k = m_data[ ptr ];
// if ( k == FREE_KEY ) // if ( k == FREE_KEY )
// return null; // return null;
if (k == (key)) { if ( k == ( key ) )
return (V) m_data[ptr + 1]; return (V) m_data[ ptr + 1 ];
}
} }
} }
public V put(final K key, final V value) { public V put( final K key, final V value )
if (key == null) { {
if ( key == null )
return insertNullKey(value); return insertNullKey(value);
}
int ptr = getStartIndex(key) << 1; int ptr = getStartIndex(key) << 1;
Object k = m_data[ptr]; Object k = m_data[ptr];
if (k == FREE_KEY) //end of chain already if ( k == FREE_KEY ) //end of chain already
{ {
m_data[ptr] = key; m_data[ ptr ] = key;
m_data[ptr + 1] = value; m_data[ ptr + 1 ] = value;
if (m_size >= m_threshold) { if ( m_size >= m_threshold )
rehash(m_data.length * 2); //size is set inside rehash( m_data.length * 2 ); //size is set inside
} else { else
++m_size; ++m_size;
}
return null; return null;
} else if (k == (key)) //we check FREE and REMOVED prior to this call }
else if ( k == ( key ) ) //we check FREE and REMOVED prior to this call
{ {
final Object ret = m_data[ptr + 1]; final Object ret = m_data[ ptr + 1 ];
m_data[ptr + 1] = value; m_data[ ptr + 1 ] = value;
return (V) ret; return (V) ret;
} }
int firstRemoved = -1; int firstRemoved = -1;
if (k == REMOVED_KEY) { if ( k == REMOVED_KEY )
firstRemoved = ptr; //we may find a key later firstRemoved = ptr; //we may find a key later
}
while (true) { while ( true )
ptr = (ptr + 2) & m_mask2; //that's next index calculation {
k = m_data[ptr]; ptr = ( ptr + 2 ) & m_mask2; //that's next index calculation
if (k == FREE_KEY) { k = m_data[ ptr ];
if (firstRemoved != -1) { if ( k == FREE_KEY )
{
if ( firstRemoved != -1 )
ptr = firstRemoved; ptr = firstRemoved;
} m_data[ ptr ] = key;
m_data[ptr] = key; m_data[ ptr + 1 ] = value;
m_data[ptr + 1] = value; if ( m_size >= m_threshold )
if (m_size >= m_threshold) { rehash( m_data.length * 2 ); //size is set inside
rehash(m_data.length * 2); //size is set inside else
} else {
++m_size; ++m_size;
}
return null; return null;
} else if (k == (key)) { }
final Object ret = m_data[ptr + 1]; else if ( k == ( key ) )
m_data[ptr + 1] = value; {
final Object ret = m_data[ ptr + 1 ];
m_data[ ptr + 1 ] = value;
return (V) ret; return (V) ret;
} else if (k == REMOVED_KEY) { }
if (firstRemoved == -1) { else if ( k == REMOVED_KEY )
{
if ( firstRemoved == -1 )
firstRemoved = ptr; firstRemoved = ptr;
} }
} }
} }
}
public V remove(final K key) { public V remove( final K key )
if (key == null) { {
if ( key == null )
return removeNullKey(); return removeNullKey();
}
int ptr = getStartIndex(key) << 1; int ptr = getStartIndex(key) << 1;
Object k = m_data[ptr]; Object k = m_data[ ptr ];
if (k == FREE_KEY) { if ( k == FREE_KEY )
return null; //end of chain already return null; //end of chain already
} else if (k == (key)) //we check FREE and REMOVED prior to this call else if ( k == ( key ) ) //we check FREE and REMOVED prior to this call
{ {
--m_size; --m_size;
if (m_data[(ptr + 2) & m_mask2] == FREE_KEY) { if ( m_data[ ( ptr + 2 ) & m_mask2 ] == FREE_KEY )
m_data[ptr] = FREE_KEY; m_data[ ptr ] = FREE_KEY;
} else { else
m_data[ptr] = REMOVED_KEY; m_data[ ptr ] = REMOVED_KEY;
} final V ret = (V) m_data[ ptr + 1 ];
final V ret = (V) m_data[ptr + 1]; m_data[ ptr + 1 ] = null;
m_data[ptr + 1] = null;
return ret; return ret;
} }
while (true) { while ( true )
ptr = (ptr + 2) & m_mask2; //that's next index calculation {
k = m_data[ptr]; ptr = ( ptr + 2 ) & m_mask2; //that's next index calculation
if (k == FREE_KEY) { k = m_data[ ptr ];
if ( k == FREE_KEY )
return null; return null;
} else if (k == (key)) { else if ( k == ( key ) )
{
--m_size; --m_size;
if (m_data[(ptr + 2) & m_mask2] == FREE_KEY) { if ( m_data[ ( ptr + 2 ) & m_mask2 ] == FREE_KEY )
m_data[ptr] = FREE_KEY; m_data[ ptr ] = FREE_KEY;
} else { else
m_data[ptr] = REMOVED_KEY; m_data[ ptr ] = REMOVED_KEY;
} final V ret = (V) m_data[ ptr + 1 ];
final V ret = (V) m_data[ptr + 1]; m_data[ ptr + 1 ] = null;
m_data[ptr + 1] = null;
return ret; return ret;
} }
} }
} }
private V insertNullKey(final V value) { private V insertNullKey(final V value)
if (m_hasNull) { {
if ( m_hasNull )
{
final Object ret = m_nullValue; final Object ret = m_nullValue;
m_nullValue = value; m_nullValue = value;
return (V) ret; return (V) ret;
} else { }
else
{
m_nullValue = value; m_nullValue = value;
++m_size; ++m_size;
return null; return null;
} }
} }
private V removeNullKey() { private V removeNullKey()
if (m_hasNull) { {
if ( m_hasNull )
{
final Object ret = m_nullValue; final Object ret = m_nullValue;
m_nullValue = null; m_nullValue = null;
m_hasNull = false; m_hasNull = false;
--m_size; --m_size;
return (V) ret; return (V) ret;
} else { }
else
{
return null; return null;
} }
} }
public int size() { public int size()
{
return m_size; return m_size;
} }
private void rehash(final int newCapacity) { private void rehash( final int newCapacity )
m_threshold = (int) (newCapacity / 2 * m_fillFactor); {
m_mask = newCapacity / 2 - 1; m_threshold = (int) (newCapacity/2 * m_fillFactor);
m_mask = newCapacity/2 - 1;
m_mask2 = newCapacity - 1; m_mask2 = newCapacity - 1;
final int oldCapacity = m_data.length; final int oldCapacity = m_data.length;
final Object[] oldData = m_data; final Object[] oldData = m_data;
m_data = new Object[newCapacity]; m_data = new Object[ newCapacity ];
Arrays.fill(m_data, FREE_KEY); Arrays.fill( m_data, FREE_KEY );
m_size = m_hasNull ? 1 : 0; m_size = m_hasNull ? 1 : 0;
for (int i = 0; i < oldCapacity; i += 2) { for ( int i = 0; i < oldCapacity; i += 2 ) {
final Object oldKey = oldData[i]; final Object oldKey = oldData[ i ];
if (oldKey != FREE_KEY && oldKey != REMOVED_KEY) { if( oldKey != FREE_KEY && oldKey != REMOVED_KEY )
put((K) oldKey, (V) oldData[i + 1]); put( (K)oldKey, (V)oldData[ i + 1 ]);
}
} }
} }
public int getStartIndex(final Object key) { public int getStartIndex( final Object key )
{
//key is not null here //key is not null here
return key.hashCode() & m_mask; return key.hashCode() & m_mask;
} }

View File

@ -28,9 +28,10 @@ public class SummedAreaTable {
public void processSummedAreaTable() { public void processSummedAreaTable() {
int rowSize = source.length / width; int rowSize = source.length / width;
int colSize = width;
int index = 0; int index = 0;
for (int i = 0; i < rowSize; i++) { for (int i = 0; i < rowSize; i++) {
for (int j = 0; j < width; j++, index++) { for (int j = 0; j < colSize; j++, index++) {
long val = getVal(i, j, index, source[index]); long val = getVal(i, j, index, source[index]);
summed[index] = val; summed[index] = val;
} }

View File

@ -28,7 +28,7 @@ public class MultiTransform extends RandomTransform {
@Override @Override
public void add(ResettableExtent extent, double chance) { public void add(ResettableExtent extent, double chance) {
super.add(extent, chance); super.add(extent, chance);
this.extents = getExtents().toArray(new ResettableExtent[0]); this.extents = getExtents().toArray(new ResettableExtent[getExtents().size()]);
} }
@Override @Override

View File

@ -4,7 +4,9 @@ import com.boydti.fawe.config.Settings;
import com.boydti.fawe.example.MappedFaweQueue; import com.boydti.fawe.example.MappedFaweQueue;
import com.boydti.fawe.object.FaweQueue; import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.HasFaweQueue; import com.boydti.fawe.object.HasFaweQueue;
import com.boydti.fawe.util.ExtentTraverser;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
import java.util.Iterator; import java.util.Iterator;
@ -20,13 +22,17 @@ public class Fast2DIterator implements Iterable<BlockVector2> {
this(iter, (HasFaweQueue) extent); this(iter, (HasFaweQueue) extent);
} }
public Fast2DIterator(@Nonnull Iterable<? extends BlockVector2> iter, @Nullable Extent extent) {
this(iter, (HasFaweQueue) (extent != null ? (extent instanceof HasFaweQueue ? extent : new ExtentTraverser(extent).findAndGet(HasFaweQueue.class)) : null));
}
public Fast2DIterator(@Nonnull Iterable<? extends BlockVector2> iter, @Nullable HasFaweQueue editSession) { public Fast2DIterator(@Nonnull Iterable<? extends BlockVector2> iter, @Nullable HasFaweQueue editSession) {
this(iter, (FaweQueue) (editSession != null ? editSession.getQueue() : null)); this(iter, (FaweQueue) (editSession != null ? editSession.getQueue() : null));
} }
public Fast2DIterator(@Nonnull Iterable<? extends BlockVector2> iter, @Nullable FaweQueue faweQueue) { public Fast2DIterator(@Nonnull Iterable<? extends BlockVector2> iter, @Nullable FaweQueue faweQueue) {
this.iterable = iter; this.iterable = iter;
this.queue = faweQueue instanceof MappedFaweQueue ? (MappedFaweQueue) faweQueue : null; this.queue = faweQueue != null && faweQueue instanceof MappedFaweQueue ? (MappedFaweQueue) faweQueue : null;
} }
public Iterable<? extends BlockVector2> getIterable() { public Iterable<? extends BlockVector2> getIterable() {

View File

@ -124,7 +124,10 @@ public class PlotTrim {
@Override @Override
public boolean appliesFile(int mcaX, int mcaZ) { public boolean appliesFile(int mcaX, int mcaZ) {
ChunkLoc loc = new ChunkLoc(mcaX, mcaZ); ChunkLoc loc = new ChunkLoc(mcaX, mcaZ);
return !mcas.contains(loc); if (mcas.contains(loc)) {
return false;
}
return true;
} }
@Override @Override

View File

@ -0,0 +1,27 @@
package com.boydti.fawe.util;
import java.util.Arrays;
public class ArrayUtil {
public static final void fill(byte[] a, int fromIndex, int toIndex, byte val) {
for (int i = fromIndex; i < toIndex; i++) a[i] = val;
}
public static final void fill(char[] a, int fromIndex, int toIndex, char val) {
for (int i = fromIndex; i < toIndex; i++) a[i] = val;
}
public static <T> T[] concatAll(T[] first, T[]... rest) {
int totalLength = first.length;
for (T[] array : rest) {
totalLength += array.length;
}
T[] result = Arrays.copyOf(first, totalLength);
int offset = first.length;
for (T[] array : rest) {
System.arraycopy(array, 0, result, offset, array.length);
offset += array.length;
}
return result;
}
}

View File

@ -20,7 +20,6 @@ import java.util.WeakHashMap;
public final class BrushCache { public final class BrushCache {
private static final WeakHashMap<Object, BrushTool> brushCache = new WeakHashMap<>(); private static final WeakHashMap<Object, BrushTool> brushCache = new WeakHashMap<>();
private static final Gson gson = new GsonBuilder().setPrettyPrinting().create(); private static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
private static final ThreadLocal<Boolean> RECURSION = new ThreadLocal<>();
private static final CompoundTag getNBT(BaseItem item) { private static final CompoundTag getNBT(BaseItem item) {
return item.hasNbtData() ? item.getNbtData() : null; return item.hasNbtData() ? item.getNbtData() : null;
@ -30,29 +29,21 @@ public final class BrushCache {
return item.getNativeItem(); return item.getNativeItem();
} }
private static final ThreadLocal<Boolean> RECURSION = new ThreadLocal<>();
public static final BrushTool getTool(Player player, LocalSession session, BaseItem item) { public static final BrushTool getTool(Player player, LocalSession session, BaseItem item) {
if (!item.hasNbtData()) { if (!item.hasNbtData()) return null;
return null;
}
Object key = getKey(item); Object key = getKey(item);
if (key == null) { if (key == null) return null;
return null;
}
BrushTool cached = brushCache.get(key); BrushTool cached = brushCache.get(key);
if (cached != null) { if (cached != null) return cached;
return cached;
}
CompoundTag nbt = item.getNbtData(); CompoundTag nbt = item.getNbtData();
if (nbt == null) { if (nbt == null) return null;
return null;
}
StringTag json = (StringTag) nbt.getValue().get("weBrushJson"); StringTag json = (StringTag) nbt.getValue().get("weBrushJson");
if (json != null) { if (json != null) {
try { try {
if (RECURSION.get() != null) { if (RECURSION.get() != null) return null;
return null;
}
RECURSION.set(true); RECURSION.set(true);
BrushTool tool = BrushTool.fromString(player, session, json.getValue()); BrushTool tool = BrushTool.fromString(player, session, json.getValue());
@ -73,16 +64,12 @@ public final class BrushCache {
public static BrushTool getCachedTool(BaseItem item) { public static BrushTool getCachedTool(BaseItem item) {
Object key = getKey(item); Object key = getKey(item);
if (key != null) { if (key != null) return brushCache.get(key);
return brushCache.get(key);
}
return null; return null;
} }
public static final BrushTool setTool(BaseItem item, BrushTool tool) { public static final BrushTool setTool(BaseItem item, BrushTool tool) {
if (item.getNativeItem() == null) { if (item.getNativeItem() == null) return null;
return null;
}
CompoundTag nbt = item.getNbtData(); CompoundTag nbt = item.getNbtData();
Map<String, Tag> map; Map<String, Tag> map;
@ -109,12 +96,8 @@ public final class BrushCache {
displayMap.put("Lore", FaweCache.asTag(json.split("\\r?\\n"))); displayMap.put("Lore", FaweCache.asTag(json.split("\\r?\\n")));
String primary = (String) tool.getPrimary().getSettings().get(BrushSettings.SettingType.BRUSH); String primary = (String) tool.getPrimary().getSettings().get(BrushSettings.SettingType.BRUSH);
String secondary = (String) tool.getSecondary().getSettings().get(BrushSettings.SettingType.BRUSH); String secondary = (String) tool.getSecondary().getSettings().get(BrushSettings.SettingType.BRUSH);
if (primary == null) { if (primary == null) primary = secondary;
primary = secondary; if (secondary == null) secondary = primary;
}
if (secondary == null) {
secondary = primary;
}
if (primary != null) { if (primary != null) {
String name = primary == secondary ? primary.split(" ")[0] : primary.split(" ")[0] + " / " + secondary.split(" ")[0]; String name = primary == secondary ? primary.split(" ")[0] : primary.split(" ")[0] + " / " + secondary.split(" ")[0];
displayMap.put("Name", new StringTag("{\"text\":\"" + name + "\"}")); displayMap.put("Name", new StringTag("{\"text\":\"" + name + "\"}"));

View File

@ -5,17 +5,29 @@ public class CachedMathMan {
private static final int ATAN2_BITS2 = ATAN2_BITS << 1; private static final int ATAN2_BITS2 = ATAN2_BITS << 1;
private static final int ATAN2_MASK = ~(-1 << ATAN2_BITS2); private static final int ATAN2_MASK = ~(-1 << ATAN2_BITS2);
private static final int ATAN2_COUNT = ATAN2_MASK + 1; private static final int ATAN2_COUNT = ATAN2_MASK + 1;
private static final int ATAN2_DIM = (int) Math.sqrt(ATAN2_COUNT);
private static final float INV_ATAN2_DIM_MINUS_1 = 1.0f / (ATAN2_DIM - 1);
private static final float[] atan2 = new float[ATAN2_COUNT];
static {
for (int i = 0; i < ATAN2_DIM; i++) {
for (int j = 0; j < ATAN2_DIM; j++) {
float x0 = (float) i / ATAN2_DIM;
float y0 = (float) j / ATAN2_DIM;
atan2[(j * ATAN2_DIM) + i] = (float) Math.atan2(y0, x0);
}
}
}
private static float[] ANGLES = new float[65536]; private static float[] ANGLES = new float[65536];
private static char[] SQRT = new char[65536];
static { static {
for (int i = 0; i < 65536; ++i) { for (int i = 0; i < 65536; ++i) {
ANGLES[i] = (float) Math.sin((double) i * 3.141592653589793D * 2.0D / 65536.0D); ANGLES[i] = (float) Math.sin((double) i * 3.141592653589793D * 2.0D / 65536.0D);
} }
} }
private static char[] SQRT = new char[65536];
static { static {
for (int i = 0; i < SQRT.length; i++) { for (int i = 0; i < SQRT.length; i++) {
SQRT[i] = (char) Math.round(Math.sqrt(i)); SQRT[i] = (char) Math.round(Math.sqrt(i));
@ -24,7 +36,6 @@ public class CachedMathMan {
/** /**
* Optimized for i elem 0,65536 (characters) * Optimized for i elem 0,65536 (characters)
*
* @param i * @param i
* @return square root * @return square root
*/ */
@ -40,4 +51,37 @@ public class CachedMathMan {
return ANGLES[(int) (paramFloat * 10430.378F + 16384.0F) & 0xFFFF]; return ANGLES[(int) (paramFloat * 10430.378F + 16384.0F) & 0xFFFF];
} }
protected static final float atan2(float y, float x) {
float add, mul;
if (x < 0.0f) {
if (y < 0.0f) {
x = -x;
y = -y;
mul = 1.0f;
} else {
x = -x;
mul = -1.0f;
}
add = -3.141592653f;
} else {
if (y < 0.0f) {
y = -y;
mul = -1.0f;
} else {
mul = 1.0f;
}
add = 0.0f;
}
float invDiv = 1.0f / ((Math.max(x, y)) * INV_ATAN2_DIM_MINUS_1);
int xi = (int) (x * invDiv);
int yi = (int) (y * invDiv);
return (atan2[(yi * ATAN2_DIM) + xi] + add) * mul;
}
} }

View File

@ -1,8 +1,11 @@
package com.boydti.fawe.util; package com.boydti.fawe.util;
import com.sk89q.worldedit.world.block.BlockType; import com.boydti.fawe.FaweCache;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
public class CachedTextureUtil extends DelegateTextureUtil { public class CachedTextureUtil extends DelegateTextureUtil {
@ -40,7 +43,7 @@ public class CachedTextureUtil extends DelegateTextureUtil {
} }
BiomeColor result = parent.getNearestBiome(color); BiomeColor result = parent.getNearestBiome(color);
if (result != null) { if (result != null) {
colorBiomeMap.put(color, (Integer) result.id); colorBiomeMap.put((int) color, (Integer) result.id);
} }
return result; return result;
} }
@ -53,7 +56,7 @@ public class CachedTextureUtil extends DelegateTextureUtil {
} }
BlockType result = parent.getNearestBlock(color); BlockType result = parent.getNearestBlock(color);
if (result != null) { if (result != null) {
colorBlockMap.put(color, result); colorBlockMap.put((int) color, result);
} }
return result; return result;
} }

View File

@ -14,12 +14,8 @@ public class CleanTextureUtil extends TextureUtil {
int maxIndex = ((parent.distances.length - 1) * maxPercent) / 100; int maxIndex = ((parent.distances.length - 1) * maxPercent) / 100;
long min = parent.distances[minIndex]; long min = parent.distances[minIndex];
long max = parent.distances[maxIndex]; long max = parent.distances[maxIndex];
for (; minIndex > 0 && parent.distances[minIndex - 1] == min; minIndex--) { for (; minIndex > 0 && parent.distances[minIndex - 1] == min; minIndex--) ;
; for (; maxIndex < parent.distances.length - 1 && parent.distances[maxIndex + 1] == max; maxIndex++) ;
}
for (; maxIndex < parent.distances.length - 1 && parent.distances[maxIndex + 1] == max; maxIndex++) {
;
}
int num = maxIndex - minIndex + 1; int num = maxIndex - minIndex + 1;
this.validMixBiomeColors = parent.validMixBiomeColors; this.validMixBiomeColors = parent.validMixBiomeColors;
this.validMixBiomeIds = parent.validMixBiomeIds; this.validMixBiomeIds = parent.validMixBiomeIds;

View File

@ -1,6 +1,6 @@
package com.boydti.fawe.util; package com.boydti.fawe.util;
import java.awt.*; import java.awt.Color;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.Locale; import java.util.Locale;
@ -17,7 +17,7 @@ public class ColorUtil {
throw new IllegalArgumentException("Invalid color specification"); throw new IllegalArgumentException("Invalid color specification");
} }
type = PARSE_PERCENT; type = PARSE_PERCENT;
color = color.substring(0, color.length() - 1).trim(); color = color.substring(0, color.length()-1).trim();
} else if (type == PARSE_PERCENT) { } else if (type == PARSE_PERCENT) {
throw new IllegalArgumentException("Invalid color specification"); throw new IllegalArgumentException("Invalid color specification");
} }
@ -42,32 +42,32 @@ public class ColorUtil {
throw new IllegalArgumentException("Invalid color specification"); throw new IllegalArgumentException("Invalid color specification");
} }
private static Color parseRGBColor(String color, int roff) { private static Color parseRGBColor(String color, int roff)
{
try { try {
int rend = color.indexOf(',', roff); int rend = color.indexOf(',', roff);
int gend = rend < 0 ? -1 : color.indexOf(',', rend + 1); int gend = rend < 0 ? -1 : color.indexOf(',', rend+1);
int bend = gend < 0 ? -1 : color.indexOf(gend + 1); int bend = gend < 0 ? -1 : color.indexOf(gend+1);
float r = parseComponent(color, roff, rend, PARSE_COMPONENT); float r = parseComponent(color, roff, rend, PARSE_COMPONENT);
float g = parseComponent(color, rend + 1, gend, PARSE_COMPONENT); float g = parseComponent(color, rend+1, gend, PARSE_COMPONENT);
float b = parseComponent(color, gend + 1, bend, PARSE_COMPONENT); float b = parseComponent(color, gend+1, bend, PARSE_COMPONENT);
return new Color(r, g, b); return new Color(r, g, b);
} catch (NumberFormatException ignored) { } catch (NumberFormatException nfe) {}
}
throw new IllegalArgumentException("Invalid color specification"); throw new IllegalArgumentException("Invalid color specification");
} }
private static Color parseHSLColor(String color, int hoff) { private static Color parseHSLColor(String color, int hoff)
{
try { try {
int hend = color.indexOf(',', hoff); int hend = color.indexOf(',', hoff);
int send = hend < 0 ? -1 : color.indexOf(',', hend + 1); int send = hend < 0 ? -1 : color.indexOf(',', hend+1);
int lend = send < 0 ? -1 : color.indexOf(send + 1); int lend = send < 0 ? -1 : color.indexOf(send+1);
float h = parseComponent(color, hoff, hend, PARSE_ANGLE); float h = parseComponent(color, hoff, hend, PARSE_ANGLE);
float s = parseComponent(color, hend + 1, send, PARSE_PERCENT); float s = parseComponent(color, hend+1, send, PARSE_PERCENT);
float l = parseComponent(color, send + 1, lend, PARSE_PERCENT); float l = parseComponent(color, send+1, lend, PARSE_PERCENT);
return Color.getHSBColor(h, s, l); return Color.getHSBColor(h, s, l);
} catch (NumberFormatException ignored) { } catch (NumberFormatException nfe) {}
}
throw new IllegalArgumentException("Invalid color specification"); throw new IllegalArgumentException("Invalid color specification");
} }
@ -104,8 +104,7 @@ public class ColorUtil {
try { try {
Field field = java.awt.Color.class.getField(color.toLowerCase()); Field field = java.awt.Color.class.getField(color.toLowerCase());
col = (Color) field.get(null); col = (Color) field.get(null);
} catch (Throwable ignore) { } catch (Throwable ignore) {}
}
if (col != null) { if (col != null) {
return col; return col;
} }
@ -117,6 +116,7 @@ public class ColorUtil {
int r; int r;
int g; int g;
int b; int b;
int a;
if (len == 3) { if (len == 3) {
r = Integer.parseInt(color.substring(0, 1), 16); r = Integer.parseInt(color.substring(0, 1), 16);
@ -139,8 +139,7 @@ public class ColorUtil {
b = Integer.parseInt(color.substring(4, 6), 16); b = Integer.parseInt(color.substring(4, 6), 16);
return new Color(r, g, b); return new Color(r, g, b);
} }
} catch (NumberFormatException ignored) { } catch (NumberFormatException nfe) {}
}
throw new IllegalArgumentException("Invalid color specification"); throw new IllegalArgumentException("Invalid color specification");
} }

View File

@ -1,7 +1,9 @@
package com.boydti.fawe.util; package com.boydti.fawe.util;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
@ -16,10 +18,6 @@ public class DelegateTextureUtil extends TextureUtil {
this.parent = parent; this.parent = parent;
} }
public static int hueDistance(int red1, int green1, int blue1, int red2, int green2, int blue2) {
return TextureUtil.hueDistance(red1, green1, blue1, red2, green2, blue2);
}
@Override @Override
public BlockType getNearestBlock(int color) { public BlockType getNearestBlock(int color) {
return parent.getNearestBlock(color); return parent.getNearestBlock(color);
@ -125,6 +123,10 @@ public class DelegateTextureUtil extends TextureUtil {
return parent.colorDistance(red1, green1, blue1, c2); return parent.colorDistance(red1, green1, blue1, c2);
} }
public static int hueDistance(int red1, int green1, int blue1, int red2, int green2, int blue2) {
return TextureUtil.hueDistance(red1, green1, blue1, red2, green2, blue2);
}
@Override @Override
public long getDistance(BufferedImage image, int c1) { public long getDistance(BufferedImage image, int c1) {
return parent.getDistance(image, c1); return parent.getDistance(image, c1);

View File

@ -24,8 +24,28 @@ import com.boydti.fawe.command.CFICommands;
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;
import com.sk89q.minecraft.util.commands.NestedCommand; import com.sk89q.minecraft.util.commands.NestedCommand;
import com.sk89q.worldedit.command.*; import com.sk89q.worldedit.command.BiomeCommands;
import com.sk89q.worldedit.command.BrushCommands;
import com.sk89q.worldedit.command.BrushOptionsCommands;
import com.sk89q.worldedit.command.ChunkCommands;
import com.sk89q.worldedit.command.ClipboardCommands;
import com.sk89q.worldedit.command.GenerationCommands;
import com.sk89q.worldedit.command.HistoryCommands;
import com.sk89q.worldedit.command.MaskCommands;
import com.sk89q.worldedit.command.NavigationCommands;
import com.sk89q.worldedit.command.OptionsCommands;
import com.sk89q.worldedit.command.PatternCommands;
import com.sk89q.worldedit.command.RegionCommands;
import com.sk89q.worldedit.command.SchematicCommands;
import com.sk89q.worldedit.command.ScriptingCommands;
import com.sk89q.worldedit.command.SelectionCommands;
import com.sk89q.worldedit.command.SnapshotCommands;
import com.sk89q.worldedit.command.SnapshotUtilCommands;
import com.sk89q.worldedit.command.SuperPickaxeCommands;
import com.sk89q.worldedit.command.ToolCommands;
import com.sk89q.worldedit.command.TransformCommands;
import com.sk89q.worldedit.command.UtilityCommands;
import com.sk89q.worldedit.command.WorldEditCommands;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
@ -159,10 +179,10 @@ public final class DocumentationPrinter {
Command cmd = method.getAnnotation(Command.class); Command cmd = method.getAnnotation(Command.class);
String[] aliases = cmd.aliases(); String[] aliases = cmd.aliases();
StringBuilder usage = new StringBuilder(prefix + aliases[0] + " " + cmd.usage()); String usage = prefix + aliases[0] + " " + cmd.usage();
if (!cmd.flags().isEmpty()) { if (!cmd.flags().isEmpty()) {
for (char c : cmd.flags().toCharArray()) { for (char c : cmd.flags().toCharArray()) {
usage.append(" [-").append(c).append("]"); usage += " [-" + c + "]";
} }
} }
// stream.append("#### [`" + usage + "`](" + "https://github.com/boy0001/FastAsyncWorldedit/wiki/" + aliases[0] + ")\n"); // stream.append("#### [`" + usage + "`](" + "https://github.com/boy0001/FastAsyncWorldedit/wiki/" + aliases[0] + ")\n");
@ -185,9 +205,7 @@ public final class DocumentationPrinter {
} }
} }
stream.append("\n"); stream.append("\n");
if (title) { if (title) stream.append("---");
stream.append("---");
}
stream.append("\n"); stream.append("\n");
stream.append("\n"); stream.append("\n");
} }

View File

@ -4,11 +4,7 @@ import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweAPI; import com.boydti.fawe.FaweAPI;
import com.boydti.fawe.config.Settings; import com.boydti.fawe.config.Settings;
import com.boydti.fawe.logging.rollback.RollbackOptimizedHistory; import com.boydti.fawe.logging.rollback.RollbackOptimizedHistory;
import com.boydti.fawe.object.FaweLimit; import com.boydti.fawe.object.*;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.NullChangeSet;
import com.boydti.fawe.object.RegionWrapper;
import com.boydti.fawe.object.changeset.DiskStorageHistory; import com.boydti.fawe.object.changeset.DiskStorageHistory;
import com.boydti.fawe.object.changeset.FaweChangeSet; import com.boydti.fawe.object.changeset.FaweChangeSet;
import com.boydti.fawe.object.changeset.MemoryOptimizedHistory; import com.boydti.fawe.object.changeset.MemoryOptimizedHistory;
@ -18,10 +14,9 @@ import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.eventbus.EventBus; import com.sk89q.worldedit.util.eventbus.EventBus;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
import java.util.UUID;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.UUID;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;

View File

@ -2,7 +2,6 @@ package com.boydti.fawe.util;
import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import java.lang.reflect.Field; import java.lang.reflect.Field;
public class ExtentTraverser<T extends Extent> { public class ExtentTraverser<T extends Extent> {

View File

@ -3,17 +3,13 @@ package com.boydti.fawe.util;
public class FaweTimer implements Runnable { public class FaweTimer implements Runnable {
private final double[] history = new double[]{20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d}; private final double[] history = new double[]{20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d, 20d};
private final long tickInterval = 5;
private final double millisPer20Interval = tickInterval * 50 * 20;
private int historyIndex = 0; private int historyIndex = 0;
private long lastPoll = System.currentTimeMillis(); private long lastPoll = System.currentTimeMillis();
private long tickStart = System.currentTimeMillis(); private long tickStart = System.currentTimeMillis();
private final long tickInterval = 5;
private final double millisPer20Interval = tickInterval * 50 * 20;
private long tick = 0; private long tick = 0;
private long tickMod = 0; private long tickMod = 0;
private long lastGetTPSTick = 0;
private double lastGetTPSValue = 20d;
private long skip = 0;
private long skipTick = 0;
@Override @Override
public void run() { public void run() {
@ -36,6 +32,9 @@ public class FaweTimer implements Runnable {
lastPoll = tickStart; lastPoll = tickStart;
} }
private long lastGetTPSTick = 0;
private double lastGetTPSValue = 20d;
public double getTPS() { public double getTPS() {
if (tick < lastGetTPSTick + tickInterval) { if (tick < lastGetTPSTick + tickInterval) {
return lastGetTPSValue; return lastGetTPSValue;
@ -61,6 +60,9 @@ public class FaweTimer implements Runnable {
return tickStart; return tickStart;
} }
private long skip = 0;
private long skipTick = 0;
public boolean isAbove(double tps) { public boolean isAbove(double tps) {
if (tps <= 0) { if (tps <= 0) {
return true; return true;

View File

@ -1,5 +1,9 @@
package com.boydti.fawe.util; package com.boydti.fawe.util;
import com.boydti.fawe.FaweCache;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
@ -7,9 +11,11 @@ import java.io.FileNotFoundException;
import java.util.Set; import java.util.Set;
public class FilteredTextureUtil extends TextureUtil { public class FilteredTextureUtil extends TextureUtil {
private final Set<BlockType> blocks;
public FilteredTextureUtil(TextureUtil parent, Set<BlockType> blocks) throws FileNotFoundException { public FilteredTextureUtil(TextureUtil parent, Set<BlockType> blocks) throws FileNotFoundException {
super(parent.getFolder()); super(parent.getFolder());
this.blocks = blocks;
this.validMixBiomeColors = parent.validMixBiomeColors; this.validMixBiomeColors = parent.validMixBiomeColors;
this.validMixBiomeIds = parent.validMixBiomeIds; this.validMixBiomeIds = parent.validMixBiomeIds;
this.validBiomes = parent.validBiomes; this.validBiomes = parent.validBiomes;
@ -21,9 +27,7 @@ public class FilteredTextureUtil extends TextureUtil {
int num = 0; int num = 0;
for (int i = 0; i < parent.validBlockIds.length; i++) { for (int i = 0; i < parent.validBlockIds.length; i++) {
BlockType block = BlockTypes.get(parent.validBlockIds[i]); BlockType block = BlockTypes.get(parent.validBlockIds[i]);
if (blocks.contains(block)) { if (blocks.contains(block)) num++;
num++;
}
} }
this.validBlockIds = new int[num]; this.validBlockIds = new int[num];
this.validColors = new int[num]; this.validColors = new int[num];

View File

@ -1,41 +1,48 @@
package com.boydti.fawe.util; package com.boydti.fawe.util;
import java.io.DataOutput; import java.io.*;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI; import java.net.URI;
public final class IOUtil { public final class IOUtil {
public static int readInt(InputStream in) throws IOException { public InputStream toInputStream(URI uri) throws IOException {
String scheme = uri.getScheme();
switch (scheme.toLowerCase()) {
case "file":
return new FileInputStream(uri.getPath());
case "http":
case "https":
return uri.toURL().openStream();
default:
return null;
}
}
public static final int readInt(InputStream in) throws IOException {
int ch1 = in.read(); int ch1 = in.read();
int ch2 = in.read(); int ch2 = in.read();
int ch3 = in.read(); int ch3 = in.read();
int ch4 = in.read(); int ch4 = in.read();
if ((ch1 | ch2 | ch3 | ch4) < 0) { if ((ch1 | ch2 | ch3 | ch4) < 0)
throw new EOFException(); throw new EOFException();
}
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0)); return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
} }
public static void writeInt(OutputStream out, int v) throws IOException { public static final void writeInt(OutputStream out, int v) throws IOException {
out.write((v >>> 24) & 0xFF); out.write((v >>> 24) & 0xFF);
out.write((v >>> 16) & 0xFF); out.write((v >>> 16) & 0xFF);
out.write((v >>> 8) & 0xFF); out.write((v >>> 8) & 0xFF);
out.write((v >>> 0) & 0xFF); out.write((v >>> 0) & 0xFF);
} }
public static void writeVarInt(final OutputStream out, int i) throws IOException { public static final void writeVarInt(final OutputStream out, int i) throws IOException {
while ((i & -128) != 0) { while((i & -128) != 0) {
out.write(i & 127 | 128); out.write(i & 127 | 128);
i >>>= 7; i >>>= 7;
} }
out.write(i); out.write(i);
} }
public static int readVarInt(InputStream in) throws IOException { public static final int readVarInt(InputStream in) throws IOException {
int i = 0; int i = 0;
int offset = 0; int offset = 0;
int b; int b;
@ -47,7 +54,7 @@ public final class IOUtil {
return i; return i;
} }
public static void copy(InputStream in, OutputStream out) throws IOException { public static final void copy(InputStream in, OutputStream out) throws IOException {
byte[] buf = new byte[8192]; byte[] buf = new byte[8192];
while (true) { while (true) {
int r = in.read(buf); int r = in.read(buf);
@ -58,7 +65,7 @@ public final class IOUtil {
} }
} }
public static int copy(InputStream in, OutputStream out, int len) throws IOException { public static final int copy(InputStream in, OutputStream out, int len) throws IOException {
byte[] buf = new byte[8192]; byte[] buf = new byte[8192];
while (len > 0) { while (len > 0) {
int r = in.read(buf, 0, Math.min(buf.length, len)); int r = in.read(buf, 0, Math.min(buf.length, len));
@ -71,7 +78,7 @@ public final class IOUtil {
return len; return len;
} }
public static void copy(InputStream in, DataOutput out) throws IOException { public static final void copy(InputStream in, DataOutput out) throws IOException {
byte[] buf = new byte[8192]; byte[] buf = new byte[8192];
while (true) { while (true) {
int r = in.read(buf); int r = in.read(buf);
@ -81,5 +88,4 @@ public final class IOUtil {
out.write(buf, 0, r); out.write(buf, 0, r);
} }
} }
} }

View File

@ -1,12 +1,9 @@
package com.boydti.fawe.util; package com.boydti.fawe.util;
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import java.io.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.net.URLEncoder; import java.net.URLEncoder;
@ -15,6 +12,21 @@ import java.util.Base64;
public class ImgurUtility { public class ImgurUtility {
public static final String CLIENT_ID = "50e34b65351eb07"; public static final String CLIENT_ID = "50e34b65351eb07";
public static URL uploadImage(File file) throws IOException {
return uploadImage(new FileInputStream(file));
}
public static URL uploadImage(InputStream is) throws IOException {
is = new BufferedInputStream(is);
FastByteArrayOutputStream baos = new FastByteArrayOutputStream(Short.MAX_VALUE);
int d;
while ((d = is.read()) != -1) {
baos.write(d);
}
baos.flush();
return uploadImage(baos.toByteArray());
}
public static URL uploadImage(byte[] image) throws IOException { public static URL uploadImage(byte[] image) throws IOException {
String json = getImgurContent(CLIENT_ID, image); String json = getImgurContent(CLIENT_ID, image);
Gson gson = new Gson(); Gson gson = new Gson();

View File

@ -5,23 +5,12 @@ import com.google.common.base.Charsets;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import java.io.BufferedReader; import java.io.*;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
/** /**
* Single class paster for the Incendo paste service * Single class paster for the Incendo paste service
@ -61,80 +50,6 @@ public final class IncendoPaster {
this.pasteApplication = pasteApplication; this.pasteApplication = pasteApplication;
} }
public static String debugPaste() throws IOException {
final IncendoPaster incendoPaster = new IncendoPaster("fastasyncworldedit");
StringBuilder b = new StringBuilder();
b.append(
"# Welcome to this paste\n# It is meant to provide us at IntellectualSites with better information about your "
+ "problem\n");
b.append("\n# Server Information\n");
b.append("server.platform: ").append(Fawe.imp().getPlatform()).append('\n');
b.append(Fawe.imp().getDebugInfo()).append('\n');
b.append("\n\n# YAY! Now, let's see what we can find in your JVM\n");
Runtime runtime = Runtime.getRuntime();
b.append("memory.free: ").append(runtime.freeMemory()).append('\n');
b.append("memory.max: ").append(runtime.maxMemory()).append('\n');
b.append("java.specification.version: '").append(System.getProperty("java.specification.version")).append("'\n");
b.append("java.vendor: '").append(System.getProperty("java.vendor")).append("'\n");
b.append("java.version: '").append(System.getProperty("java.version")).append("'\n");
b.append("os.arch: '").append(System.getProperty("os.arch")).append("'\n");
b.append("os.name: '").append(System.getProperty("os.name")).append("'\n");
b.append("os.version: '").append(System.getProperty("os.version")).append("'\n\n");
b.append("# Okay :D Great. You are now ready to create your bug report!");
b.append("\n# You can do so at https://github.com/IntellectualSites/FastAsyncWorldEdit-1.13/issues");
b.append("\n# or via our Discord at https://discord.gg/ngZCzbU");
incendoPaster.addFile(new IncendoPaster.PasteFile("information", b.toString()));
try {
final File logFile = new File(Fawe.imp().getDirectory(), "../../logs/latest.log");
final String file;
if (Files.size(logFile.toPath()) > 14_000_000) {
file = "too big :(";
} else {
file = readFile(logFile);
}
incendoPaster.addFile(new IncendoPaster.PasteFile("latest.log", file));
} catch (IOException ignored) {
}
incendoPaster.addFile(new PasteFile("config.yml", readFile(new File(Fawe.imp().getDirectory(), "config.yml"))));
incendoPaster.addFile(new PasteFile("config-legacy.yml", readFile(new File(Fawe.imp().getDirectory(), "config-legacy.yml"))));
incendoPaster.addFile(new PasteFile("message.yml", readFile(new File(Fawe.imp().getDirectory(), "message.yml"))));
incendoPaster.addFile(new PasteFile("commands.yml", readFile(new File(Fawe.imp().getDirectory(), "commands.yml"))));
final String rawResponse;
try {
rawResponse = incendoPaster.upload();
} catch (Throwable throwable) {
throw new IOException(String.format("Failed to upload files: %s", throwable.getMessage()), throwable);
}
final JsonObject jsonObject = new JsonParser().parse(rawResponse).getAsJsonObject();
if (jsonObject.has("created")) {
final String pasteId = jsonObject.get("paste_id").getAsString();
return String.format("https://athion.net/ISPaster/paste/view/%s", pasteId);
} else {
throw new IOException(String.format("Failed to upload files: %s",
jsonObject.get("response").getAsString()));
}
}
private static String readFile(final File file) throws IOException {
final StringBuilder content = new StringBuilder();
final List<String> lines = new ArrayList<>();
try (final BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
while ((line = reader.readLine()) != null) {
lines.add(line);
}
}
for (int i = Math.max(0, lines.size() - 1000); i < lines.size(); i++) {
content.append(lines.get(i)).append("\n");
}
return content.toString();
}
/** /**
* Get an immutable collection containing all the files that have been added to this paster * Get an immutable collection containing all the files that have been added to this paster
* *
@ -271,4 +186,78 @@ public final class IncendoPaster {
} }
} }
public static String debugPaste() throws IOException {
final IncendoPaster incendoPaster = new IncendoPaster("fastasyncworldedit");
StringBuilder b = new StringBuilder();
b.append(
"# Welcome to this paste\n# It is meant to provide us at IntellectualSites with better information about your "
+ "problem\n");
b.append("\n# Server Information\n");
b.append("server.platform: ").append(Fawe.imp().getPlatform()).append('\n');
b.append(Fawe.imp().getDebugInfo()).append('\n');
b.append("\n\n# YAY! Now, let's see what we can find in your JVM\n");
Runtime runtime = Runtime.getRuntime();
b.append("memory.free: ").append(runtime.freeMemory()).append('\n');
b.append("memory.max: ").append(runtime.maxMemory()).append('\n');
b.append("java.specification.version: '").append(System.getProperty("java.specification.version")).append("'\n");
b.append("java.vendor: '").append(System.getProperty("java.vendor")).append("'\n");
b.append("java.version: '").append(System.getProperty("java.version")).append("'\n");
b.append("os.arch: '").append(System.getProperty("os.arch")).append("'\n");
b.append("os.name: '").append(System.getProperty("os.name")).append("'\n");
b.append("os.version: '").append(System.getProperty("os.version")).append("'\n\n");
b.append("# Okay :D Great. You are now ready to create your bug report!");
b.append("\n# You can do so at https://github.com/IntellectualSites/FastAsyncWorldEdit-1.13/issues");
b.append("\n# or via our Discord at https://discord.gg/ngZCzbU");
incendoPaster.addFile(new IncendoPaster.PasteFile("information", b.toString()));
try {
final File logFile = new File(Fawe.imp().getDirectory(), "../../logs/latest.log");
final String file;
if (Files.size(logFile.toPath()) > 14_000_000) {
file = "too big :(";
} else {
file = readFile(logFile);
}
incendoPaster.addFile(new IncendoPaster.PasteFile("latest.log", file));
} catch (IOException ignored) {
}
incendoPaster.addFile(new PasteFile("config.yml", readFile(new File(Fawe.imp().getDirectory(), "config.yml"))));
incendoPaster.addFile(new PasteFile("config-legacy.yml", readFile(new File(Fawe.imp().getDirectory(), "config-legacy.yml"))));
incendoPaster.addFile(new PasteFile("message.yml", readFile(new File(Fawe.imp().getDirectory(), "message.yml"))));
incendoPaster.addFile(new PasteFile("commands.yml", readFile(new File(Fawe.imp().getDirectory(), "commands.yml"))));
final String rawResponse;
try {
rawResponse = incendoPaster.upload();
} catch (Throwable throwable) {
throw new IOException(String.format("Failed to upload files: %s", throwable.getMessage()), throwable);
}
final JsonObject jsonObject = new JsonParser().parse(rawResponse).getAsJsonObject();
if (jsonObject.has("created")) {
final String pasteId = jsonObject.get("paste_id").getAsString();
return String.format("https://athion.net/ISPaster/paste/view/%s", pasteId);
} else {
throw new IOException(String.format("Failed to upload files: %s",
jsonObject.get("response").getAsString()));
}
}
private static String readFile(final File file) throws IOException {
final StringBuilder content = new StringBuilder();
final List<String> lines = new ArrayList<>();
try (final BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
while ((line = reader.readLine()) != null) {
lines.add(line);
}
}
for (int i = Math.max(0, lines.size() - 1000); i < lines.size(); i++) {
content.append(lines.get(i)).append("\n");
}
return content.toString();
}
} }

View File

@ -1,7 +1,6 @@
package com.boydti.fawe.util; package com.boydti.fawe.util;
import com.boydti.fawe.Fawe; import com.boydti.fawe.Fawe;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
@ -24,9 +23,12 @@ public enum Jars {
public final String digest; public final String digest;
/** /**
* @param url Where this jar can be found and downloaded * @param url
* @param digest The SHA-256 hexadecimal digest * Where this jar can be found and downloaded
* @param filesize Size of this jar in bytes * @param digest
* The SHA-256 hexadecimal digest
* @param filesize
* Size of this jar in bytes
*/ */
Jars(String url, String digest, int filesize) { Jars(String url, String digest, int filesize) {
this.url = url; this.url = url;
@ -34,9 +36,7 @@ public enum Jars {
this.filesize = filesize; this.filesize = filesize;
} }
/** /** download a jar, verify hash, return byte[] containing the jar */
* download a jar, verify hash, return byte[] containing the jar
*/
public byte[] download() throws IOException { public byte[] download() throws IOException {
byte[] jarBytes = new byte[this.filesize]; byte[] jarBytes = new byte[this.filesize];
URL url = new URL(this.url); URL url = new URL(this.url);

View File

@ -3,35 +3,19 @@ package com.boydti.fawe.util;
import com.boydti.fawe.Fawe; import com.boydti.fawe.Fawe;
import com.boydti.fawe.config.BBC; import com.boydti.fawe.config.BBC;
import com.boydti.fawe.config.Settings; import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.FaweInputStream; import com.boydti.fawe.object.*;
import com.boydti.fawe.object.FaweOutputStream;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.RegionWrapper;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.object.RunnableVal2;
import com.boydti.fawe.object.changeset.CPUOptimizedChangeSet; import com.boydti.fawe.object.changeset.CPUOptimizedChangeSet;
import com.boydti.fawe.object.changeset.FaweStreamChangeSet; import com.boydti.fawe.object.changeset.FaweStreamChangeSet;
import com.boydti.fawe.object.io.AbstractDelegateOutputStream; import com.boydti.fawe.object.io.AbstractDelegateOutputStream;
import com.github.luben.zstd.ZstdInputStream; import com.github.luben.zstd.ZstdInputStream;
import com.github.luben.zstd.ZstdOutputStream; import com.github.luben.zstd.ZstdOutputStream;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.*;
import com.sk89q.jnbt.DoubleTag;
import com.sk89q.jnbt.IntTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat; import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats; import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
import com.sk89q.worldedit.history.changeset.ChangeSet; import com.sk89q.worldedit.history.changeset.ChangeSet;
import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.Location;
import net.jpountz.lz4.LZ4BlockInputStream; import net.jpountz.lz4.*;
import net.jpountz.lz4.LZ4BlockOutputStream;
import net.jpountz.lz4.LZ4Compressor;
import net.jpountz.lz4.LZ4Factory;
import net.jpountz.lz4.LZ4FastDecompressor;
import net.jpountz.lz4.LZ4InputStream;
import net.jpountz.lz4.LZ4Utils;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
@ -39,49 +23,28 @@ import java.awt.*;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.*; import java.io.*;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.net.HttpURLConnection; import java.lang.reflect.Method;
import java.net.MalformedURLException; import java.net.*;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.Channels; import java.nio.channels.Channels;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.FileVisitResult; import java.nio.file.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.*;
import java.util.Scanner; import java.util.Map.Entry;
import java.util.UUID;
import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.zip.DataFormatException; import java.util.zip.*;
import java.util.zip.Deflater;
import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import static java.lang.System.arraycopy; import static java.lang.System.arraycopy;
public class MainUtil { public class MainUtil {
private static final LZ4Factory FACTORY = LZ4Factory.fastestInstance();
private static final LZ4Compressor COMPRESSOR = FACTORY.fastCompressor();
private static final LZ4FastDecompressor DECOMPRESSOR = FACTORY.fastDecompressor();
/* /*
* Generic non plugin related utils * Generic non plugin related utils
* e.g. sending messages * e.g. sending messages
@ -142,6 +105,10 @@ public class MainUtil {
return Double.parseDouble(version.substring(0, pos)); return Double.parseDouble(version.substring(0, pos));
} }
public static void stacktrace() {
new Exception().printStackTrace();
}
public static void traverse(Path path, final BiConsumer<Path, BasicFileAttributes> onEach) { public static void traverse(Path path, final BiConsumer<Path, BasicFileAttributes> onEach) {
try { try {
Files.walkFileTree(path, new SimpleFileVisitor<Path>() { Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
@ -170,9 +137,7 @@ public class MainUtil {
} }
public static File resolveRelative(File file) { public static File resolveRelative(File file) {
if (!file.exists()) { if (!file.exists()) return new File(relativize(file.getPath()));
return new File(relativize(file.getPath()));
}
return file; return file;
} }
@ -182,15 +147,11 @@ public class MainUtil {
int skip = 0; int skip = 0;
int len = split.length - 1; int len = split.length - 1;
for (int i = len; i >= 0; i--) { for (int i = len; i >= 0; i--) {
if (skip > 0) { if (skip > 0) skip--;
skip--; else {
} else {
String arg = split[i]; String arg = split[i];
if (arg.equals("..")) { if (arg.equals("..")) skip++;
skip++; else out.insert(0, arg + (i == len ? "" : File.separator));
} else {
out.insert(0, arg + (i == len ? "" : File.separator));
}
} }
} }
return out.toString(); return out.toString();
@ -198,13 +159,9 @@ public class MainUtil {
public static void forEachFile(Path path, final RunnableVal2<Path, BasicFileAttributes> onEach, Comparator<File> comparator) { public static void forEachFile(Path path, final RunnableVal2<Path, BasicFileAttributes> onEach, Comparator<File> comparator) {
File dir = path.toFile(); File dir = path.toFile();
if (!dir.exists()) { if (!dir.exists()) return;
return;
}
File[] files = path.toFile().listFiles(); File[] files = path.toFile().listFiles();
if (comparator != null) { if (comparator != null) Arrays.sort(files, comparator);
Arrays.sort(files, comparator);
}
for (File file : files) { for (File file : files) {
Path filePath = file.toPath(); Path filePath = file.toPath();
try { try {
@ -225,13 +182,9 @@ public class MainUtil {
val = StringMan.toInteger(name, 0, name.length()); val = StringMan.toInteger(name, 0, name.length());
} else { } else {
int i = name.lastIndexOf('.'); int i = name.lastIndexOf('.');
if (i != -1) { if (i != -1) val = StringMan.toInteger(name, 0, i);
val = StringMan.toInteger(name, 0, i);
}
}
if (val != null && val > max[0]) {
max[0] = val;
} }
if (val != null && val > max[0]) max[0] = val;
return false; return false;
}); });
return max[0] + 1; return max[0] + 1;
@ -269,6 +222,10 @@ public class MainUtil {
return getCompressedOS(os, amount, Settings.IMP.HISTORY.BUFFER_SIZE); return getCompressedOS(os, amount, Settings.IMP.HISTORY.BUFFER_SIZE);
} }
private static final LZ4Factory FACTORY = LZ4Factory.fastestInstance();
private static final LZ4Compressor COMPRESSOR = FACTORY.fastCompressor();
private static final LZ4FastDecompressor DECOMPRESSOR = FACTORY.fastDecompressor();
public static int getMaxCompressedLength(int size) { public static int getMaxCompressedLength(int size) {
return LZ4Utils.maxCompressedLength(size); return LZ4Utils.maxCompressedLength(size);
} }
@ -287,9 +244,7 @@ public class MainUtil {
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
while (!deflate.finished()) { while (!deflate.finished()) {
int n = deflate.deflate(buffer); int n = deflate.deflate(buffer);
if (n != 0) { if (n != 0) baos.write(buffer, 0, n);
baos.write(buffer, 0, n);
}
} }
return baos.toByteArray(); return baos.toByteArray();
} }
@ -307,9 +262,7 @@ public class MainUtil {
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
while (!inflater.finished()) { while (!inflater.finished()) {
int n = inflater.inflate(buffer); int n = inflater.inflate(buffer);
if (n != 0) { if (n != 0) baos.write(buffer, 0, n);
baos.write(buffer, 0, n);
}
} }
return baos.toByteArray(); return baos.toByteArray();
} }
@ -491,6 +444,36 @@ public class MainUtil {
} }
} }
private static final Class[] parameters = new Class[]{URL.class};
public static ClassLoader loadURLClasspath(URL u) throws IOException {
ClassLoader sysloader = ClassLoader.getSystemClassLoader();
Class sysclass = URLClassLoader.class;
try {
Method method = sysclass.getDeclaredMethod("addURL", parameters);
method.setAccessible(true);
if (sysloader instanceof URLClassLoader) {
method.invoke(sysloader, new Object[]{u});
} else {
ClassLoader loader = MainUtil.class.getClassLoader();
while (!(loader instanceof URLClassLoader) && loader.getParent() != null) {
loader = loader.getParent();
}
if (loader instanceof URLClassLoader) {
method.invoke(sysloader, new Object[]{u});
} else {
loader = new URLClassLoader(new URL[]{u}, MainUtil.class.getClassLoader());
return loader;
}
}
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return sysloader;
}
public static String getText(String url) throws IOException { public static String getText(String url) throws IOException {
try (Scanner scanner = new Scanner(new URL(url).openStream(), "UTF-8")) { try (Scanner scanner = new Scanner(new URL(url).openStream(), "UTF-8")) {
return scanner.useDelimiter("\\A").next(); return scanner.useDelimiter("\\A").next();
@ -568,12 +551,12 @@ public class MainUtil {
} }
public static Thread[] getThreads() { public static Thread[] getThreads() {
ThreadGroup rootGroup = Thread.currentThread().getThreadGroup(); ThreadGroup rootGroup = Thread.currentThread( ).getThreadGroup( );
ThreadGroup parentGroup; ThreadGroup parentGroup;
while ((parentGroup = rootGroup.getParent()) != null) { while ( ( parentGroup = rootGroup.getParent() ) != null ) {
rootGroup = parentGroup; rootGroup = parentGroup;
} }
Thread[] threads = new Thread[rootGroup.activeCount()]; Thread[] threads = new Thread[ rootGroup.activeCount() ];
if (threads.length != 0) { if (threads.length != 0) {
while (rootGroup.enumerate(threads, true) == threads.length) { while (rootGroup.enumerate(threads, true) == threads.length) {
threads = new Thread[threads.length * 2]; threads = new Thread[threads.length * 2];
@ -615,9 +598,7 @@ public class MainUtil {
} }
public static BufferedImage toRGB(BufferedImage src) { public static BufferedImage toRGB(BufferedImage src) {
if (src == null) { if (src == null) return src;
return src;
}
BufferedImage img = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_INT_ARGB); BufferedImage img = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics(); Graphics2D g2d = img.createGraphics();
g2d.drawImage(src, 0, 0, null); g2d.drawImage(src, 0, 0, null);
@ -695,6 +676,60 @@ public class MainUtil {
// if (!debug) { // if (!debug) {
e.printStackTrace(); e.printStackTrace();
return; return;
// }
// String header = "====== FAWE: " + e.getLocalizedMessage() + " ======";
// Fawe.debug(header);
// String[] trace = getTrace(e);
// for (int i = 0; i < trace.length && i < 8; i++) {
// Fawe.debug(" - " + trace[i]);
// }
// String[] cause = getTrace(e.getCause());
// Fawe.debug("Cause: " + (cause.length == 0 ? "N/A" : ""));
// for (int i = 0; i < cause.length && i < 8; i++) {
// Fawe.debug(" - " + cause[i]);
// }
// Fawe.debug(StringMan.repeat("=", header.length()));
}
public static String[] getTrace(Throwable e) {
if (e == null) {
return new String[0];
}
StackTraceElement[] elems = e.getStackTrace();
String[] msg = new String[elems.length];//[elems.length + 1];
// HashSet<String> packages = new HashSet<>();
for (int i = 0; i < elems.length; i++) {
StackTraceElement elem = elems[i];
elem.getLineNumber();
String methodName = elem.getMethodName();
int index = elem.getClassName().lastIndexOf('.');
String className = elem.getClassName();
// if (!(index == -1 || className.startsWith("io.netty") || className.startsWith("javax") || className.startsWith("java") || className.startsWith("sun") || className.startsWith("net.minecraft") || className.startsWith("org.spongepowered") || className.startsWith("org.bukkit") || className.startsWith("com.google"))) {
// packages.add(className.substring(0, index-1));
// }
String name = className.substring(index == -1 ? 0 : index + 1);
name = name.length() == 0 ? elem.getClassName() : name;
String argString = "(...)";
try {
for (Method method : Class.forName(elem.getClassName()).getDeclaredMethods()) {
if (method.getName().equals(methodName)) {
Class<?>[] params = method.getParameterTypes();
argString = "";
String prefix = "";
for (Class param : params) {
argString += prefix + param.getSimpleName();
prefix = ",";
}
argString = "[" + method.getReturnType().getSimpleName() + "](" + argString + ")";
break;
}
}
} catch (Throwable ignore) {
}
msg[i] = name + "." + methodName + argString + ":" + elem.getLineNumber();
}
// msg[msg.length-1] = StringMan.getString(packages);
return msg;
} }
public static void warnDeprecated(Class... alternatives) { public static void warnDeprecated(Class... alternatives) {
@ -711,12 +746,16 @@ public class MainUtil {
String className = creatorElement.getClassName(); String className = creatorElement.getClassName();
Class clazz = Class.forName(className); Class clazz = Class.forName(className);
String creator = clazz.getSimpleName(); String creator = clazz.getSimpleName();
String packageName = clazz.getPackage().getName();
String myName = Class.forName(stack.getClassName()).getSimpleName(); StackTraceElement deprecatedElement = stack;
Fawe.debug("@" + creator + " used by " + myName + "." + stack.getMethodName() + "():" + stack.getLineNumber() + " is deprecated."); String myName = Class.forName(deprecatedElement.getClassName()).getSimpleName();
Fawe.debug("@" + creator + " used by " + myName + "." + deprecatedElement.getMethodName() + "():" + deprecatedElement.getLineNumber() + " is deprecated.");
Fawe.debug(" - Alternatives: " + StringMan.getString(alternatives)); Fawe.debug(" - Alternatives: " + StringMan.getString(alternatives));
} catch (Throwable throwable) { } catch (Throwable throwable) {
throwable.printStackTrace(); throwable.printStackTrace();
} finally {
break;
} }
} }
} }
@ -743,9 +782,7 @@ public class MainUtil {
break; break;
case '.': case '.':
res[index--] = val; res[index--] = val;
if (index == -1) { if (index == -1) return res;
return res;
}
val = 0; val = 0;
numIndex = 1; numIndex = 1;
break; break;
@ -768,26 +805,18 @@ public class MainUtil {
} }
if (allowDir) { if (allowDir) {
File file = MainUtil.resolveRelative(new File(dir, filename)); File file = MainUtil.resolveRelative(new File(dir, filename));
if (file.exists() && file.isDirectory()) { if (file.exists() && file.isDirectory()) return file;
return file;
}
} }
for (ClipboardFormat f : ClipboardFormats.getAll()) { for (ClipboardFormat f : ClipboardFormats.getAll()) {
File file = MainUtil.resolveRelative(new File(dir, filename + "." + f.getPrimaryFileExtension())); File file = MainUtil.resolveRelative(new File(dir, filename + "." + f.getPrimaryFileExtension()));
if (file.exists()) { if (file.exists()) return file;
return file;
}
} }
return null; return null;
} }
public static boolean isInSubDirectory(File dir, File file) throws IOException { public static boolean isInSubDirectory(File dir, File file) throws IOException {
if (file == null) { if (file == null) return false;
return false; if (file.equals(dir)) return true;
}
if (file.equals(dir)) {
return true;
}
file = file.getCanonicalFile(); file = file.getCanonicalFile();
dir = dir.getCanonicalFile(); dir = dir.getCanonicalFile();
return isInSubDirectory(dir, file.getParentFile()); return isInSubDirectory(dir, file.getParentFile());
@ -951,6 +980,10 @@ public class MainUtil {
return time; return time;
} }
public static void deleteOlder(File directory, final long timeDiff) {
deleteOlder(directory, timeDiff, true);
}
public static void deleteOlder(File directory, final long timeDiff, boolean printDebug) { public static void deleteOlder(File directory, final long timeDiff, boolean printDebug) {
final long now = System.currentTimeMillis(); final long now = System.currentTimeMillis();
ForkJoinPool pool = new ForkJoinPool(); ForkJoinPool pool = new ForkJoinPool();
@ -958,9 +991,7 @@ public class MainUtil {
long age = now - file.lastModified(); long age = now - file.lastModified();
if (age > timeDiff) { if (age > timeDiff) {
pool.submit(file::delete); pool.submit(file::delete);
if (printDebug) { if (printDebug) BBC.FILE_DELETED.send(null, file);
BBC.FILE_DELETED.send(null, file);
}
} }
}); });
pool.shutdown(); pool.shutdown();
@ -971,6 +1002,49 @@ public class MainUtil {
} }
} }
public static boolean deleteDirectory(File directory) {
return deleteDirectory(directory, true);
}
public static boolean deleteDirectory(File directory, boolean printDebug) {
if (directory.exists()) {
File[] files = directory.listFiles();
if (null != files) {
for (File file : files) {
if (file.isDirectory()) {
deleteDirectory(file, printDebug);
} else {
file.delete();
if (printDebug) BBC.FILE_DELETED.send(null, file);
}
}
}
}
return (directory.delete());
}
public static boolean isValidTag(Tag tag) {
if (tag instanceof EndTag) {
return false;
} else if (tag instanceof ListTag) {
ListTag lt = (ListTag) tag;
if ((lt).getType() == EndTag.class) {
return false;
}
} else if (tag instanceof CompoundTag) {
for (Entry<String, Tag> entry : ((CompoundTag) tag).getValue().entrySet()) {
if (!isValidTag(entry.getValue())) {
return false;
}
}
}
return true;
}
public enum OS {
LINUX, WINDOWS, MACOS, UNKNOWN;
}
public static File getWorkingDirectory(String applicationName) { public static File getWorkingDirectory(String applicationName) {
String userHome = System.getProperty("user.home", "."); String userHome = System.getProperty("user.home", ".");
File workingDirectory; File workingDirectory;
@ -1014,8 +1088,4 @@ public class MainUtil {
} }
return OS.UNKNOWN; return OS.UNKNOWN;
} }
public enum OS {
LINUX, WINDOWS, MACOS, UNKNOWN;
}
} }

View File

@ -3,7 +3,6 @@ package com.boydti.fawe.util;
import com.boydti.fawe.object.mask.ResettableMask; import com.boydti.fawe.object.mask.ResettableMask;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Mask;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.Collection; import java.util.Collection;

View File

@ -4,7 +4,6 @@ public class MathMan {
/** /**
* Optimized for i elem 0,65536 (characters) * Optimized for i elem 0,65536 (characters)
*
* @param i * @param i
* @return square root * @return square root
*/ */
@ -23,7 +22,7 @@ public class MathMan {
return CachedMathMan.cosInexact(paramFloat); return CachedMathMan.cosInexact(paramFloat);
} }
public static int log2nlz(int bits) { public static int log2nlz( int bits ) {
return Integer.SIZE - Integer.numberOfLeadingZeros(bits); return Integer.SIZE - Integer.numberOfLeadingZeros(bits);
} }
@ -52,6 +51,16 @@ public class MathMan {
return max; return max;
} }
public static int min(int... values) {
int min = Integer.MAX_VALUE;
for (int d : values) {
if (d < min) {
min = d;
}
}
return min;
}
public static double min(double... values) { public static double min(double... values) {
double min = Double.MAX_VALUE; double min = Double.MAX_VALUE;
for (double d : values) { for (double d : values) {
@ -62,6 +71,11 @@ public class MathMan {
return min; return min;
} }
public static int ceilZero(float floatNumber) {
int floor = (int) floatNumber;
return floatNumber > (float) floor ? floor + 1 : floor;
}
public static int sqr(int val) { public static int sqr(int val) {
return val * val; return val * val;
} }
@ -107,59 +121,72 @@ public class MathMan {
} }
} }
public static int pair(short x, short y) { public static final long inverseRound(double val) {
long round = Math.round(val);
return (long) (round + Math.signum(val - round));
}
public static final int pair(short x, short y) {
return (x << 16) | (y & 0xFFFF); return (x << 16) | (y & 0xFFFF);
} }
public static short unpairX(int hash) { public static final short unpairX(int hash) {
return (short) (hash >> 16); return (short) (hash >> 16);
} }
public static short unpairY(int hash) { public static final short unpairY(int hash) {
return (short) (hash & 0xFFFF); return (short) (hash & 0xFFFF);
} }
public static short pairByte(int x, int y) { public static final short pairByte(int x, int y) {
return (short) ((x << 8) | (y & 0xFF)); return (short) ((x << 8) | (y & 0xFF));
} }
public static byte unpairShortX(short pair) { public static final byte unpairShortX(short pair) {
return (byte) (pair >> 8); return (byte) (pair >> 8);
} }
public static byte unpairShortY(short pair) { public static final byte unpairShortY(short pair) {
return (byte) pair; return (byte) pair;
} }
public static long pairInt(int x, int y) { public static final long pairInt(int x, int y) {
return (((long) x) << 32) | (y & 0xffffffffL); return (((long) x) << 32) | (y & 0xffffffffL);
} }
public static long untripleWorldCoordX(long triple) { public static final long tripleWorldCoord(int x, int y, int z) {
return y + (((long) x & 0x3FFFFFF) << 8) + (((long) z & 0x3FFFFFF) << 34);
}
public static final long untripleWorldCoordX(long triple) {
return (((triple >> 8) & 0x3FFFFFF) << 38) >> 38; return (((triple >> 8) & 0x3FFFFFF) << 38) >> 38;
} }
public static long untripleWorldCoordY(long triple) { public static final long untripleWorldCoordY(long triple) {
return triple & 0xFF; return triple & 0xFF;
} }
public static short tripleBlockCoord(int x, int y, int z) { public static final long untripleWorldCoordZ(long triple) {
return (((triple >> 34) & 0x3FFFFFF) << 38) >> 38;
}
public static final short tripleBlockCoord(int x, int y, int z) {
return (short) ((x & 15) << 12 | (z & 15) << 8 | y); return (short) ((x & 15) << 12 | (z & 15) << 8 | y);
} }
public static char tripleBlockCoordChar(int x, int y, int z) { public static final char tripleBlockCoordChar(int x, int y, int z) {
return (char) ((x & 15) << 12 | (z & 15) << 8 | y); return (char) ((x & 15) << 12 | (z & 15) << 8 | y);
} }
public static int untripleBlockCoordX(int triple) { public static final int untripleBlockCoordX(int triple) {
return (triple >> 12) & 0xF; return (triple >> 12) & 0xF;
} }
public static int untripleBlockCoordY(int triple) { public static final int untripleBlockCoordY(int triple) {
return (triple & 0xFF); return (triple & 0xFF);
} }
public static int untripleBlockCoordZ(int triple) { public static final int untripleBlockCoordZ(int triple) {
return (triple >> 8) & 0xF; return (triple >> 8) & 0xF;
} }
@ -204,27 +231,31 @@ public class MathMan {
return y3 + (y2 << 4) + (y1 << 12); return y3 + (y2 << 4) + (y1 << 12);
} }
public static int unpairIntX(long pair) { public static final long chunkXZ2Int(int x, int z) {
return (long) x & 4294967295L | ((long) z & 4294967295L) << 32;
}
public static final int unpairIntX(long pair) {
return (int) (pair >> 32); return (int) (pair >> 32);
} }
public static int unpairIntY(long pair) { public static final int unpairIntY(long pair) {
return (int) pair; return (int) pair;
} }
public static byte pair16(int x, int y) { public static final byte pair16(int x, int y) {
return (byte) (x + (y << 4)); return (byte) (x + (y << 4));
} }
public static byte unpair16x(byte value) { public static final byte unpair16x(byte value) {
return (byte) (value & 0xF); return (byte) (value & 0xF);
} }
public static byte unpair16y(byte value) { public static final byte unpair16y(byte value) {
return (byte) ((value >> 4) & 0xF); return (byte) ((value >> 4) & 0xF);
} }
public static byte pair8(int x, int y) { public static final byte pair8(int x, int y) {
return (byte) (x + (y << 3)); return (byte) (x + (y << 3));
} }
@ -236,14 +267,18 @@ public class MathMan {
return (byte) ((value >> 3) & 0x7F); return (byte) ((value >> 3) & 0x7F);
} }
public static int gcd(int a, int b) { public static final int lossyFastDivide(int a, int b) {
return (a * ((1 << 16) / b)) >> 16;
}
public static final int gcd(int a, int b) {
if (b == 0) { if (b == 0) {
return a; return a;
} }
return gcd(b, a % b); return gcd(b, a % b);
} }
public static int gcd(int[] a) { public static final int gcd(int[] a) {
int result = a[0]; int result = a[0];
for (int i = 1; i < a.length; i++) { for (int i = 1; i < a.length; i++) {
result = gcd(result, a[i]); result = gcd(result, a[i]);
@ -252,7 +287,15 @@ public class MathMan {
} }
public static double getMean(double[] array) { public static final double getMean(int[] array) {
double count = 0;
for (int i : array) {
count += i;
}
return count / array.length;
}
public static final double getMean(double[] array) {
double count = 0; double count = 0;
for (double i : array) { for (double i : array) {
count += i; count += i;
@ -267,24 +310,50 @@ public class MathMan {
* @param pitch * @param pitch
* @return * @return
*/ */
public static float[] getDirection(float yaw, float pitch) { public static final float[] getDirection(float yaw, float pitch) {
double pitch_sin = Math.sin(pitch); double pitch_sin = Math.sin(pitch);
return new float[]{(float) (pitch_sin * Math.cos(yaw)), (float) (pitch_sin * Math.sin(yaw)), (float) Math.cos(pitch)}; return new float[]{(float) (pitch_sin * Math.cos(yaw)), (float) (pitch_sin * Math.sin(yaw)), (float) Math.cos(pitch)};
} }
public static int roundInt(double value) { public static final int roundInt(double value) {
return (int) (value < 0 ? (value == (int) value) ? value : value - 1 : value); return (int) (value < 0 ? (value == (int) value) ? value : value - 1 : value);
} }
public static float sqrtApprox(float f) { /**
* Returns [ pitch, yaw ]
*
* @param x
* @param y
* @param z
* @return
*/
public static final float[] getPitchAndYaw(float x, float y, float z) {
float distance = sqrtApprox((z * z) + (x * x));
return new float[]{atan2(y, distance), atan2(x, z)};
}
public static final float atan2(float y, float x) {
return CachedMathMan.atan2(y, x);
}
public static final float sqrtApprox(float f) {
return f * Float.intBitsToFloat(0x5f375a86 - (Float.floatToIntBits(f) >> 1)); return f * Float.intBitsToFloat(0x5f375a86 - (Float.floatToIntBits(f) >> 1));
} }
public static double sqrtApprox(double d) { public static final double sqrtApprox(double d) {
return Double.longBitsToDouble(((Double.doubleToLongBits(d) - (1L << 52)) >> 1) + (1L << 61)); return Double.longBitsToDouble(((Double.doubleToLongBits(d) - (1l << 52)) >> 1) + (1l << 61));
} }
public static boolean isInteger(CharSequence str) { public static final float invSqrt(float x) {
float xhalf = 0.5f * x;
int i = Float.floatToIntBits(x);
i = 0x5f3759df - (i >> 1);
x = Float.intBitsToFloat(i);
x = x * (1.5f - (xhalf * x * x));
return x;
}
public static final boolean isInteger(CharSequence str) {
if (str == null) { if (str == null) {
return false; return false;
} }
@ -308,8 +377,41 @@ public class MathMan {
return true; return true;
} }
public static int absByte(int value) { public static final double getSD(double[] array, double av) {
double sd = 0;
for (double element : array) {
sd += Math.pow(Math.abs(element - av), 2);
}
return Math.sqrt(sd / array.length);
}
public static final double getSD(int[] array, double av) {
double sd = 0;
for (int element : array) {
sd += Math.pow(Math.abs(element - av), 2);
}
return Math.sqrt(sd / array.length);
}
public static final int absByte(int value) {
return (value ^ (value >> 8)) - (value >> 8); return (value ^ (value >> 8)) - (value >> 8);
} }
public static final int mod(int x, int y) {
if (isPowerOfTwo(y)) {
return x & (y - 1);
}
return x % y;
}
public static final int unsignedmod(int x, int y) {
if (isPowerOfTwo(y)) {
return x & (y - 1);
}
return x % y;
}
public static final boolean isPowerOfTwo(int x) {
return (x & (x - 1)) == 0;
}
} }

View File

@ -1,7 +1,6 @@
package com.boydti.fawe.util; package com.boydti.fawe.util;
import com.boydti.fawe.config.Settings; import com.boydti.fawe.config.Settings;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
@ -9,8 +8,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
public class MemUtil { public class MemUtil {
private static AtomicBoolean memory = new AtomicBoolean(false); private static AtomicBoolean memory = new AtomicBoolean(false);
private static Queue<Runnable> memoryLimitedTasks = new ConcurrentLinkedQueue<>();
private static Queue<Runnable> memoryPlentifulTasks = new ConcurrentLinkedQueue<>();
public static boolean isMemoryFree() { public static boolean isMemoryFree() {
return !memory.get(); return !memory.get();
@ -31,7 +28,8 @@ public class MemUtil {
} }
public static long getUsedBytes() { public static long getUsedBytes() {
return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); long used = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
return used;
} }
public static long getFreeBytes() { public static long getFreeBytes() {
@ -53,17 +51,18 @@ public class MemUtil {
return size; return size;
} }
private static Queue<Runnable> memoryLimitedTasks = new ConcurrentLinkedQueue<>();
private static Queue<Runnable> memoryPlentifulTasks = new ConcurrentLinkedQueue<>();
public static void addMemoryLimitedTask(Runnable run) { public static void addMemoryLimitedTask(Runnable run) {
if (run != null) { if (run != null)
memoryLimitedTasks.add(run); memoryLimitedTasks.add(run);
} }
}
public static void addMemoryPlentifulTask(Runnable run) { public static void addMemoryPlentifulTask(Runnable run) {
if (run != null) { if (run != null)
memoryPlentifulTasks.add(run); memoryPlentifulTasks.add(run);
} }
}
public static void memoryLimitedTask() { public static void memoryLimitedTask() {
System.gc(); System.gc();

View File

@ -16,6 +16,14 @@ public enum Perm {
this.cat = cat; this.cat = cat;
} }
public boolean has(final FawePlayer<?> player) {
return this.hasPermission(player, this);
}
public boolean hasPermission(final FawePlayer<?> player, final Perm perm) {
return hasPermission(player, perm.s);
}
public static boolean hasPermission(final FawePlayer<?> player, final String perm) { public static boolean hasPermission(final FawePlayer<?> player, final String perm) {
if ((player == null) || player.hasPermission(ADMIN.s)) { if ((player == null) || player.hasPermission(ADMIN.s)) {
return true; return true;
@ -33,12 +41,4 @@ public enum Perm {
} }
return false; return false;
} }
public boolean has(final FawePlayer<?> player) {
return this.hasPermission(player, this);
}
public boolean hasPermission(final FawePlayer<?> player, final Perm perm) {
return hasPermission(player, perm.s);
}
} }

View File

@ -8,13 +8,14 @@ import java.util.concurrent.ThreadLocalRandom;
public class RandomTextureUtil extends CachedTextureUtil { public class RandomTextureUtil extends CachedTextureUtil {
public RandomTextureUtil(TextureUtil parent) throws FileNotFoundException {
super(parent);
}
private int index; private int index;
private int[] biomeMixBuffer = new int[3]; private int[] biomeMixBuffer = new int[3];
private Int2ObjectOpenHashMap<Integer> offsets = new Int2ObjectOpenHashMap<>(); private Int2ObjectOpenHashMap<Integer> offsets = new Int2ObjectOpenHashMap<>();
private Int2ObjectOpenHashMap<int[]> biomeMixes = new Int2ObjectOpenHashMap<>(); private Int2ObjectOpenHashMap<int[]> biomeMixes = new Int2ObjectOpenHashMap<>();
public RandomTextureUtil(TextureUtil parent) throws FileNotFoundException {
super(parent);
}
protected int addRandomColor(int c1, int c2) { protected int addRandomColor(int c1, int c2) {
int red1 = (c1 >> 16) & 0xFF; int red1 = (c1 >> 16) & 0xFF;
@ -49,9 +50,7 @@ public class RandomTextureUtil extends CachedTextureUtil {
mix[3] = average; mix[3] = average;
biomeMixes.put(color, mix); biomeMixes.put(color, mix);
} }
if (++index > 2) { if (++index > 2) index = 0;
index = 0;
}
int biomeId = mix[index]; int biomeId = mix[index];
int biomeAvColor = mix[3]; int biomeAvColor = mix[3];
int blockColor = getColor(block); int blockColor = getColor(block);
@ -74,9 +73,7 @@ public class RandomTextureUtil extends CachedTextureUtil {
mix[3] = average; mix[3] = average;
biomeMixes.put(color, mix); biomeMixes.put(color, mix);
} }
if (++index > 2) { if (++index > 2) index = 0;
index = 0;
}
int biomeId = mix[index]; int biomeId = mix[index];
return getBiome(biomeId); return getBiome(biomeId);
} }
@ -90,9 +87,7 @@ public class RandomTextureUtil extends CachedTextureUtil {
offsetColor = color; offsetColor = color;
} }
BlockType res = super.getNearestBlock(offsetColor); BlockType res = super.getNearestBlock(offsetColor);
if (res == null) { if (res == null) return null;
return null;
}
int newColor = getColor(res); int newColor = getColor(res);
{ {
byte dr = (byte) (((color >> 16) & 0xFF) - ((newColor >> 16) & 0xFF)); byte dr = (byte) (((color >> 16) & 0xFF) - ((newColor >> 16) & 0xFF));

View File

@ -1,9 +1,5 @@
package com.boydti.fawe.util; package com.boydti.fawe.util;
import sun.reflect.ConstructorAccessor;
import sun.reflect.FieldAccessor;
import sun.reflect.ReflectionFactory;
import java.lang.reflect.AccessibleObject; import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
@ -11,12 +7,11 @@ import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.Collections; import sun.reflect.ConstructorAccessor;
import java.util.Comparator; import sun.reflect.FieldAccessor;
import java.util.List; import sun.reflect.ReflectionFactory;
import java.util.Map;
/** /**
* @author DPOH-VAR * @author DPOH-VAR
@ -24,8 +19,6 @@ import java.util.Map;
*/ */
@SuppressWarnings({"UnusedDeclaration", "rawtypes"}) @SuppressWarnings({"UnusedDeclaration", "rawtypes"})
public class ReflectionUtils { public class ReflectionUtils {
private static Class<?> UNMODIFIABLE_MAP = Collections.unmodifiableMap(Collections.EMPTY_MAP).getClass();
public static <T> T as(Class<T> t, Object o) { public static <T> T as(Class<T> t, Object o) {
return t.isInstance(o) ? t.cast(o) : null; return t.isInstance(o) ? t.cast(o) : null;
} }
@ -59,7 +52,7 @@ public class ReflectionUtils {
// 2. Copy it // 2. Copy it
T[] previousValues = (T[]) valuesField.get(enumType); T[] previousValues = (T[]) valuesField.get(enumType);
List<T> values = new ArrayList<>(Arrays.asList(previousValues)); List values = new ArrayList(Arrays.asList(previousValues));
// 3. build new enum // 3. build new enum
T newValue = (T) makeEnum(enumType, // The target enum class T newValue = (T) makeEnum(enumType, // The target enum class
@ -114,9 +107,7 @@ public class ReflectionUtils {
Class<? extends Enum> clazz = dest.getClass(); Class<? extends Enum> clazz = dest.getClass();
Object newEnum = makeEnum(clazz, value, dest.ordinal(), additionalTypes, additionalValues); Object newEnum = makeEnum(clazz, value, dest.ordinal(), additionalTypes, additionalValues);
for (Field field : clazz.getDeclaredFields()) { for (Field field : clazz.getDeclaredFields()) {
if (Modifier.isStatic(field.getModifiers())) { if (Modifier.isStatic(field.getModifiers())) continue;
continue;
}
field.setAccessible(true); field.setAccessible(true);
Object newValue = field.get(newEnum); Object newValue = field.get(newEnum);
setField(field, dest, newValue); setField(field, dest, newValue);
@ -189,12 +180,12 @@ public class ReflectionUtils {
blankField(enumClass, "enumConstants"); // IBM JDK blankField(enumClass, "enumConstants"); // IBM JDK
} }
private static Class<?> UNMODIFIABLE_MAP = Collections.unmodifiableMap(Collections.EMPTY_MAP).getClass();
public static <T, V> Map<T, V> getMap(Map<T, V> map) { public static <T, V> Map<T, V> getMap(Map<T, V> map) {
try { try {
Class<? extends Map> clazz = map.getClass(); Class<? extends Map> clazz = map.getClass();
if (clazz != UNMODIFIABLE_MAP) { if (clazz != UNMODIFIABLE_MAP) return map;
return map;
}
Field m = clazz.getDeclaredField("m"); Field m = clazz.getDeclaredField("m");
m.setAccessible(true); m.setAccessible(true);
return (Map<T, V>) m.get(map); return (Map<T, V>) m.get(map);
@ -207,9 +198,7 @@ public class ReflectionUtils {
public static <T> List<T> getList(List<T> list) { public static <T> List<T> getList(List<T> list) {
try { try {
Class<? extends List> clazz = (Class<? extends List>) Class.forName("java.util.Collections$UnmodifiableList"); Class<? extends List> clazz = (Class<? extends List>) Class.forName("java.util.Collections$UnmodifiableList");
if (!clazz.isInstance(list)) { if (!clazz.isInstance(list)) return list;
return list;
}
Field m = clazz.getDeclaredField("list"); Field m = clazz.getDeclaredField("list");
m.setAccessible(true); m.setAccessible(true);
return (List<T>) m.get(list); return (List<T>) m.get(list);
@ -316,25 +305,19 @@ public class ReflectionUtils {
if (returnType == null || method.getReturnType() == returnType) { if (returnType == null || method.getReturnType() == returnType) {
Class<?>[] mp = method.getParameterTypes(); Class<?>[] mp = method.getParameterTypes();
int mods = method.getModifiers(); int mods = method.getModifiers();
if ((mods & hasMods) != hasMods || (mods & noMods) != 0) { if ((mods & hasMods) != hasMods || (mods & noMods) != 0) continue;
continue;
}
if (params == null) { if (params == null) {
if (index-- == 0) { if (index-- == 0) return setAccessible(method);
return setAccessible(method); else {
} else {
continue; continue;
} }
} }
if (mp.length == params.length) { if (mp.length == params.length) {
for (int i = 0; i < mp.length; i++) { for (int i = 0; i < mp.length; i++) {
if (mp[i] != params[i]) { if (mp[i] != params[i]) continue outer;
continue outer;
} }
} if (index-- == 0) return setAccessible(method);
if (index-- == 0) { else {
return setAccessible(method);
} else {
continue; continue;
} }
} }

View File

@ -2,11 +2,7 @@ package com.boydti.fawe.util;
import sun.misc.Unsafe; import sun.misc.Unsafe;
import java.lang.reflect.AccessibleObject; import java.lang.reflect.*;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -33,7 +29,7 @@ public class ReflectionUtils9 {
// 2. Copy it // 2. Copy it
T[] previousValues = (T[]) valuesField.get(enumType); T[] previousValues = (T[]) valuesField.get(enumType);
List<T> values = new ArrayList<>(Arrays.asList(previousValues)); List values = new ArrayList(Arrays.asList(previousValues));
// 3. build new enum // 3. build new enum
T newValue = (T) makeEnum(enumType, // The target enum class T newValue = (T) makeEnum(enumType, // The target enum class
@ -121,11 +117,8 @@ public class ReflectionUtils9 {
} }
try { try {
if (target == null) { if (target == null) field.set(null, value);
field.set(null, value); else field.set(target, value);
} else {
field.set(target, value);
}
} catch (NoSuchMethodError error) { } catch (NoSuchMethodError error) {
field.set(target, value); field.set(target, value);
} }

View File

@ -5,7 +5,6 @@ import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.FaweQueue; import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.wrappers.WorldWrapper; import com.boydti.fawe.wrappers.WorldWrapper;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -22,29 +21,61 @@ public class SetQueue {
* The implementation specific queue * The implementation specific queue
*/ */
public static final SetQueue IMP = new SetQueue(); public static final SetQueue IMP = new SetQueue();
private double targetTPS = 18;
public enum QueueStage {
INACTIVE, ACTIVE, NONE;
}
private final ConcurrentLinkedDeque<FaweQueue> activeQueues; private final ConcurrentLinkedDeque<FaweQueue> activeQueues;
private final ConcurrentLinkedDeque<FaweQueue> inactiveQueues; private final ConcurrentLinkedDeque<FaweQueue> inactiveQueues;
private final ConcurrentLinkedDeque<Runnable> tasks; private final ConcurrentLinkedDeque<Runnable> tasks;
/**
* A queue of tasks that will run when the queue is empty
*/
private final ConcurrentLinkedDeque<Runnable> emptyTasks = new ConcurrentLinkedDeque<>();
private double targetTPS = 18;
/** /**
* Used to calculate elapsed time in milliseconds and ensure block placement doesn't lag the server * Used to calculate elapsed time in milliseconds and ensure block placement doesn't lag the server
*/ */
private long last; private long last;
private long allocate = 50; private long allocate = 50;
private long lastSuccess; private long lastSuccess;
/**
* A queue of tasks that will run when the queue is empty
*/
private final ConcurrentLinkedDeque<Runnable> emptyTasks = new ConcurrentLinkedDeque<>();
private ForkJoinPool pool = new ForkJoinPool(); private ForkJoinPool pool = new ForkJoinPool();
private ExecutorCompletionService completer = new ExecutorCompletionService(pool); private ExecutorCompletionService completer = new ExecutorCompletionService(pool);
/**
* @return ForkJoinPool
* @see TaskManager#getPublicForkJoinPool()
*/
@Deprecated
public ExecutorCompletionService getCompleterService() {
return completer;
}
@Deprecated
public ForkJoinPool getForkJoinPool() {
return pool;
}
public void runMiscTasks() {
while (Fawe.get().getTimer().isAbove(targetTPS)) {
Runnable task = tasks.poll();
if (task != null) {
task.run();
} else {
break;
}
}
}
public SetQueue() { public SetQueue() {
tasks = new ConcurrentLinkedDeque<>(); tasks = new ConcurrentLinkedDeque<>();
activeQueues = new ConcurrentLinkedDeque<>(); activeQueues = new ConcurrentLinkedDeque<>();
inactiveQueues = new ConcurrentLinkedDeque<>(); inactiveQueues = new ConcurrentLinkedDeque<>();
if (TaskManager.IMP == null) { if (TaskManager.IMP == null) return;
return;
}
TaskManager.IMP.repeat(() -> { TaskManager.IMP.repeat(() -> {
try { try {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
@ -139,8 +170,17 @@ public class SetQueue {
e.printStackTrace(); e.printStackTrace();
} }
if (pool.getQueuedSubmissionCount() != 0 || pool.getRunningThreadCount() != 0 || pool.getQueuedTaskCount() != 0) { if (pool.getQueuedSubmissionCount() != 0 || pool.getRunningThreadCount() != 0 || pool.getQueuedTaskCount() != 0) {
// if (Fawe.get().isJava8())
{
pool.awaitQuiescence(Long.MAX_VALUE, TimeUnit.MILLISECONDS); pool.awaitQuiescence(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
} }
// else {
// pool.shutdown();
// pool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
// pool = new ForkJoinPool();
// completer = new ExecutorCompletionService(pool);
// }
}
queue.endSet(parallel); queue.endSet(parallel);
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
@ -148,31 +188,6 @@ public class SetQueue {
}, 1); }, 1);
} }
/**
* @return ForkJoinPool
* @see TaskManager#getPublicForkJoinPool()
*/
@Deprecated
public ExecutorCompletionService getCompleterService() {
return completer;
}
@Deprecated
public ForkJoinPool getForkJoinPool() {
return pool;
}
public void runMiscTasks() {
while (Fawe.get().getTimer().isAbove(targetTPS)) {
Runnable task = tasks.poll();
if (task != null) {
task.run();
} else {
break;
}
}
}
public QueueStage getStage(FaweQueue queue) { public QueueStage getStage(FaweQueue queue) {
return queue.getStage(); return queue.getStage();
} }
@ -226,9 +241,7 @@ public class SetQueue {
public FaweQueue getNewQueue(World world, boolean fast, boolean autoqueue) { public FaweQueue getNewQueue(World world, boolean fast, boolean autoqueue) {
world = WorldWrapper.unwrap(world); world = WorldWrapper.unwrap(world);
if (world instanceof FaweQueue) { if (world instanceof FaweQueue) return (FaweQueue) world;
return (FaweQueue) world;
}
FaweQueue queue = Fawe.imp().getNewQueue(world, fast); FaweQueue queue = Fawe.imp().getNewQueue(world, fast);
if (autoqueue) { if (autoqueue) {
queue.setStage(QueueStage.INACTIVE); queue.setStage(QueueStage.INACTIVE);
@ -431,8 +444,4 @@ public class SetQueue {
} }
return true; return true;
} }
public enum QueueStage {
INACTIVE, ACTIVE, NONE;
}
} }

View File

@ -1,6 +1,7 @@
package com.boydti.fawe.util; package com.boydti.fawe.util;
import java.awt.*; import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
import java.awt.geom.FlatteningPathIterator; import java.awt.geom.FlatteningPathIterator;
import java.awt.geom.IllegalPathStateException; import java.awt.geom.IllegalPathStateException;
@ -53,43 +54,6 @@ public class ShapeInterpolator {
return instance.evaluate(v0, v1, fraction, unionBounds); return instance.evaluate(v0, v1, fraction, unionBounds);
} }
private static float[] mergeTVals(float[] tVals0, float[] tVals1) {
final int count = sortTVals(tVals0, tVals1, null);
final float[] newTVals = new float[count];
sortTVals(tVals0, tVals1, newTVals);
return newTVals;
}
private static int sortTVals(float[] tVals0,
float[] tVals1,
float[] newTVals) {
int i0 = 0;
int i1 = 0;
int numTVals = 0;
while (i0 < tVals0.length && i1 < tVals1.length) {
final float t0 = tVals0[i0];
final float t1 = tVals1[i1];
if (t0 <= t1) {
if (newTVals != null) {
newTVals[numTVals] = t0;
}
i0++;
}
if (t1 <= t0) {
if (newTVals != null) {
newTVals[numTVals] = t1;
}
i1++;
}
numTVals++;
}
return numTVals;
}
private static float interp(float v0, float v1, float t) {
return (v0 + ((v1 - v0) * t));
}
/** /**
* Creates an interpolated shape from tight bounds. * Creates an interpolated shape from tight bounds.
*/ */
@ -137,6 +101,43 @@ public class ShapeInterpolator {
return new MorphedShape(geom0, geom1, fraction, unionBounds); return new MorphedShape(geom0, geom1, fraction, unionBounds);
} }
private static float[] mergeTVals(float[] tVals0, float[] tVals1) {
final int count = sortTVals(tVals0, tVals1, null);
final float[] newTVals = new float[count];
sortTVals(tVals0, tVals1, newTVals);
return newTVals;
}
private static int sortTVals(float[] tVals0,
float[] tVals1,
float[] newTVals) {
int i0 = 0;
int i1 = 0;
int numTVals = 0;
while (i0 < tVals0.length && i1 < tVals1.length) {
final float t0 = tVals0[i0];
final float t1 = tVals1[i1];
if (t0 <= t1) {
if (newTVals != null) {
newTVals[numTVals] = t0;
}
i0++;
}
if (t1 <= t0) {
if (newTVals != null) {
newTVals[numTVals] = t1;
}
i1++;
}
numTVals++;
}
return numTVals;
}
private static float interp(float v0, float v1, float t) {
return (v0 + ((v1 - v0) * t));
}
private static class Geometry { private static class Geometry {
static final float THIRD = (1f / 3f); static final float THIRD = (1f / 3f);
static final float MIN_LEN = 0.001f; static final float MIN_LEN = 0.001f;
@ -671,21 +672,21 @@ public class ShapeInterpolator {
} }
/** /**
* @inheritDoc * @{inheritDoc}
*/ */
public int getWindingRule() { public int getWindingRule() {
return (t < 0.5 ? g0.getWindingRule() : g1.getWindingRule()); return (t < 0.5 ? g0.getWindingRule() : g1.getWindingRule());
} }
/** /**
* @inheritDoc * @{inheritDoc}
*/ */
public boolean isDone() { public boolean isDone() {
return (cIndex > g0.getNumCoordinates()); return (cIndex > g0.getNumCoordinates());
} }
/** /**
* @inheritDoc * @{inheritDoc}
*/ */
public void next() { public void next() {
if (cIndex == 0) { if (cIndex == 0) {
@ -696,7 +697,7 @@ public class ShapeInterpolator {
} }
/** /**
* @inheritDoc * @{inheritDoc}
*/ */
public int currentSegment(float[] coordinates) { public int currentSegment(float[] coordinates) {
int type; int type;

View File

@ -1,5 +1,7 @@
package com.boydti.fawe.util; package com.boydti.fawe.util;
import com.sk89q.util.StringUtil;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -10,6 +12,9 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.IntConsumer;
import java.util.function.IntFunction;
import java.util.function.Predicate;
public class StringMan { public class StringMan {
public static String replaceFromMap(final String string, final Map<String, String> replacements) { public static String replaceFromMap(final String string, final Map<String, String> replacements) {
@ -35,9 +40,7 @@ public class StringMan {
public static boolean containsAny(CharSequence sequence, String any) { public static boolean containsAny(CharSequence sequence, String any) {
for (int i = 0; i < sequence.length(); i++) { for (int i = 0; i < sequence.length(); i++) {
if (any.indexOf(sequence.charAt(i)) != -1) { if (any.indexOf(sequence.charAt(i)) != -1) return true;
return true;
}
} }
return false; return false;
} }
@ -45,9 +48,7 @@ public class StringMan {
public static int findMatchingBracket(CharSequence sequence, int index) { public static int findMatchingBracket(CharSequence sequence, int index) {
char startC = sequence.charAt(index); char startC = sequence.charAt(index);
char lookC = getMatchingBracket(startC); char lookC = getMatchingBracket(startC);
if (lookC == startC) { if (lookC == startC) return -1;
return -1;
}
boolean forward = isBracketForwards(startC); boolean forward = isBracketForwards(startC);
int increment = forward ? 1 : -1; int increment = forward ? 1 : -1;
int end = forward ? sequence.length() : -1; int end = forward ? sequence.length() : -1;
@ -64,17 +65,10 @@ public class StringMan {
} }
public static String prettyFormat(double d) { public static String prettyFormat(double d) {
if (d == Double.MIN_VALUE) { if (d == Double.MIN_VALUE) return "-∞";
return "-∞"; if (d == Double.MAX_VALUE) return "";
} if(d == (long) d) return String.format("%d",(long)d);
if (d == Double.MAX_VALUE) { else return String.format("%s",d);
return "";
}
if (d == (long) d) {
return String.format("%d", (long) d);
} else {
return String.format("%s", d);
}
} }
public static boolean isBracketForwards(char c) { public static boolean isBracketForwards(char c) {
@ -84,31 +78,21 @@ public class StringMan {
case '{': case '{':
case '<': case '<':
return true; return true;
default: default: return false;
return false;
} }
} }
public static char getMatchingBracket(char c) { public static char getMatchingBracket(char c) {
switch (c) { switch (c) {
case '[': case '[': return ']';
return ']'; case '(': return ')';
case '(': case '{': return '}';
return ')'; case '<': return '>';
case '{': case ']': return '[';
return '}'; case ')': return '(';
case '<': case '}': return '{';
return '>'; case '>': return '<';
case ']': default: return c;
return '[';
case ')':
return '(';
case '}':
return '{';
case '>':
return '<';
default:
return c;
} }
} }
@ -155,9 +139,7 @@ public class StringMan {
public static int indexOf(String input, int start, char... values) { public static int indexOf(String input, int start, char... values) {
for (int i = start; i < input.length(); i++) { for (int i = start; i < input.length(); i++) {
for (char c : values) { for (char c : values) {
if (c == input.charAt(i)) { if (c == input.charAt(i)) return i;
return i;
}
} }
} }
return -1; return -1;
@ -176,15 +158,11 @@ public class StringMan {
for (int current = 0; current < input.length(); current++) { for (int current = 0; current < input.length(); current++) {
char currentChar = input.charAt(current); char currentChar = input.charAt(current);
boolean atLastChar = (current == input.length() - 1); boolean atLastChar = (current == input.length() - 1);
if (!atLastChar && (bracket > 0 || (currentChar == '{' && ++bracket > 0) || (current == '}' && --bracket <= 0))) { if (!atLastChar && (bracket > 0 || (currentChar == '{' && ++bracket > 0) || (current == '}' && --bracket <= 0)))
continue; continue;
} if (currentChar == '\"') inQuotes = !inQuotes; // toggle state
if (currentChar == '\"') { if (atLastChar) result.add(input.substring(start));
inQuotes = !inQuotes; // toggle state else if (currentChar == delim && !inQuotes) {
}
if (atLastChar) {
result.add(input.substring(start));
} else if (currentChar == delim && !inQuotes) {
String toAdd = input.substring(start, current); String toAdd = input.substring(start, current);
if (toAdd.startsWith("\"")) { if (toAdd.startsWith("\"")) {
toAdd = toAdd.substring(1, toAdd.length() - 1); toAdd = toAdd.substring(1, toAdd.length() - 1);
@ -369,9 +347,7 @@ public class StringMan {
char ai = input.charAt(i); char ai = input.charAt(i);
outer: outer:
while (true) { while (true) {
if (j >= item.length()) { if (j >= item.length()) return Integer.MAX_VALUE;
return Integer.MAX_VALUE;
}
char bj = item.charAt(j++); char bj = item.charAt(j++);
if (sequentail) { if (sequentail) {
@ -379,9 +355,7 @@ public class StringMan {
case ':': case ':':
case '_': case '_':
sequentail = false; sequentail = false;
if (bj == ai) { if (bj == ai) break outer;
break outer;
}
continue; continue;
} }
continue; continue;
@ -481,9 +455,8 @@ public class StringMan {
if (char0 == '-') { if (char0 == '-') {
negative = true; negative = true;
start++; start++;
} else {
negative = false;
} }
else negative = false;
for (int i = start; i < end; i++) { for (int i = start; i < end; i++) {
char c = string.charAt(i); char c = string.charAt(i);
switch (c) { switch (c) {

View File

@ -6,13 +6,13 @@ import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.RunnableVal; import com.boydti.fawe.object.RunnableVal;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier; import java.util.function.Supplier;
import javax.annotation.Nullable;
public abstract class TaskManager { public abstract class TaskManager {

View File

@ -1,19 +1,25 @@
package com.boydti.fawe.util; package com.boydti.fawe.util;
import com.boydti.fawe.Fawe; import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.config.Settings; import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.pattern.PatternExtent; import com.boydti.fawe.object.pattern.PatternExtent;
import com.boydti.fawe.util.image.ImageUtil; import com.boydti.fawe.util.image.ImageUtil;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonReader;
import com.sk89q.worldedit.util.command.binding.Text;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.pattern.BlockPattern; import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType; 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.BlockMaterial; import com.sk89q.worldedit.world.registry.BlockMaterial;
import com.sk89q.worldedit.world.registry.BundledBlockData;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntArraySet; import it.unimi.dsi.fastutil.ints.IntArraySet;
@ -21,32 +27,59 @@ import it.unimi.dsi.fastutil.longs.LongArrayList;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File; import java.io.*;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
// TODO FIXME // TODO FIXME
public class public class TextureUtil implements TextureHolder {
TextureUtil implements TextureHolder {
public static TextureUtil fromClipboard(Clipboard clipboard) throws FileNotFoundException {
boolean[] ids = new boolean[BlockTypes.size()];
for (BlockVector3 pt : clipboard.getRegion()) {
ids[clipboard.getBlock(pt).getInternalBlockTypeId()] = true;
}
HashSet<BlockType> blocks = new HashSet<>();
for (int typeId = 0; typeId < ids.length; typeId++) {
if (ids[typeId]) {
blocks.add(BlockTypes.get(typeId));
}
}
return fromBlocks(blocks);
}
public static TextureUtil fromBlocks(Set<BlockType> blocks) throws FileNotFoundException {
return new FilteredTextureUtil(Fawe.get().getTextureUtil(), blocks);
}
public static TextureUtil fromMask(Mask mask) throws FileNotFoundException {
HashSet<BlockType> blocks = new HashSet<>();
BlockPattern pattern = new BlockPattern(BlockTypes.AIR.getDefaultState());
PatternExtent extent = new PatternExtent(pattern);
new MaskTraverser(mask).reset(extent);
TextureUtil tu = Fawe.get().getTextureUtil();
for (int typeId : tu.getValidBlockIds()) {
BlockType block = BlockTypes.get(typeId);
pattern.setBlock(block.getDefaultState());
if (mask.test(BlockVector3.ZERO)) {
blocks.add(block);
}
}
return fromBlocks(blocks);
}
@Override public TextureUtil getTextureUtil() {
return this;
}
private final File folder;
private static final int[] FACTORS = new int[766]; private static final int[] FACTORS = new int[766];
static { static {
@ -55,21 +88,23 @@ TextureUtil implements TextureHolder {
} }
} }
private final File folder;
protected int[] blockColors = new int[BlockTypes.size()]; protected int[] blockColors = new int[BlockTypes.size()];
protected long[] blockDistance = new long[BlockTypes.size()]; protected long[] blockDistance = new long[BlockTypes.size()];
protected long[] distances; protected long[] distances;
protected int[] validColors; protected int[] validColors;
protected int[] validBlockIds; protected int[] validBlockIds;
protected int[] validLayerColors; protected int[] validLayerColors;
protected int[][] validLayerBlocks; protected int[][] validLayerBlocks;
protected int[] validMixBiomeColors; protected int[] validMixBiomeColors;
protected long[] validMixBiomeIds; protected long[] validMixBiomeIds;
/** /**
* https://github.com/erich666/Mineways/blob/master/Win/biomes.cpp * https://github.com/erich666/Mineways/blob/master/Win/biomes.cpp
*/ */
protected BiomeColor[] validBiomes; protected BiomeColor[] validBiomes;
private BiomeColor[] biomes = new BiomeColor[]{ private BiomeColor[] biomes = new BiomeColor[] {
// ID Name Temperature, rainfall, grass, foliage colors // ID Name Temperature, rainfall, grass, foliage colors
// - note: the colors here are just placeholders, they are computed in the program // - note: the colors here are just placeholders, they are computed in the program
new BiomeColor(0, "Ocean", 0.5f, 0.5f, 0x92BD59, 0x77AB2F), new BiomeColor(0, "Ocean", 0.5f, 0.5f, 0x92BD59, 0x77AB2F),
@ -333,7 +368,7 @@ TextureUtil implements TextureHolder {
new BiomeColor(253, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F), new BiomeColor(253, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(254, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F), new BiomeColor(254, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
new BiomeColor(255, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),}; new BiomeColor(255, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),};
private BlockType[] layerBuffer = new BlockType[2];
public TextureUtil() throws FileNotFoundException { public TextureUtil() throws FileNotFoundException {
this(MainUtil.getFile(Fawe.imp().getDirectory(), Settings.IMP.PATHS.TEXTURES)); this(MainUtil.getFile(Fawe.imp().getDirectory(), Settings.IMP.PATHS.TEXTURES));
} }
@ -346,59 +381,6 @@ TextureUtil implements TextureHolder {
} }
} }
public static TextureUtil fromClipboard(Clipboard clipboard) throws FileNotFoundException {
boolean[] ids = new boolean[BlockTypes.size()];
for (BlockVector3 pt : clipboard.getRegion()) {
ids[clipboard.getBlock(pt).getInternalBlockTypeId()] = true;
}
HashSet<BlockType> blocks = new HashSet<>();
for (int typeId = 0; typeId < ids.length; typeId++) {
if (ids[typeId]) {
blocks.add(BlockTypes.get(typeId));
}
}
return fromBlocks(blocks);
}
public static TextureUtil fromBlocks(Set<BlockType> blocks) throws FileNotFoundException {
return new FilteredTextureUtil(Fawe.get().getTextureUtil(), blocks);
}
public static TextureUtil fromMask(Mask mask) throws FileNotFoundException {
HashSet<BlockType> blocks = new HashSet<>();
BlockPattern pattern = new BlockPattern(BlockTypes.AIR.getDefaultState());
PatternExtent extent = new PatternExtent(pattern);
new MaskTraverser(mask).reset(extent);
TextureUtil tu = Fawe.get().getTextureUtil();
for (int typeId : tu.getValidBlockIds()) {
BlockType block = BlockTypes.get(typeId);
pattern.setBlock(block.getDefaultState());
if (mask.test(BlockVector3.ZERO)) {
blocks.add(block);
}
}
return fromBlocks(blocks);
}
protected static int hueDistance(int red1, int green1, int blue1, int red2, int green2,
int blue2) {
int total1 = (red1 + green1 + blue1);
int total2 = (red2 + green2 + blue2);
if (total1 == 0 || total2 == 0) {
return 0;
}
int factor1 = FACTORS[total1];
int factor2 = FACTORS[total2];
long r = (512 * (red1 * factor1 - red2 * factor2)) >> 10;
long g = (green1 * factor1 - green2 * factor2);
long b = (767 * (blue1 * factor1 - blue2 * factor2)) >> 10;
return (int) ((r * r + g * g + b * b) >> 25);
}
@Override public TextureUtil getTextureUtil() {
return this;
}
public BlockType getNearestBlock(int color) { public BlockType getNearestBlock(int color) {
long min = Long.MAX_VALUE; long min = Long.MAX_VALUE;
int closest = 0; int closest = 0;
@ -453,6 +435,8 @@ TextureUtil implements TextureHolder {
return BlockTypes.get(closest); return BlockTypes.get(closest);
} }
private BlockType[] layerBuffer = new BlockType[2];
/** /**
* Returns the block combined ids as an array * Returns the block combined ids as an array
* *
@ -732,7 +716,6 @@ TextureUtil implements TextureHolder {
biomes[134].grass = 0; biomes[134].grass = 0;
// roofed forest: averaged w/ 0x28340A // roofed forest: averaged w/ 0x28340A
biomes[29].grass = biomes[29].grass =
//TODO the following expressions will always overflow because they will be bigger than MAX_INT
multiplyColor(biomes[29].grass, 0x28340A + (255 << 24)); multiplyColor(biomes[29].grass, 0x28340A + (255 << 24));
biomes[157].grass = biomes[157].grass =
multiplyColor(biomes[157].grass, 0x28340A + (255 << 24)); multiplyColor(biomes[157].grass, 0x28340A + (255 << 24));
@ -752,7 +735,7 @@ TextureUtil implements TextureHolder {
} }
biome.grassCombined = multiplyColor(grass, biome.grass); biome.grassCombined = multiplyColor(grass, biome.grass);
} }
this.validBiomes = valid.toArray(new BiomeColor[0]); this.validBiomes = valid.toArray(new BiomeColor[valid.size()]);
{ {
ArrayList<BiomeColor> uniqueColors = new ArrayList<>(); ArrayList<BiomeColor> uniqueColors = new ArrayList<>();
@ -906,7 +889,7 @@ TextureUtil implements TextureHolder {
if (!hasAlpha(colorOther)) { if (!hasAlpha(colorOther)) {
int combinedOther = validBlockIds[j]; int combinedOther = validBlockIds[j];
int combinedColor = combineTransparency(color, colorOther); int combinedColor = combineTransparency(color, colorOther);
colorLayerMap.put(combinedColor, new int[]{combined, combinedOther}); colorLayerMap.put(combinedColor, new int[] {combined, combinedOther});
} }
} }
} }
@ -994,6 +977,21 @@ TextureUtil implements TextureHolder {
* hd); * hd);
} }
protected static int hueDistance(int red1, int green1, int blue1, int red2, int green2,
int blue2) {
int total1 = (red1 + green1 + blue1);
int total2 = (red2 + green2 + blue2);
if (total1 == 0 || total2 == 0) {
return 0;
}
int factor1 = FACTORS[total1];
int factor2 = FACTORS[total2];
long r = (512 * (red1 * factor1 - red2 * factor2)) >> 10;
long g = (green1 * factor1 - green2 * factor2);
long b = (767 * (blue1 * factor1 - blue2 * factor2)) >> 10;
return (int) ((r * r + g * g + b * b) >> 25);
}
public long getDistance(BufferedImage image, int c1) { public long getDistance(BufferedImage image, int c1) {
long totalDistSqr = 0; long totalDistSqr = 0;
int width = image.getWidth(); int width = image.getWidth();
@ -1012,10 +1010,6 @@ TextureUtil implements TextureHolder {
return totalDistSqr / area; return totalDistSqr / area;
} }
public int[] getValidBlockIds() {
return validBlockIds.clone();
}
public static class BiomeColor { public static class BiomeColor {
public int id; public int id;
public String name; public String name;
@ -1036,4 +1030,8 @@ TextureUtil implements TextureHolder {
this.foliage = foliage; this.foliage = foliage;
} }
} }
public int[] getValidBlockIds() {
return validBlockIds.clone();
}
} }

View File

@ -14,12 +14,9 @@ import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayDeque; import java.util.*;
import java.util.HashSet; import java.util.stream.Collectors;
import java.util.Iterator;
import java.util.Set;
public class WEManager { public class WEManager {
@ -127,9 +124,7 @@ public class WEManager {
} }
} }
} }
if (!removed) { if (!removed) return regions.toArray(new Region[0]);
return regions.toArray(new Region[0]);
}
masks.clear(); masks.clear();
} }
} }
@ -137,16 +132,12 @@ public class WEManager {
for (final FaweMaskManager manager : managers) { for (final FaweMaskManager manager : managers) {
if (player.hasPermission("fawe." + manager.getKey())) { if (player.hasPermission("fawe." + manager.getKey())) {
try { try {
if (manager.isExclusive() && !masks.isEmpty()) { if (manager.isExclusive() && !masks.isEmpty()) continue;
continue;
}
final FaweMask mask = manager.getMask(player, FaweMaskManager.MaskType.getDefaultMaskType()); final FaweMask mask = manager.getMask(player, FaweMaskManager.MaskType.getDefaultMaskType());
if (mask != null) { if (mask != null) {
regions.add(mask.getRegion()); regions.add(mask.getRegion());
masks.add(mask); masks.add(mask);
if (manager.isExclusive()) { if (manager.isExclusive()) break;
break;
}
} }
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();

View File

@ -5,7 +5,6 @@ import com.boydti.fawe.config.BBC;
import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.FawePlayer;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import java.util.Objects; import java.util.Objects;
public class Message { public class Message {
@ -98,9 +97,7 @@ public class Message {
public Message cmdOptions(String prefix, String suffix, String... options) { public Message cmdOptions(String prefix, String suffix, String... options) {
for (int i = 0; i < options.length; i++) { for (int i = 0; i < options.length; i++) {
if (i != 0) { if (i != 0) text(" &8|&7 ");
text(" &8|&7 ");
}
text("&7[&a" + options[i] + "&7]") text("&7[&a" + options[i] + "&7]")
.cmdTip(prefix + options[i] + suffix); .cmdTip(prefix + options[i] + suffix);
} }

View File

@ -3,7 +3,6 @@ package com.boydti.fawe.util.chat;
import com.boydti.fawe.config.BBC; import com.boydti.fawe.config.BBC;
import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.FawePlayer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -21,12 +20,10 @@ public class PlainChatManager implements ChatManager<List<StringBuilder>> {
} }
@Override @Override
public void tooltip(Message message, Message... tooltips) { public void tooltip(Message message, Message... tooltips) {}
}
@Override @Override
public void command(Message message, String command) { public void command(Message message, String command) {}
}
@Override @Override
public void text(Message message, String text) { public void text(Message message, String text) {
@ -43,10 +40,8 @@ public class PlainChatManager implements ChatManager<List<StringBuilder>> {
} }
@Override @Override
public void suggest(Message plotMessage, String command) { public void suggest(Message plotMessage, String command) {}
}
@Override @Override
public void link(Message message, String url) { public void link(Message message, String url) {}
}
} }

View File

@ -15,11 +15,11 @@ import com.sk89q.worldedit.util.command.Parameter;
import com.sk89q.worldedit.util.command.PrimaryAliasComparator; import com.sk89q.worldedit.util.command.PrimaryAliasComparator;
import com.sk89q.worldedit.util.command.binding.Range; import com.sk89q.worldedit.util.command.binding.Range;
import com.sk89q.worldedit.util.command.parametric.ParameterData; import com.sk89q.worldedit.util.command.parametric.ParameterData;
import javax.annotation.Nullable;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
@ -85,15 +85,13 @@ public class UsageMessage extends Message {
String arg; String arg;
if (param.getFlag() != null) { if (param.getFlag() != null) {
arg = "-" + param.getFlag(); arg = "-" + param.getFlag();
if (param.isValueFlag()) { if (param.isValueFlag())
arg += param.getName(); arg += param.getName();
}
} else { } else {
arg = param.getName(); arg = param.getName();
if (param.getDefaultValue() != null && param.getDefaultValue().length > 0) { if (param.getDefaultValue() != null && param.getDefaultValue().length > 0)
arg += "=" + StringMan.join(param.getDefaultValue(), ","); arg += "=" + StringMan.join(param.getDefaultValue(), ",");
} }
}
usage[i] = optional ? ("[" + arg + "]") : ("<" + arg + ">"); usage[i] = optional ? ("[" + arg + "]") : ("<" + arg + ">");
} }
} }
@ -106,9 +104,7 @@ public class UsageMessage extends Message {
String argStr = usage[i]; String argStr = usage[i];
text(separateArg(argStr.replaceAll("[\\[|\\]|<|>]", "&0$0&7"))); text(separateArg(argStr.replaceAll("[\\[|\\]|<|>]", "&0$0&7")));
if (params.isEmpty()) { if (params.isEmpty()) continue;
continue;
}
Parameter param = params.get(i); Parameter param = params.get(i);
StringBuilder tooltip = new StringBuilder(); StringBuilder tooltip = new StringBuilder();
@ -145,9 +141,7 @@ public class UsageMessage extends Message {
tooltip.append("\nClick for more info"); tooltip.append("\nClick for more info");
} }
tooltip(tooltip.toString()); tooltip(tooltip.toString());
if (command != null) { if (command != null) command(command);
command(command);
}
} }
newline(); newline();

View File

@ -7,7 +7,9 @@ import com.boydti.fawe.util.MathMan;
import com.sk89q.worldedit.util.command.parametric.ParameterException; import com.sk89q.worldedit.util.command.parametric.ParameterException;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.awt.*; import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt; import java.awt.image.DataBufferInt;
import java.io.File; import java.io.File;
@ -23,56 +25,54 @@ public class ImageUtil {
int targetWidth, int targetWidth,
int targetHeight, int targetHeight,
Object hint, Object hint,
boolean higherQuality) { boolean higherQuality)
{
if (img.getHeight() == targetHeight && img.getWidth() == targetWidth) { if (img.getHeight() == targetHeight && img.getWidth() == targetWidth) {
return img; return img;
} }
int type = (img.getTransparency() == Transparency.OPAQUE) ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB; int type = (img.getTransparency() == Transparency.OPAQUE) ?
BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage ret = img; BufferedImage ret = img;
int width, height; int w, h;
if (higherQuality) { if (higherQuality) {
// Use multi-step technique: start with original size, then // Use multi-step technique: start with original size, then
// scale down in multiple passes with drawImage() // scale down in multiple passes with drawImage()
// until the target size is reached // until the target size is reached
width = ret.getWidth(); w = ret.getWidth();
height = ret.getHeight(); h = ret.getHeight();
} else { } else {
// Use one-step technique: scale directly from original // Use one-step technique: scale directly from original
// size to target size with a single drawImage() call // size to target size with a single drawImage() call
width = targetWidth; w = targetWidth;
height = targetHeight; h = targetHeight;
} }
do { do {
if (higherQuality && width > targetWidth) { if (higherQuality && w > targetWidth) {
width /= 2; w /= 2;
if (width < targetWidth) { if (w < targetWidth) {
width = targetWidth; w = targetWidth;
}
} else if (width < targetWidth) {
width = targetWidth;
} }
} else if (w < targetWidth) w = targetWidth;
if (higherQuality && height > targetHeight) { if (higherQuality && h > targetHeight) {
height /= 2; h /= 2;
if (height < targetHeight) { if (h < targetHeight) {
height = targetHeight; h = targetHeight;
}
} else if (height < targetHeight) {
height = targetHeight;
} }
} else if (h < targetHeight) h = targetHeight;
BufferedImage tmp = new BufferedImage(width, height, type); BufferedImage tmp = new BufferedImage(w, h, type);
Graphics2D g2 = tmp.createGraphics(); Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint); g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED); g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
g2.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_SPEED); g2.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_SPEED);
g2.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED); g2.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED);
g2.drawImage(ret, 0, 0, width, height, null); g2.drawImage(ret, 0, 0, w, h, null);
g2.dispose(); g2.dispose();
ret = tmp; ret = tmp;
} while (width != targetWidth || height != targetHeight); } while (w != targetWidth || h != targetHeight);
return ret; return ret;
} }
@ -107,9 +107,8 @@ public class ImageUtil {
if (alpha != 0) { if (alpha != 0) {
float dx2 = sqrX[x]; float dx2 = sqrX[x];
float distSqr = dz2 + dx2; float distSqr = dz2 + dx2;
if (distSqr > 1) { if (distSqr > 1) raw[index] = 0;
raw[index] = 0; else {
} else {
alpha = (int) (alpha * (1 - distSqr)); alpha = (int) (alpha * (1 - distSqr));
raw[index] = (color & 0x00FFFFFF) + (alpha << 24); raw[index] = (color & 0x00FFFFFF) + (alpha << 24);
} }

View File

@ -2,6 +2,6 @@ package com.boydti.fawe.util.image;
import java.io.Closeable; import java.io.Closeable;
public interface ImageViewer extends Closeable { public interface ImageViewer extends Closeable{
public void view(Drawable drawable); public void view(Drawable drawable);
} }

View File

@ -6,7 +6,6 @@ import com.boydti.fawe.object.Metadatable;
import com.boydti.fawe.object.RunnableVal; import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.util.SetQueue; import com.boydti.fawe.util.SetQueue;
import com.boydti.fawe.util.TaskManager; import com.boydti.fawe.util.TaskManager;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Objects; import java.util.Objects;
@ -19,12 +18,6 @@ public class TaskBuilder extends Metadatable {
private final ArrayDeque<RunnableTask> tasks; private final ArrayDeque<RunnableTask> tasks;
private Object result = null; private Object result = null;
private Thread.UncaughtExceptionHandler handler; private Thread.UncaughtExceptionHandler handler;
private FaweQueue queue;
private long last;
private long start;
private Object asyncWaitLock = new Object();
private Object syncWaitLock = new Object();
private boolean finished;
public TaskBuilder() { public TaskBuilder() {
this(null); this(null);
@ -175,9 +168,7 @@ public class TaskBuilder extends Metadatable {
public TaskBuilder abortIfTrue(final Runnable run) { public TaskBuilder abortIfTrue(final Runnable run) {
tasks.add(RunnableTask.adapt((Task<Boolean, Boolean>) previous -> { tasks.add(RunnableTask.adapt((Task<Boolean, Boolean>) previous -> {
if (previous == Boolean.TRUE) { if (previous == Boolean.TRUE) run.run();
run.run();
}
return previous == Boolean.TRUE; return previous == Boolean.TRUE;
}, TaskType.ABORT)); }, TaskType.ABORT));
return this; return this;
@ -185,9 +176,7 @@ public class TaskBuilder extends Metadatable {
public TaskBuilder abortIfNull(final Runnable run) { public TaskBuilder abortIfNull(final Runnable run) {
tasks.add(RunnableTask.adapt((Task<Boolean, Object>) previous -> { tasks.add(RunnableTask.adapt((Task<Boolean, Object>) previous -> {
if (previous == null) { if (previous == null) run.run();
run.run();
}
return previous == null; return previous == null;
}, TaskType.ABORT)); }, TaskType.ABORT));
return this; return this;
@ -195,9 +184,7 @@ public class TaskBuilder extends Metadatable {
public TaskBuilder abortIfEqual(final Runnable run, final Object other) { public TaskBuilder abortIfEqual(final Runnable run, final Object other) {
tasks.add(RunnableTask.adapt((Task<Boolean, Object>) previous -> { tasks.add(RunnableTask.adapt((Task<Boolean, Object>) previous -> {
if (Objects.equals(previous, other)) { if (Objects.equals(previous, other)) run.run();
run.run();
}
return Objects.equals(previous, other); return Objects.equals(previous, other);
}, TaskType.ABORT)); }, TaskType.ABORT));
return this; return this;
@ -205,9 +192,7 @@ public class TaskBuilder extends Metadatable {
public TaskBuilder abortIfNotEqual(final Runnable run, final Object other) { public TaskBuilder abortIfNotEqual(final Runnable run, final Object other) {
tasks.add(RunnableTask.adapt((Task<Boolean, Object>) previous -> { tasks.add(RunnableTask.adapt((Task<Boolean, Object>) previous -> {
if (!Objects.equals(previous, other)) { if (!Objects.equals(previous, other)) run.run();
run.run();
}
return !Objects.equals(previous, other); return !Objects.equals(previous, other);
}, TaskType.ABORT)); }, TaskType.ABORT));
return this; return this;
@ -329,15 +314,6 @@ public class TaskBuilder extends Metadatable {
} }
} }
} }
private enum TaskType {
SYNC,
ASYNC,
SYNC_PARALLEL,
ASYNC_PARALLEL,
SYNC_WHEN_FREE,
DELAY,
ABORT
}
public static final class TaskAbortException extends RuntimeException { public static final class TaskAbortException extends RuntimeException {
@Override @Override
@ -346,6 +322,13 @@ public class TaskBuilder extends Metadatable {
} }
} }
private FaweQueue queue;
private long last;
private long start;
private Object asyncWaitLock = new Object();
private Object syncWaitLock = new Object();
private boolean finished;
private static abstract class RunnableTask<T> extends RunnableVal<T> { private static abstract class RunnableTask<T> extends RunnableVal<T> {
public final TaskType type; public final TaskType type;
private boolean aborted; private boolean aborted;
@ -354,6 +337,14 @@ public class TaskBuilder extends Metadatable {
this.type = type; this.type = type;
} }
public void abortNextTasks() {
this.aborted = true;
}
public boolean isAborted() {
return aborted;
}
public static RunnableTask adapt(final Task task, TaskType type) { public static RunnableTask adapt(final Task task, TaskType type) {
return new RunnableTask(type) { return new RunnableTask(type) {
@Override @Override
@ -396,14 +387,6 @@ public class TaskBuilder extends Metadatable {
}; };
} }
public void abortNextTasks() {
this.aborted = true;
}
public boolean isAborted() {
return aborted;
}
public abstract T exec(Object previous); public abstract T exec(Object previous);
@Override @Override
@ -418,6 +401,13 @@ public class TaskBuilder extends Metadatable {
super(type); super(type);
} }
@Override
public Object exec(Object previous) {
return previous;
}
public abstract int delay(Object previous);
public static RunnableDelayedTask adapt(final DelayedTask task) { public static RunnableDelayedTask adapt(final DelayedTask task) {
return new RunnableDelayedTask(TaskType.DELAY) { return new RunnableDelayedTask(TaskType.DELAY) {
@Override @Override
@ -435,13 +425,6 @@ public class TaskBuilder extends Metadatable {
} }
}; };
} }
@Override
public Object exec(Object previous) {
return previous;
}
public abstract int delay(Object previous);
} }
public static abstract class SplitTask extends RunnableTask { public static abstract class SplitTask extends RunnableTask {
@ -503,9 +486,7 @@ public class TaskBuilder extends Metadatable {
try { try {
if (!finished) { if (!finished) {
synchronized (asyncWaitLock) { synchronized (asyncWaitLock) {
while (!waitingAsync) { while (!waitingAsync) asyncWaitLock.wait(1);
asyncWaitLock.wait(1);
}
asyncWaitLock.notifyAll(); asyncWaitLock.notifyAll();
} }
waitingSync = true; waitingSync = true;
@ -530,9 +511,7 @@ public class TaskBuilder extends Metadatable {
if (now - start > allocation) { if (now - start > allocation) {
try { try {
synchronized (syncWaitLock) { synchronized (syncWaitLock) {
while (!waitingSync) { while (!waitingSync) syncWaitLock.wait(1);
syncWaitLock.wait(1);
}
syncWaitLock.notifyAll(); syncWaitLock.notifyAll();
} }
waitingAsync = true; waitingAsync = true;
@ -547,4 +526,14 @@ public class TaskBuilder extends Metadatable {
} }
} }
} }
private enum TaskType {
SYNC,
ASYNC,
SYNC_PARALLEL,
ASYNC_PARALLEL,
SYNC_WHEN_FREE,
DELAY,
ABORT
}
} }

View File

@ -2,6 +2,7 @@ package com.boydti.fawe.util.terrain;
import java.util.Arrays; import java.util.Arrays;
import static com.boydti.fawe.util.MathMan.pairInt; import static com.boydti.fawe.util.MathMan.pairInt;
public final class Erosion { public final class Erosion {
@ -30,4 +31,5 @@ public final class Erosion {
} }
} }

View File

@ -20,12 +20,16 @@
package com.sk89q.jnbt; package com.sk89q.jnbt;
import com.boydti.fawe.jnbt.NBTStreamer; import com.boydti.fawe.jnbt.NBTStreamer;
import com.boydti.fawe.object.RunnableVal2;
import com.boydti.fawe.util.StringMan;
import java.io.Closeable; import java.io.Closeable;
import java.io.DataInput;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -80,7 +84,7 @@ public final class NBTInputStream implements Closeable {
* @return The map that was read. * @return The map that was read.
* @throws IOException if an I/O error occurs. * @throws IOException if an I/O error occurs.
*/ */
public NamedData<? extends Object> readNamedData() throws IOException { public NamedData readNamedData() throws IOException {
return readNamedData(0); return readNamedData(0);
} }
@ -98,7 +102,7 @@ public final class NBTInputStream implements Closeable {
private NamedData readNamedData(int depth) throws IOException { private NamedData readNamedData(int depth) throws IOException {
int type = is.readByte(); int type = is.readByte();
return new NamedData<>(readNamedTagName(type), readDataPayload(type, depth)); return new NamedData(readNamedTagName(type), readDataPayload(type, depth));
} }
public Tag readTag() throws IOException { public Tag readTag() throws IOException {
@ -607,7 +611,7 @@ public final class NBTInputStream implements Closeable {
@Override @Override
public void close() throws IOException { public void close() throws IOException {
if (is != null) { if (is instanceof AutoCloseable) {
try { try {
((AutoCloseable) is).close(); ((AutoCloseable) is).close();
} catch (Exception e) { } catch (Exception e) {

View File

@ -0,0 +1,482 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit;
import com.boydti.fawe.object.schematic.Schematic;
import com.boydti.fawe.util.MainUtil;
import com.sk89q.worldedit.command.ClipboardCommands;
import com.sk89q.worldedit.command.FlattenedClipboardTransform;
import com.sk89q.worldedit.command.SchematicCommands;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Countable;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.world.DataException;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* The clipboard remembers the state of a cuboid region.
*
* @deprecated This is slowly being replaced with {@link Clipboard}, which is
* far more versatile. Transforms are supported using affine
* transformations and full entity support is provided because
* the clipboard properly implements {@link Extent}. However,
* the new clipboard class is only available in WorldEdit 6.x and
* beyond. We intend on keeping this deprecated class in WorldEdit
* for an extended amount of time so there is no rush to
* switch (but new features will not be supported). To copy between
* a clipboard and a world (or between any two {@code Extent}s),
* one can use {@link ForwardExtentCopy}. See
* {@link ClipboardCommands} and {@link SchematicCommands} for
* more information.
*/
@Deprecated
public class CuboidClipboard {
/**
* An enum of possible flip directions.
*/
public enum FlipDirection {
NORTH_SOUTH(Direction.NORTH),
WEST_EAST(Direction.WEST),
UP_DOWN(Direction.UP),
;
private final Direction direction;
FlipDirection(Direction direction) {
this.direction = direction;
}
}
private BlockArrayClipboard clipboard;
private AffineTransform transform;
public BlockVector3 size;
/**
* Constructs the clipboard.
*
* @param size the dimensions of the clipboard (should be at least 1 on every dimension)
*/
public CuboidClipboard(BlockVector3 size) {
checkNotNull(size);
MainUtil.warnDeprecated(BlockArrayClipboard.class, ClipboardFormat.class);
this.size = size;
this.clipboard = this.init(BlockVector3.ZERO, BlockVector3.ZERO);
}
public CuboidClipboard(BlockArrayClipboard clipboard) {
this.clipboard = clipboard;
this.size = clipboard.getDimensions();
}
/**
* Constructs the clipboard.
*
* @param size the dimensions of the clipboard (should be at least 1 on every dimension)
* @param origin the origin point where the copy was made, which must be the
* {@link CuboidRegion#getMinimumPoint()} relative to the copy
*/
public CuboidClipboard(BlockVector3 size, BlockVector3 origin) {
checkNotNull(size);
checkNotNull(origin);
MainUtil.warnDeprecated(BlockArrayClipboard.class, ClipboardFormat.class);
this.size = size;
this.clipboard = init(BlockVector3.ZERO, origin);
}
/**
* Constructs the clipboard.
*
* @param size the dimensions of the clipboard (should be at least 1 on every dimension)
* @param origin the origin point where the copy was made, which must be the
* {@link CuboidRegion#getMinimumPoint()} relative to the copy
* @param offset the offset from the minimum point of the copy where the user was
*/
public CuboidClipboard(BlockVector3 size, BlockVector3 origin, BlockVector3 offset) {
checkNotNull(size);
checkNotNull(origin);
checkNotNull(offset);
MainUtil.warnDeprecated(BlockArrayClipboard.class, ClipboardFormat.class);
this.size = size;
this.clipboard = this.init(offset, origin);
}
/* ------------------------------------------------------------------------------------------------------------- */
private BlockArrayClipboard init(BlockVector3 offset, BlockVector3 min) {
BlockVector3 origin = min.subtract(offset);
CuboidRegion region = new CuboidRegion(min, min.add(size).subtract(BlockVector3.ONE));
BlockArrayClipboard clipboard = new BlockArrayClipboard(region);
clipboard.setOrigin(origin);
return clipboard;
}
/* ------------------------------------------------------------------------------------------------------------- */
public BaseBlock getBlock(BlockVector3 position) {
return getBlock(position.getBlockX(), position.getBlockY(), position.getBlockZ());
}
public BaseBlock getBlock(int x, int y, int z) {
// return adapt(clipboard.IMP.getBlock(x, y, z));
return clipboard.IMP.getBlock(x, y, z);
}
public BaseBlock getLazyBlock(BlockVector3 position) {
return getBlock(position);
}
public void setBlock(BlockVector3 location, BaseBlock block) {
setBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ(), block);
}
public boolean setBlock(int x, int y, int z, BaseBlock block) {
return setBlock(x, y, z, block);
}
public boolean setBlock(int x, int y, int z, BlockState block) {
return clipboard.IMP.setBlock(x, y, z, block);
}
/**
* Get the width (X-direction) of the clipboard.
*
* @return width
*/
public int getWidth() {
return size.getBlockX();
}
/**
* Get the length (Z-direction) of the clipboard.
*
* @return length
*/
public int getLength() {
return size.getBlockZ();
}
/**
* Get the height (Y-direction) of the clipboard.
*
* @return height
*/
public int getHeight() {
return size.getBlockY();
}
/**
* Rotate the clipboard in 2D. It can only rotate by angles divisible by 90.
*
* @param angle in degrees
*/
@SuppressWarnings("deprecation")
public void rotate2D(int angle) {
AffineTransform newTransform = new AffineTransform().rotateY(-angle);
this.transform = transform == null ? newTransform : newTransform.combine(transform);
}
/**
* Flip the clipboard.
*
* @param dir direction to flip
*/
public void flip(FlipDirection dir) {
flip(dir, false);
}
/**
* Flip the clipboard.
*
* @param dir direction to flip
* @param aroundPlayer flip the offset around the player
*/
@SuppressWarnings("deprecation")
public void flip(FlipDirection dir, boolean aroundPlayer) {
checkNotNull(dir);
Direction direction = dir.direction;
AffineTransform newTransform = new AffineTransform().scale(direction.toVector().abs().multiply(-2).add(1, 1, 1));
this.transform = transform == null ? newTransform : newTransform.combine(transform);
}
/**
* Copies blocks to the clipboard.
*
* @param editSession the EditSession from which to take the blocks
*/
public void copy(EditSession editSession) {
for (int x = 0; x < size.getBlockX(); ++x) {
for (int y = 0; y < size.getBlockY(); ++y) {
for (int z = 0; z < size.getBlockZ(); ++z) {
setBlock(x, y, z, editSession.getBlock(BlockVector3.at(x, y, z).add(getOrigin())));
}
}
}
}
/**
* Copies blocks to the clipboard.
*
* @param editSession The EditSession from which to take the blocks
* @param region A region that further constrains which blocks to take.
*/
public void copy(EditSession editSession, Region region) {
for (int x = 0; x < size.getBlockX(); ++x) {
for (int y = 0; y < size.getBlockY(); ++y) {
for (int z = 0; z < size.getBlockZ(); ++z) {
final BlockVector3 pt = BlockVector3.at(x, y, z).add(getOrigin());
if (region.contains(pt)) {
setBlock(x, y, z, editSession.getBlock(pt));
} else {
setBlock(x, y, z, (BlockState)null);
}
}
}
}
}
/**
* Paste the clipboard at the given location using the given {@code EditSession}.
* <p>
* <p>This method blocks the server/game until the entire clipboard is
* pasted. In the future, {@link ForwardExtentCopy} will be recommended,
* which, if combined with the proposed operation scheduler framework,
* will not freeze the game/server.</p>
*
* @param editSession the EditSession to which blocks are to be copied to
* @param newOrigin the new origin point (must correspond to the minimum point of the cuboid)
* @param noAir true to not copy air blocks in the source
* @throws MaxChangedBlocksException thrown if too many blocks were changed
*/
public void paste(EditSession editSession, BlockVector3 newOrigin, boolean noAir) throws MaxChangedBlocksException {
paste(editSession, newOrigin, noAir, false);
}
/**
* Paste the clipboard at the given location using the given {@code EditSession}.
* <p>
* <p>This method blocks the server/game until the entire clipboard is
* pasted. In the future, {@link ForwardExtentCopy} will be recommended,
* which, if combined with the proposed operation scheduler framework,
* will not freeze the game/server.</p>
*
* @param editSession the EditSession to which blocks are to be copied to
* @param newOrigin the new origin point (must correspond to the minimum point of the cuboid)
* @param noAir true to not copy air blocks in the source
* @param entities true to copy entities
* @throws MaxChangedBlocksException thrown if too many blocks were changed
*/
public void paste(EditSession editSession, BlockVector3 newOrigin, boolean noAir, boolean entities) throws MaxChangedBlocksException {
new Schematic(clipboard).paste(editSession, newOrigin, false, !noAir, entities, transform);
editSession.flushQueue();
}
/**
* Paste the clipboard at the given location using the given {@code EditSession}.
* <p>
* <p>This method blocks the server/game until the entire clipboard is
* pasted. In the future, {@link ForwardExtentCopy} will be recommended,
* which, if combined with the proposed operation scheduler framework,
* will not freeze the game/server.</p>
*
* @param editSession the EditSession to which blocks are to be copied to
* @param newOrigin the new origin point (must correspond to the minimum point of the cuboid)
* @param noAir true to not copy air blocks in the source
* @throws MaxChangedBlocksException thrown if too many blocks were changed
*/
public void place(EditSession editSession, BlockVector3 newOrigin, boolean noAir) throws MaxChangedBlocksException {
paste(editSession, newOrigin, noAir, false);
}
/**
* Get the block at the given position.
* <p>
* <p>If the position is out of bounds, air will be returned.</p>
*
* @param position the point, relative to the origin of the copy (0, 0, 0) and not to the actual copy origin
* @return air, if this block was outside the (non-cuboid) selection while copying
* @throws ArrayIndexOutOfBoundsException if the position is outside the bounds of the CuboidClipboard
* @deprecated use {@link #getBlock(Vector)} instead
*/
@Deprecated
public BaseBlock getPoint(BlockVector3 position) throws ArrayIndexOutOfBoundsException {
final BaseBlock block = getBlock(position);
if (block == null) {
return BlockTypes.AIR.getDefaultState().toBaseBlock();
}
return block;
}
/**
* Get the origin point, which corresponds to where the copy was
* originally copied from. The origin is the lowest possible X, Y, and
* Z components of the cuboid region that was copied.
*
* @return the origin
*/
public BlockVector3 getOrigin() {
return clipboard.getMinimumPoint();
}
/**
* Set the origin point, which corresponds to where the copy was
* originally copied from. The origin is the lowest possible X, Y, and
* Z components of the cuboid region that was copied.
*
* @param origin the origin to set
*/
public void setOrigin(BlockVector3 origin) {
checkNotNull(origin);
setOriginAndOffset(getOffset(), origin);
}
public void setOriginAndOffset(BlockVector3 offset, BlockVector3 min) {
BlockVector3 origin = min.subtract(offset);
CuboidRegion region = new CuboidRegion(min, min.add(size).subtract(BlockVector3.ONE));
clipboard.setRegion(region);
clipboard.setOrigin(origin);
}
/**
* Get the offset of the player to the clipboard's minimum point
* (minimum X, Y, Z coordinates).
* <p>
* <p>The offset is inverse (multiplied by -1).</p>
*
* @return the offset the offset
*/
public BlockVector3 getOffset() {
BlockVector3 min = clipboard.getMinimumPoint();
BlockVector3 origin = clipboard.getOrigin();
BlockVector3 offset = min.subtract(origin);
return offset;
}
/**
* Set the offset of the player to the clipboard's minimum point
* (minimum X, Y, Z coordinates).
* <p>
* <p>The offset is inverse (multiplied by -1).</p>
*
* @param offset the new offset
*/
public void setOffset(BlockVector3 offset) {
checkNotNull(offset);
setOriginAndOffset(offset, getOrigin());
}
/**
* Get the dimensions of the clipboard.
*
* @return the dimensions, where (1, 1, 1) is 1 wide, 1 across, 1 deep
*/
public BlockVector3 getSize() {
return size;
}
/**
* Saves the clipboard data to a .schematic-format file.
*
* @param path the path to the file to save
* @throws IOException thrown on I/O error
* @throws DataException thrown on error writing the data for other reasons
* @deprecated use {@link ClipboardFormat#SCHEMATIC}
*/
@Deprecated
public void saveSchematic(File path) throws IOException, DataException {
checkNotNull(path);
if (transform != null && !transform.isIdentity()) {
final FlattenedClipboardTransform result = FlattenedClipboardTransform.transform(clipboard, transform);
BlockArrayClipboard target = new BlockArrayClipboard(result.getTransformedRegion(), UUID.randomUUID());
target.setOrigin(clipboard.getOrigin());
Operations.completeLegacy(result.copyTo(target));
this.clipboard = target;
}
new Schematic(clipboard).save(path, BuiltInClipboardFormat.SPONGE_SCHEMATIC);
}
/**
* Load a .schematic file into a clipboard.
*
* @param path the path to the file to load
* @return a clipboard
* @throws IOException thrown on I/O error
* @throws DataException thrown on error writing the data for other reasons
* @deprecated use {@link ClipboardFormat#SCHEMATIC}
*/
@Deprecated
public static CuboidClipboard loadSchematic(File path) throws DataException, IOException {
checkNotNull(path);
return new CuboidClipboard((BlockVector3) BuiltInClipboardFormat.MCEDIT_SCHEMATIC.load(path).getClipboard());
}
/**
* Get the block distribution inside a clipboard.
*
* @return a block distribution
*/
public List<Countable<Integer>> getBlockDistribution() {
List<Countable<Integer>> distribution = new ArrayList<>();
List<Countable<BlockState>> distr = clipboard.getBlockDistributionWithData(clipboard.getRegion());
for (Countable<BlockState> item : distr) {
BlockStateHolder state = item.getID();
int[] legacyId = LegacyMapper.getInstance().getLegacyFromBlock(state.toImmutableState());
if (legacyId[0] != 0) distribution.add(new Countable<>(legacyId[0], item.getAmount()));
}
return distribution;
}
/**
* Get the block distribution inside a clipboard with data values.
*
* @return a block distribution
*/
public List<Countable<BaseBlock>> getBlockDistributionWithData() {
List<Countable<BaseBlock>> distribution = new ArrayList<>();
List<Countable<BlockState>> distr = clipboard.getBlockDistributionWithData(clipboard.getRegion());
for (Countable<BlockState> item : distr) {
distribution.add(new Countable<>(item.getID().toBaseBlock(), item.getAmount()));
}
return distribution;
}
}

View File

@ -151,7 +151,6 @@ import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.*; import com.sk89q.worldedit.world.block.*;
import com.sk89q.worldedit.world.weather.WeatherType; import com.sk89q.worldedit.world.weather.WeatherType;
import net.royawesome.jlibnoise.module.modifier.Abs;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -424,7 +423,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
public void resetLimit() { public void resetLimit() {
this.limit.set(this.originalLimit); this.limit.set(this.originalLimit);
ExtentTraverser<ProcessedWEExtent> find = new ExtentTraverser<>(extent).find(ProcessedWEExtent.class); ExtentTraverser<ProcessedWEExtent> find = new ExtentTraverser(extent).find(ProcessedWEExtent.class);
if (find != null && find.get() != null) { if (find != null && find.get() != null) {
find.get().setLimit(this.limit); find.get().setLimit(this.limit);
} }
@ -463,7 +462,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* @return FaweRegionExtent (may be null) * @return FaweRegionExtent (may be null)
*/ */
public FaweRegionExtent getRegionExtent() { public FaweRegionExtent getRegionExtent() {
ExtentTraverser<FaweRegionExtent> traverser = new ExtentTraverser<>(this.extent).find(FaweRegionExtent.class); ExtentTraverser<FaweRegionExtent> traverser = new ExtentTraverser(this.extent).find(FaweRegionExtent.class);
return traverser == null ? null : traverser.get(); return traverser == null ? null : traverser.get();
} }
@ -495,12 +494,12 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
} }
public boolean cancel() { public boolean cancel() {
ExtentTraverser<AbstractDelegateExtent> traverser = new ExtentTraverser<>(this.extent); ExtentTraverser traverser = new ExtentTraverser(this.extent);
NullExtent nullExtent = new NullExtent(world, BBC.WORLDEDIT_CANCEL_REASON_MANUAL); NullExtent nullExtent = new NullExtent(world, BBC.WORLDEDIT_CANCEL_REASON_MANUAL);
while (traverser != null) { while (traverser != null) {
ExtentTraverser<AbstractDelegateExtent> next = traverser.next(); ExtentTraverser next = traverser.next();
Extent get = traverser.get(); Extent get = traverser.get();
if (get != null && !(get instanceof NullExtent)) { if (get instanceof AbstractDelegateExtent && !(get instanceof NullExtent)) {
traverser.setNext(nullExtent); traverser.setNext(nullExtent);
} }
traverser = next; traverser = next;
@ -739,7 +738,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* @return mask, may be null * @return mask, may be null
*/ */
public Mask getMask() { public Mask getMask() {
ExtentTraverser<MaskingExtent> maskingExtent = new ExtentTraverser<>(this.extent).find(MaskingExtent.class); ExtentTraverser<MaskingExtent> maskingExtent = new ExtentTraverser(this.extent).find(MaskingExtent.class);
return maskingExtent != null ? maskingExtent.get().getMask() : null; return maskingExtent != null ? maskingExtent.get().getMask() : null;
} }
@ -749,16 +748,16 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* @return mask, may be null * @return mask, may be null
*/ */
public Mask getSourceMask() { public Mask getSourceMask() {
ExtentTraverser<SourceMaskExtent> maskingExtent = new ExtentTraverser<>(this.extent).find(SourceMaskExtent.class); ExtentTraverser<SourceMaskExtent> maskingExtent = new ExtentTraverser(this.extent).find(SourceMaskExtent.class);
return maskingExtent != null ? maskingExtent.get().getMask() : null; return maskingExtent != null ? maskingExtent.get().getMask() : null;
} }
public void addTransform(ResettableExtent transform) { public void addTransform(ResettableExtent transform) {
wrapped = true; wrapped = true;
if (transform == null) { if (transform == null) {
ExtentTraverser<ResettableExtent> traverser = new ExtentTraverser<>(this.extent).find(ResettableExtent.class); ExtentTraverser<AbstractDelegateExtent> traverser = new ExtentTraverser(this.extent).find(ResettableExtent.class);
AbstractDelegateExtent next = extent; AbstractDelegateExtent next = extent;
while (traverser != null && traverser.get() != null) { while (traverser != null && traverser.get() instanceof ResettableExtent) {
traverser = traverser.next(); traverser = traverser.next();
next = traverser.get(); next = traverser.get();
} }
@ -770,9 +769,9 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
} }
public @Nullable ResettableExtent getTransform() { public @Nullable ResettableExtent getTransform() {
ExtentTraverser<ResettableExtent> traverser = new ExtentTraverser<>(this.extent).find(ResettableExtent.class); ExtentTraverser<AbstractDelegateExtent> traverser = new ExtentTraverser(this.extent).find(ResettableExtent.class);
if (traverser != null) { if (traverser != null) {
return traverser.get(); return (ResettableExtent) traverser.get();
} }
return null; return null;
} }
@ -788,7 +787,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
} else { } else {
new MaskTraverser(mask).reset(this); new MaskTraverser(mask).reset(this);
} }
ExtentTraverser<SourceMaskExtent> maskingExtent = new ExtentTraverser<>(this.extent).find(SourceMaskExtent.class); ExtentTraverser<SourceMaskExtent> maskingExtent = new ExtentTraverser(this.extent).find(SourceMaskExtent.class);
if (maskingExtent != null && maskingExtent.get() != null) { if (maskingExtent != null && maskingExtent.get() != null) {
Mask oldMask = maskingExtent.get().getMask(); Mask oldMask = maskingExtent.get().getMask();
if (oldMask instanceof ResettableMask) { if (oldMask instanceof ResettableMask) {
@ -827,7 +826,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
} else { } else {
new MaskTraverser(mask).reset(this); new MaskTraverser(mask).reset(this);
} }
ExtentTraverser<MaskingExtent> maskingExtent = new ExtentTraverser<>(this.extent).find(MaskingExtent.class); ExtentTraverser<MaskingExtent> maskingExtent = new ExtentTraverser(this.extent).find(MaskingExtent.class);
if (maskingExtent != null && maskingExtent.get() != null) { if (maskingExtent != null && maskingExtent.get() != null) {
Mask oldMask = maskingExtent.get().getMask(); Mask oldMask = maskingExtent.get().getMask();
if (oldMask instanceof ResettableMask) { if (oldMask instanceof ResettableMask) {
@ -845,13 +844,13 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
* @return the survival simulation extent * @return the survival simulation extent
*/ */
public SurvivalModeExtent getSurvivalExtent() { public SurvivalModeExtent getSurvivalExtent() {
ExtentTraverser<SurvivalModeExtent> survivalExtent = new ExtentTraverser<>(this.extent).find(SurvivalModeExtent.class); ExtentTraverser<SurvivalModeExtent> survivalExtent = new ExtentTraverser(this.extent).find(SurvivalModeExtent.class);
if (survivalExtent != null) { if (survivalExtent != null) {
return survivalExtent.get(); return survivalExtent.get();
} else { } else {
AbstractDelegateExtent extent = this.extent; AbstractDelegateExtent extent = this.extent;
SurvivalModeExtent survival = new SurvivalModeExtent(extent.getExtent(), getWorld()); SurvivalModeExtent survival = new SurvivalModeExtent(extent.getExtent(), getWorld());
new ExtentTraverser<>(extent).setNext(survival); new ExtentTraverser(extent).setNext(survival);
return survival; return survival;
} }
} }
@ -878,21 +877,21 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
if (history == null) { if (history == null) {
return; return;
} }
ExtentTraverser<HistoryExtent> traverseHistory = new ExtentTraverser<>(this.extent).find(HistoryExtent.class); ExtentTraverser traverseHistory = new ExtentTraverser(this.extent).find(HistoryExtent.class);
if (disableHistory) { if (disableHistory) {
if (traverseHistory != null && traverseHistory.exists()) { if (traverseHistory != null && traverseHistory.exists()) {
ExtentTraverser<HistoryExtent> beforeHistory = traverseHistory.previous(); ExtentTraverser beforeHistory = traverseHistory.previous();
ExtentTraverser<HistoryExtent> afterHistory = traverseHistory.next(); ExtentTraverser afterHistory = traverseHistory.next();
if (beforeHistory != null && beforeHistory.exists()) { if (beforeHistory != null && beforeHistory.exists()) {
beforeHistory.setNext(afterHistory.get()); beforeHistory.setNext(afterHistory.get());
} else { } else {
extent = afterHistory.get(); extent = (AbstractDelegateExtent) afterHistory.get();
} }
} }
} else if (traverseHistory == null || !traverseHistory.exists()) { } else if (traverseHistory == null || !traverseHistory.exists()) {
ExtentTraverser<AbstractDelegateExtent> traverseBypass = new ExtentTraverser<>(this.extent).find(bypassHistory); ExtentTraverser traverseBypass = new ExtentTraverser(this.extent).find(bypassHistory);
if (traverseBypass != null) { if (traverseBypass != null) {
ExtentTraverser<AbstractDelegateExtent> beforeHistory = traverseBypass.previous(); ExtentTraverser beforeHistory = traverseBypass.previous();
beforeHistory.setNext(history); beforeHistory.setNext(history);
} }
} }
@ -951,7 +950,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
if (changeSet instanceof BlockBagChangeSet) { if (changeSet instanceof BlockBagChangeSet) {
missingBlocks = ((BlockBagChangeSet) changeSet).popMissing(); missingBlocks = ((BlockBagChangeSet) changeSet).popMissing();
} else { } else {
ExtentTraverser<BlockBagExtent> find = new ExtentTraverser<>(extent).find(BlockBagExtent.class); ExtentTraverser<BlockBagExtent> find = new ExtentTraverser(extent).find(BlockBagExtent.class);
if (find != null && find.get() != null) { if (find != null && find.get() != null) {
missingBlocks = find.get().popMissing(); missingBlocks = find.get().popMissing();
} else { } else {
@ -1411,7 +1410,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
if (used.MAX_FAILS > 0) { if (used.MAX_FAILS > 0) {
if (used.MAX_CHANGES > 0 || used.MAX_ENTITIES > 0) { if (used.MAX_CHANGES > 0 || used.MAX_ENTITIES > 0) {
BBC.WORLDEDIT_SOME_FAILS.send(player, used.MAX_FAILS); BBC.WORLDEDIT_SOME_FAILS.send(player, used.MAX_FAILS);
} else if (new ExtentTraverser<>(this).findAndGet(FaweRegionExtent.class) != null){ } else if (new ExtentTraverser(this).findAndGet(FaweRegionExtent.class) != null){
BBC.WORLDEDIT_CANCEL_REASON_OUTSIDE_REGION.send(player); BBC.WORLDEDIT_CANCEL_REASON_OUTSIDE_REGION.send(player);
} else { } else {
BBC.WORLDEDIT_CANCEL_REASON_OUTSIDE_LEVEL.send(player); BBC.WORLDEDIT_CANCEL_REASON_OUTSIDE_LEVEL.send(player);
@ -3359,7 +3358,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
} }
public Set<BlockVector3> getHollowed(final Set<BlockVector3> vset) { public Set<BlockVector3> getHollowed(final Set<BlockVector3> vset) {
final Set<BlockVector3> returnset = new LocalBlockVectorSet(); final Set returnset = new LocalBlockVectorSet();
final LocalBlockVectorSet newset = new LocalBlockVectorSet(); final LocalBlockVectorSet newset = new LocalBlockVectorSet();
newset.addAll(vset); newset.addAll(vset);
for (final BlockVector3 v : newset) { for (final BlockVector3 v : newset) {

View File

@ -33,9 +33,12 @@ 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 static com.google.common.base.Preconditions.checkNotNull;
/** /**
* Helper class to 'bake' a transform into a clipboard. * Helper class to 'bake' a transform into a clipboard.
* * <p>
* <p>This class needs a better name and may need to be made more generic.</p> * <p>This class needs a better name and may need to be made more generic.</p>
* *
* @see Clipboard * @see Clipboard
@ -91,10 +94,10 @@ public class FlattenedClipboardTransform {
Vector3 newMinimum = corners[0]; Vector3 newMinimum = corners[0];
Vector3 newMaximum = corners[0]; Vector3 newMaximum = corners[0];
for (int i = 1; i < corners.length; i++) { for (int i = 1; i < corners.length; i++) {
newMinimum = newMinimum.getMinimum(corners[i]); Vector3 cbv = corners[i];
newMaximum = newMaximum.getMaximum(corners[i]); newMinimum = newMinimum.getMinimum(cbv);
newMaximum = newMaximum.getMaximum(cbv);
} }
// After transformation, the points may not really sit on a block, // After transformation, the points may not really sit on a block,
@ -130,4 +133,5 @@ public class FlattenedClipboardTransform {
return new FlattenedClipboardTransform(original, transform); return new FlattenedClipboardTransform(original, transform);
} }
} }

View File

@ -31,6 +31,7 @@ import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.minecraft.util.commands.Logging; import com.sk89q.minecraft.util.commands.Logging;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
@ -43,16 +44,17 @@ import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.visitor.RegionVisitor; import com.sk89q.worldedit.function.visitor.RegionVisitor;
import com.sk89q.worldedit.internal.annotation.Selection; import com.sk89q.worldedit.internal.annotation.Selection;
import com.sk89q.worldedit.internal.expression.ExpressionException; import com.sk89q.worldedit.internal.expression.ExpressionException;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
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;
import com.sk89q.worldedit.util.command.binding.Switch; import com.sk89q.worldedit.util.command.binding.Switch;
import com.sk89q.worldedit.util.command.binding.Text; import com.sk89q.worldedit.util.command.binding.Text;
import com.sk89q.worldedit.util.command.parametric.Optional; import com.sk89q.worldedit.util.command.parametric.Optional;
import com.sk89q.worldedit.util.command.parametric.ParameterException;
import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockType;
@ -61,9 +63,7 @@ import java.awt.image.BufferedImage;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import static com.sk89q.minecraft.util.commands.Logging.LogMode.ALL; import static com.sk89q.minecraft.util.commands.Logging.LogMode.*;
import static com.sk89q.minecraft.util.commands.Logging.LogMode.PLACEMENT;
import static com.sk89q.minecraft.util.commands.Logging.LogMode.POSITION;
/** /**
@ -82,14 +82,14 @@ public class GenerationCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/caves" }, aliases = {"/caves"},
usage = "[size=8] [freq=40] [rarity=7] [minY=8] [maxY=127] [sysFreq=1] [sysRarity=25] [pocketRarity=0] [pocketMin=0] [pocketMax=3]", usage = "[size=8] [freq=40] [rarity=7] [minY=8] [maxY=127] [sysFreq=1] [sysRarity=25] [pocketRarity=0] [pocketMin=0] [pocketMax=3]",
desc = "Generates caves", desc = "Generates caves",
help = "Generates a cave network" help = "Generates a cave network"
) )
@CommandPermissions("worldedit.generation.caves") @CommandPermissions("worldedit.generation.caves")
@Logging(PLACEMENT) @Logging(PLACEMENT)
public void caves(FawePlayer fp, LocalSession session, EditSession editSession, @Selection Region region, @Optional("8") int size, @Optional("40") int frequency, @Optional("7") int rarity, @Optional("8") int minY, @Optional("127") int maxY, @Optional("1") int systemFrequency, @Optional("25") int individualRarity, @Optional("0") int pocketChance, @Optional("0") int pocketMin, @Optional("3") int pocketMax, CommandContext context) throws WorldEditException { public void caves(FawePlayer fp, LocalSession session, EditSession editSession, @Selection Region region, @Optional("8") int size, @Optional("40") int frequency, @Optional("7") int rarity, @Optional("8") int minY, @Optional("127") int maxY, @Optional("1") int systemFrequency, @Optional("25") int individualRarity, @Optional("0") int pocketChance, @Optional("0") int pocketMin, @Optional("3") int pocketMax, CommandContext context) throws WorldEditException, ParameterException {
fp.checkConfirmationRegion(() -> { fp.checkConfirmationRegion(() -> {
CavesGen gen = new CavesGen(size, frequency, rarity, minY, maxY, systemFrequency, individualRarity, pocketChance, pocketMin, pocketMax); CavesGen gen = new CavesGen(size, frequency, rarity, minY, maxY, systemFrequency, individualRarity, pocketChance, pocketMin, pocketMax);
editSession.generate(region, gen); editSession.generate(region, gen);
@ -100,7 +100,7 @@ public class GenerationCommands extends MethodCommands {
// public void addOre(Mask mask, Pattern material, int size, int frequency, int rarity, int minY, int maxY) throws WorldEditException { // public void addOre(Mask mask, Pattern material, int size, int frequency, int rarity, int minY, int maxY) throws WorldEditException {
@Command( @Command(
aliases = { "/ores" }, aliases = {"/ores"},
desc = "Generates ores", desc = "Generates ores",
help = "Generates ores", help = "Generates ores",
min = 1, min = 1,
@ -108,7 +108,7 @@ public class GenerationCommands extends MethodCommands {
) )
@CommandPermissions("worldedit.generation.ore") @CommandPermissions("worldedit.generation.ore")
@Logging(PLACEMENT) @Logging(PLACEMENT)
public void ores(FawePlayer player, LocalSession session, EditSession editSession, @Selection Region region, Mask mask, CommandContext context) throws WorldEditException { public void ores(FawePlayer player, LocalSession session, EditSession editSession, @Selection Region region, Mask mask, CommandContext context) throws WorldEditException, ParameterException {
player.checkConfirmationRegion(() -> { player.checkConfirmationRegion(() -> {
editSession.addOres(region, mask); editSession.addOres(region, mask);
BBC.VISITOR_BLOCK.send(player, editSession.getBlockChangeCount()); BBC.VISITOR_BLOCK.send(player, editSession.getBlockChangeCount());
@ -116,7 +116,7 @@ public class GenerationCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/image", "/img" }, aliases = {"/image", "/img"},
desc = "Generate an image", desc = "Generate an image",
usage = "<imgur> [randomize=true] [complexity=100] [dimensions=100,100]", usage = "<imgur> [randomize=true] [complexity=100] [dimensions=100,100]",
min = 1, min = 1,
@ -124,7 +124,7 @@ public class GenerationCommands extends MethodCommands {
) )
@CommandPermissions("worldedit.generation.image") @CommandPermissions("worldedit.generation.image")
@Logging(PLACEMENT) @Logging(PLACEMENT)
public void image(Player player, LocalSession session, EditSession editSession, String arg, @Optional("true") boolean randomize, @Optional("100") int threshold, @Optional BlockVector2 dimensions) throws WorldEditException, IOException { public void image(Player player, LocalSession session, EditSession editSession, String arg, @Optional("true") boolean randomize, @Optional("100") int threshold, @Optional BlockVector2 dimensions) throws WorldEditException, ParameterException, IOException {
TextureUtil tu = Fawe.get().getCachedTextureUtil(randomize, 0, threshold); TextureUtil tu = Fawe.get().getCachedTextureUtil(randomize, 0, threshold);
URL url = new URL(arg); URL url = new URL(arg);
if (!url.getHost().equalsIgnoreCase("i.imgur.com") && !url.getHost().equalsIgnoreCase("empcraft.com")) { if (!url.getHost().equalsIgnoreCase("i.imgur.com") && !url.getHost().equalsIgnoreCase("empcraft.com")) {
@ -174,7 +174,7 @@ public class GenerationCommands extends MethodCommands {
) )
@CommandPermissions("worldedit.generation.ore") @CommandPermissions("worldedit.generation.ore")
@Logging(PLACEMENT) @Logging(PLACEMENT)
public void ore(FawePlayer player, LocalSession session, EditSession editSession, @Selection Region region, Mask mask, Pattern material, @Range(min = 0) int size, int freq, @Range(min = 0, max = 100) int rarity, @Range(min = 0, max = 255) int minY, @Range(min = 0, max = 255) int maxY, CommandContext context) throws WorldEditException { public void ore(FawePlayer player, LocalSession session, EditSession editSession, @Selection Region region, Mask mask, Pattern material, @Range(min = 0) int size, int freq, @Range(min = 0, max = 100) int rarity, @Range(min = 0, max = 255) int minY, @Range(min = 0, max = 255) int maxY, CommandContext context) throws WorldEditException, ParameterException {
player.checkConfirmationRegion(() -> { player.checkConfirmationRegion(() -> {
editSession.addOre(region, mask, material, size, freq, rarity, minY, maxY); editSession.addOre(region, mask, material, size, freq, rarity, minY, maxY);
BBC.VISITOR_BLOCK.send(player, editSession.getBlockChangeCount()); BBC.VISITOR_BLOCK.send(player, editSession.getBlockChangeCount());
@ -182,7 +182,7 @@ public class GenerationCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/hcyl" }, aliases = {"/hcyl"},
usage = "<pattern> <radius>[,<radius>] [height]", usage = "<pattern> <radius>[,<radius>] [height]",
desc = "Generates a hollow cylinder.", desc = "Generates a hollow cylinder.",
help = help =
@ -195,18 +195,18 @@ public class GenerationCommands extends MethodCommands {
) )
@CommandPermissions("worldedit.generation.cylinder") @CommandPermissions("worldedit.generation.cylinder")
@Logging(PLACEMENT) @Logging(PLACEMENT)
public void hcyl(FawePlayer fp, Player player, LocalSession session, EditSession editSession, Pattern pattern, BlockVector2 radius, @Optional("1") int height, @Range(min = 1) @Optional("1") double thickness, CommandContext context) throws WorldEditException { public void hcyl(FawePlayer fp, Player player, LocalSession session, EditSession editSession, Pattern pattern, BlockVector2 radius, @Optional("1") int height, @Range(min = 1) @Optional("1") double thickness, CommandContext context) throws WorldEditException, ParameterException {
int max = Math.max(radius.getBlockX(), radius.getBlockZ()); double max = MathMan.max(radius.getBlockX(), radius.getBlockZ());
worldEdit.checkMaxRadius(max); worldEdit.checkMaxRadius(max);
BlockVector3 pos = session.getPlacementPosition(player); BlockVector3 pos = session.getPlacementPosition(player);
fp.checkConfirmationRadius(() -> { fp.checkConfirmationRadius(() -> {
int affected = editSession.makeHollowCylinder(pos, pattern, radius.getX(), radius.getZ(), Math.min(256, height), thickness - 1); int affected = editSession.makeHollowCylinder(pos, pattern, radius.getX(), radius.getZ(), Math.min(256, height), thickness - 1);
BBC.VISITOR_BLOCK.send(fp, affected); BBC.VISITOR_BLOCK.send(fp, affected);
}, getArguments(context), max, context); }, getArguments(context), (int) max, context);
} }
@Command( @Command(
aliases = { "/cyl" }, aliases = {"/cyl"},
usage = "<pattern> <radius>[,<radius>] [height]", usage = "<pattern> <radius>[,<radius>] [height]",
flags = "h", flags = "h",
desc = "Generates a cylinder.", desc = "Generates a cylinder.",
@ -220,18 +220,18 @@ public class GenerationCommands extends MethodCommands {
) )
@CommandPermissions("worldedit.generation.cylinder") @CommandPermissions("worldedit.generation.cylinder")
@Logging(PLACEMENT) @Logging(PLACEMENT)
public void cyl(FawePlayer fp, Player player, LocalSession session, EditSession editSession, Pattern pattern, BlockVector2 radius, @Optional("1") int height, @Switch('h') boolean hollow, CommandContext context) throws WorldEditException { public void cyl(FawePlayer fp, Player player, LocalSession session, EditSession editSession, Pattern pattern, BlockVector2 radius, @Optional("1") int height, @Switch('h') boolean hollow, CommandContext context) throws WorldEditException, ParameterException {
int max = Math.max(radius.getBlockX(), radius.getBlockZ()); double max = MathMan.max(radius.getBlockX(), radius.getBlockZ());
worldEdit.checkMaxRadius(max); worldEdit.checkMaxRadius(max);
BlockVector3 pos = session.getPlacementPosition(player); BlockVector3 pos = session.getPlacementPosition(player);
fp.checkConfirmationRadius(() -> { fp.checkConfirmationRadius(() -> {
int affected = editSession.makeCylinder(pos, pattern, radius.getX(), radius.getZ(), Math.min(256, height), !hollow); int affected = editSession.makeCylinder(pos, pattern, radius.getX(), radius.getZ(), Math.min(256, height), !hollow);
BBC.VISITOR_BLOCK.send(fp, affected); BBC.VISITOR_BLOCK.send(fp, affected);
}, getArguments(context), max, context); }, getArguments(context), (int) max, context);
} }
@Command( @Command(
aliases = { "/hsphere" }, aliases = {"/hsphere"},
usage = "<pattern> <radius>[,<radius>,<radius>] [raised?]", usage = "<pattern> <radius>[,<radius>,<radius>] [raised?]",
desc = "Generates a hollow sphere.", desc = "Generates a hollow sphere.",
help = help =
@ -244,12 +244,12 @@ public class GenerationCommands extends MethodCommands {
) )
@CommandPermissions("worldedit.generation.sphere") @CommandPermissions("worldedit.generation.sphere")
@Logging(PLACEMENT) @Logging(PLACEMENT)
public void hsphere(FawePlayer fp, Player player, LocalSession session, EditSession editSession, Pattern pattern, BlockVector3 radius, @Optional("false") boolean raised, CommandContext context) throws WorldEditException { public void hsphere(FawePlayer fp, Player player, LocalSession session, EditSession editSession, Pattern pattern, BlockVector3 radius, @Optional("false") boolean raised, CommandContext context) throws WorldEditException, ParameterException {
sphere(fp, player, session, editSession, pattern, radius, raised, true, context); sphere(fp, player, session, editSession, pattern, radius, raised, true, context);
} }
@Command( @Command(
aliases = { "/sphere" }, aliases = {"/sphere"},
usage = "<pattern> <radius>[,<radius>,<radius>] [raised?]", usage = "<pattern> <radius>[,<radius>,<radius>] [raised?]",
flags = "h", flags = "h",
desc = "Generates a filled sphere.", desc = "Generates a filled sphere.",
@ -263,7 +263,7 @@ public class GenerationCommands extends MethodCommands {
) )
@CommandPermissions("worldedit.generation.sphere") @CommandPermissions("worldedit.generation.sphere")
@Logging(PLACEMENT) @Logging(PLACEMENT)
public void sphere(FawePlayer fp, Player player, LocalSession session, EditSession editSession, Pattern pattern, BlockVector3 radius, @Optional("false") boolean raised, @Switch('h') boolean hollow, CommandContext context) throws WorldEditException { public void sphere(FawePlayer fp, Player player, LocalSession session, EditSession editSession, Pattern pattern, BlockVector3 radius, @Optional("false") boolean raised, @Switch('h') boolean hollow, CommandContext context) throws WorldEditException, ParameterException {
double max = MathMan.max(radius.getBlockX(), radius.getBlockY(), radius.getBlockZ()); double max = MathMan.max(radius.getBlockX(), radius.getBlockY(), radius.getBlockZ());
worldEdit.checkMaxRadius(max); worldEdit.checkMaxRadius(max);
BlockVector3 pos = session.getPlacementPosition(player); BlockVector3 pos = session.getPlacementPosition(player);
@ -276,37 +276,36 @@ public class GenerationCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "forestgen" }, aliases = {"forestgen"},
usage = "[size] [type] [density]", usage = "[size] [tree-type] [density]",
desc = "Generate a forest", desc = "Generate a forest",
min = 0, min = 0,
max = 3 max = 3
) )
@CommandPermissions("worldedit.generation.forest") @CommandPermissions("worldedit.generation.forest")
@Logging(POSITION) @Logging(POSITION)
public void forestGen(Player player, LocalSession session, EditSession editSession, @Optional("10") int size, @SuppressWarnings("deprecation")
@Optional("tree") TreeType type, @Optional("5") @Range(min = 0, max = 100) double density) throws WorldEditException { public void forestGen(Player player, LocalSession session, EditSession editSession, @Optional("10") int size, @Optional("tree") TreeType type, @Optional("5") @Range(min = 0, max = 100) double density) throws WorldEditException, ParameterException {
density = density / 100; density = density / 100;
int affected = editSession.makeForest(session.getPlacementPosition(player), size, density, type); int affected = editSession.makeForest(session.getPlacementPosition(player), size, density, type);
player.print(affected + " trees created."); player.print(BBC.getPrefix() + affected + " trees created.");
} }
@Command( @Command(
aliases = { "pumpkins" }, aliases = {"pumpkins"},
usage = "[size]", usage = "[size=10]",
desc = "Generate pumpkin patches", desc = "Generate pumpkin patches",
min = 0, max = 2
max = 1
) )
@CommandPermissions("worldedit.generation.pumpkins") @CommandPermissions("worldedit.generation.pumpkins")
@Logging(POSITION) @Logging(POSITION)
public void pumpkins(Player player, LocalSession session, EditSession editSession, @Optional("10") int apothem) throws WorldEditException { public void pumpkins(Player player, LocalSession session, EditSession editSession, @Optional("10") int apothem) throws WorldEditException, ParameterException {
int affected = editSession.makePumpkinPatches(session.getPlacementPosition(player), apothem); int affected = editSession.makePumpkinPatches(session.getPlacementPosition(player), apothem);
BBC.COMMAND_PUMPKIN.send(player, affected); BBC.COMMAND_PUMPKIN.send(player, affected);
} }
@Command( @Command(
aliases = { "/hpyramid" }, aliases = {"/hpyramid"},
usage = "<pattern> <size>", usage = "<pattern> <size>",
desc = "Generate a hollow pyramid", desc = "Generate a hollow pyramid",
min = 2, min = 2,
@ -314,12 +313,12 @@ public class GenerationCommands extends MethodCommands {
) )
@CommandPermissions("worldedit.generation.pyramid") @CommandPermissions("worldedit.generation.pyramid")
@Logging(PLACEMENT) @Logging(PLACEMENT)
public void hollowPyramid(FawePlayer fp, Player player, LocalSession session, EditSession editSession, Pattern pattern, @Range(min = 1) int size, CommandContext context) throws WorldEditException { public void hollowPyramid(FawePlayer fp, Player player, LocalSession session, EditSession editSession, Pattern pattern, @Range(min = 1) int size, CommandContext context) throws WorldEditException, ParameterException {
pyramid(fp, player, session, editSession, pattern, size, true, context); pyramid(fp, player, session, editSession, pattern, size, true, context);
} }
@Command( @Command(
aliases = { "/pyramid" }, aliases = {"/pyramid"},
usage = "<pattern> <size>", usage = "<pattern> <size>",
flags = "h", flags = "h",
desc = "Generate a filled pyramid", desc = "Generate a filled pyramid",
@ -328,7 +327,7 @@ public class GenerationCommands extends MethodCommands {
) )
@CommandPermissions("worldedit.generation.pyramid") @CommandPermissions("worldedit.generation.pyramid")
@Logging(PLACEMENT) @Logging(PLACEMENT)
public void pyramid(FawePlayer fp, Player player, LocalSession session, EditSession editSession, Pattern pattern, @Range(min = 1) int size, @Switch('h') boolean hollow, CommandContext context) throws WorldEditException { public void pyramid(FawePlayer fp, Player player, LocalSession session, EditSession editSession, Pattern pattern, @Range(min = 1) int size, @Switch('h') boolean hollow, CommandContext context) throws WorldEditException, ParameterException {
BlockVector3 pos = session.getPlacementPosition(player); BlockVector3 pos = session.getPlacementPosition(player);
worldEdit.checkMaxRadius(size); worldEdit.checkMaxRadius(size);
fp.checkConfirmationRadius(() -> { fp.checkConfirmationRadius(() -> {

View File

@ -50,8 +50,6 @@ import java.io.File;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import static com.google.common.base.Preconditions.checkNotNull;
/** /**
* Commands to undo, redo, and clear history. * Commands to undo, redo, and clear history.
*/ */
@ -65,11 +63,10 @@ public class HistoryCommands extends MethodCommands {
*/ */
public HistoryCommands(WorldEdit worldEdit) { public HistoryCommands(WorldEdit worldEdit) {
super(worldEdit); super(worldEdit);
checkNotNull(worldEdit);
} }
@Command( @Command(
aliases = { "/frb", "frb", "fawerollback", "/fawerollback", "/rollback" }, aliases = {"/frb", "frb", "fawerollback", "/fawerollback", "/rollback"},
usage = "<user=Empire92> <radius=5> <time=3d4h>", usage = "<user=Empire92> <radius=5> <time=3d4h>",
desc = "Undo a specific edit. " + desc = "Undo a specific edit. " +
" - The time uses s, m, h, d, y.\n" + " - The time uses s, m, h, d, y.\n" +
@ -83,7 +80,8 @@ public class HistoryCommands extends MethodCommands {
BBC.SETTING_DISABLE.send(player, "history.use-database (Import with /frb #import )"); BBC.SETTING_DISABLE.send(player, "history.use-database (Import with /frb #import )");
return; return;
} }
if (user.charAt(0) == '#') { switch (user.charAt(0)) {
case '#': {
if (user.equals("#import")) { if (user.equals("#import")) {
if (!player.hasPermission("fawe.rollback.import")) { if (!player.hasPermission("fawe.rollback.import")) {
BBC.NO_PERM.send(player, "fawe.rollback.import"); BBC.NO_PERM.send(player, "fawe.rollback.import");
@ -143,13 +141,14 @@ public class HistoryCommands extends MethodCommands {
DiskStorageHistory file = new DiskStorageHistory(world, uuid, index); DiskStorageHistory file = new DiskStorageHistory(world, uuid, index);
if (file.getBDFile().exists()) { if (file.getBDFile().exists()) {
if (restore) file.redo(FawePlayer.wrap(player)); if (restore) file.redo(FawePlayer.wrap(player));
else file.undo(FawePlayer.wrap(player), null); else file.undo(FawePlayer.wrap(player));
BBC.ROLLBACK_ELEMENT.send(player, Fawe.imp().getWorldName(world) + "/" + user + "-" + index); BBC.ROLLBACK_ELEMENT.send(player, Fawe.imp().getWorldName(world) + "/" + user + "-" + index);
} else { } else {
BBC.TOOL_INSPECT_INFO_FOOTER.send(player, 0); BBC.TOOL_INSPECT_INFO_FOOTER.send(player, 0);
} }
return; return;
} }
}
UUID other = Fawe.imp().getUUID(user); UUID other = Fawe.imp().getUUID(user);
if (other == null) { if (other == null) {
BBC.PLAYER_NOT_FOUND.send(player, user); BBC.PLAYER_NOT_FOUND.send(player, user);
@ -197,11 +196,16 @@ public class HistoryCommands extends MethodCommands {
BBC.ROLLBACK_ELEMENT.send(player, Fawe.imp().getWorldName(edit.getWorld()) + "/" + user + "-" + edit.getIndex()); BBC.ROLLBACK_ELEMENT.send(player, Fawe.imp().getWorldName(edit.getWorld()) + "/" + user + "-" + edit.getIndex());
count.incrementAndGet(); count.incrementAndGet();
} }
}, () -> BBC.TOOL_INSPECT_INFO_FOOTER.send(player, count), true, restore); }, new Runnable() {
@Override
public void run() {
BBC.TOOL_INSPECT_INFO_FOOTER.send(player, count);
}
}, true, restore);
} }
@Command( @Command(
aliases = { "/fawerestore", "/frestore" }, aliases = {"/fawerestore", "/frestore"},
usage = "<user=Empire92|*> <radius=5> <time=3d4h>", usage = "<user=Empire92|*> <radius=5> <time=3d4h>",
desc = "Redo a specific edit. " + desc = "Redo a specific edit. " +
" - The time uses s, m, h, d, y.\n" + " - The time uses s, m, h, d, y.\n" +
@ -215,30 +219,30 @@ public class HistoryCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/undo", "undo" }, aliases = {"/undo", "undo"},
usage = "[times] [player]", usage = "[times] [player]",
desc = "Undoes the last action", desc = "Undoes the last action",
min = 0, min = 0,
max = 2 max = 2
) )
@CommandPermissions("worldedit.history.undo") @CommandPermissions("worldedit.history.undo")
public void undo(Player player, LocalSession session, CommandContext args) throws WorldEditException { public void undo(Player player, LocalSession session, CommandContext context) throws WorldEditException {
if (session.hasFastMode()) { if (session.hasFastMode()) {
BBC.COMMAND_UNDO_DISABLED.send(player); BBC.COMMAND_UNDO_DISABLED.send(player);
return; return;
} }
int times = Math.max(1, args.getInteger(0, 1)); int times = Math.max(1, context.getInteger(0, 1));
FawePlayer.wrap(player).checkConfirmation(() -> { FawePlayer.wrap(player).checkConfirmation(() -> {
EditSession undone = null; EditSession undone = null;
int i = 0; int i = 0;
for (; i < times; ++i) { for (; i < times; ++i) {
if (args.argsLength() < 2) { if (context.argsLength() < 2) {
undone = session.undo(session.getBlockBag(player), player); undone = session.undo(session.getBlockBag(player), player);
} else { } else {
player.checkPermission("worldedit.history.undo.other"); player.checkPermission("worldedit.history.undo.other");
LocalSession sess = worldEdit.getSessionManager().findByName(args.getString(1)); LocalSession sess = worldEdit.getSessionManager().findByName(context.getString(1));
if (sess == null) { if (sess == null) {
BBC.COMMAND_HISTORY_OTHER_ERROR.send(player, args.getString(1)); BBC.COMMAND_HISTORY_OTHER_ERROR.send(player, context.getString(1));
break; break;
} }
undone = sess.undo(session.getBlockBag(player), player); undone = sess.undo(session.getBlockBag(player), player);
@ -253,11 +257,11 @@ public class HistoryCommands extends MethodCommands {
if (undone == null) { if (undone == null) {
BBC.COMMAND_UNDO_ERROR.send(player); BBC.COMMAND_UNDO_ERROR.send(player);
} }
}, getArguments(args), times, 50, args); }, getArguments(context), times, 50, context);
} }
@Command( @Command(
aliases = { "/redo", "redo" }, aliases = {"/redo", "redo"},
usage = "[times] [player]", usage = "[times] [player]",
desc = "Redoes the last action (from history)", desc = "Redoes the last action (from history)",
min = 0, min = 0,
@ -265,7 +269,6 @@ public class HistoryCommands extends MethodCommands {
) )
@CommandPermissions("worldedit.history.redo") @CommandPermissions("worldedit.history.redo")
public void redo(Player player, LocalSession session, CommandContext args) throws WorldEditException { public void redo(Player player, LocalSession session, CommandContext args) throws WorldEditException {
int times = Math.max(1, args.getInteger(0, 1)); int times = Math.max(1, args.getInteger(0, 1));
EditSession redone = null; EditSession redone = null;
@ -295,7 +298,7 @@ public class HistoryCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/clearhistory", "clearhistory" }, aliases = {"/clearhistory", "clearhistory"},
usage = "", usage = "",
desc = "Clear your history", desc = "Clear your history",
min = 0, min = 0,

View File

@ -65,12 +65,12 @@ public class NavigationCommands {
) )
@CommandPermissions("worldedit.navigation.unstuck") @CommandPermissions("worldedit.navigation.unstuck")
public void unstuck(Player player) throws WorldEditException { public void unstuck(Player player) throws WorldEditException {
BBC.UNSTUCK.send(player);
player.findFreePosition(); player.findFreePosition();
BBC.UNSTUCK.send(player);
} }
@Command( @Command(
aliases = { "ascend", "asc" }, aliases = {"ascend", "asc"},
usage = "[# of levels]", usage = "[# of levels]",
desc = "Go up a floor", desc = "Go up a floor",
min = 0, min = 0,
@ -97,7 +97,7 @@ public class NavigationCommands {
} }
@Command( @Command(
aliases = { "descend", "desc" }, aliases = {"descend", "desc"},
usage = "[# of floors]", usage = "[# of floors]",
desc = "Go down a floor", desc = "Go down a floor",
min = 0, min = 0,
@ -124,7 +124,7 @@ public class NavigationCommands {
} }
@Command( @Command(
aliases = { "ceil" }, aliases = {"ceil"},
usage = "[clearance]", usage = "[clearance]",
desc = "Go to the celing", desc = "Go to the celing",
flags = "fg", flags = "fg",
@ -147,7 +147,7 @@ public class NavigationCommands {
} }
@Command( @Command(
aliases = { "thru" }, aliases = {"thru"},
usage = "", usage = "",
desc = "Passthrough walls", desc = "Passthrough walls",
min = 0, min = 0,
@ -163,7 +163,7 @@ public class NavigationCommands {
} }
@Command( @Command(
aliases = { "jumpto", "j" }, aliases = {"jumpto", "j"},
usage = "[world,x,y,z]", usage = "[world,x,y,z]",
desc = "Teleport to a location\n" + desc = "Teleport to a location\n" +
"Flags:" + "Flags:" +
@ -197,8 +197,8 @@ public class NavigationCommands {
} }
@Command( @Command(
aliases = { "up" }, aliases = {"up"},
usage = "<block>", usage = "<number>",
desc = "Go upwards some distance", desc = "Go upwards some distance",
flags = "fg", flags = "fg",
min = 1, min = 1,
@ -231,4 +231,6 @@ public class NavigationCommands {
return forceGlass || (config.navigationUseGlass && !forceFlight); return forceGlass || (config.navigationUseGlass && !forceFlight);
} }
} }

View File

@ -220,7 +220,7 @@ public class RegionCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/line" }, aliases = {"/line"},
usage = "<pattern> [thickness]", usage = "<pattern> [thickness]",
desc = "Draws a line segment between cuboid selection corners", desc = "Draws a line segment between cuboid selection corners",
help = help =
@ -241,7 +241,7 @@ public class RegionCommands extends MethodCommands {
@Switch('h') boolean shell) throws WorldEditException { @Switch('h') boolean shell) throws WorldEditException {
if (!(region instanceof CuboidRegion)) { if (!(region instanceof CuboidRegion)) {
player.printError("//line only works with cuboid selections"); player.printError(BBC.getPrefix() + "//line only works with cuboid selections");
return; return;
} }
@ -254,7 +254,7 @@ public class RegionCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/curve", "/spline" }, aliases = {"/curve", "/spline"},
usage = "<pattern> [thickness]", usage = "<pattern> [thickness]",
desc = "Draws a spline through selected points", desc = "Draws a spline through selected points",
help = help =
@ -275,7 +275,7 @@ public class RegionCommands extends MethodCommands {
@Switch('h') boolean shell, @Switch('h') boolean shell,
CommandContext context) throws WorldEditException { CommandContext context) throws WorldEditException {
if (!(region instanceof ConvexPolyhedralRegion)) { if (!(region instanceof ConvexPolyhedralRegion)) {
player.toWorldEditPlayer().printError("//curve only works with convex polyhedral selections"); player.sendMessage(BBC.getPrefix() + "//curve only works with convex polyhedral selections");
return; return;
} }
worldEdit.checkMaxRadius(thickness); worldEdit.checkMaxRadius(thickness);
@ -336,7 +336,7 @@ public class RegionCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/overlay" }, aliases = {"/overlay"},
usage = "<pattern>", usage = "<pattern>",
desc = "Set a block on top of blocks in the region", desc = "Set a block on top of blocks in the region",
min = 1, min = 1,
@ -386,7 +386,7 @@ public class RegionCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/center", "/middle" }, aliases = {"/center", "/middle"},
usage = "<pattern>", usage = "<pattern>",
desc = "Set the center block(s)", desc = "Set the center block(s)",
min = 1, min = 1,
@ -400,7 +400,7 @@ public class RegionCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/naturalize" }, aliases = {"/naturalize"},
usage = "", usage = "",
desc = "3 layers of dirt on top then rock below", desc = "3 layers of dirt on top then rock below",
min = 0, min = 0,
@ -416,7 +416,7 @@ public class RegionCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/walls" }, aliases = {"/walls"},
usage = "<pattern>", usage = "<pattern>",
desc = "Build the four sides of the selection", desc = "Build the four sides of the selection",
min = 1, min = 1,
@ -432,7 +432,7 @@ public class RegionCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/faces", "/outline" }, aliases = {"/faces", "/outline"},
usage = "<pattern>", usage = "<pattern>",
desc = "Build the walls, ceiling, and floor of a selection", desc = "Build the walls, ceiling, and floor of a selection",
min = 1, min = 1,
@ -458,7 +458,7 @@ public class RegionCommands extends MethodCommands {
min = 0, min = 0,
max = 2 max = 2
) )
@CommandPermissions("worldedit.region.smooth") @CommandPermissions("worldedit.region.smoothsnow")
@Logging(REGION) @Logging(REGION)
public void smooth(FawePlayer player, EditSession editSession, @Selection Region region, @Optional("1") int iterations, @Optional Mask mask, @Switch('s') boolean snow, CommandContext context) throws WorldEditException { public void smooth(FawePlayer player, EditSession editSession, @Selection Region region, @Optional("1") int iterations, @Optional Mask mask, @Switch('s') boolean snow, CommandContext context) throws WorldEditException {
BlockVector3 min = region.getMinimumPoint(); BlockVector3 min = region.getMinimumPoint();
@ -514,23 +514,23 @@ public class RegionCommands extends MethodCommands {
@Command( @Command(
aliases = { "/move" }, aliases = {"/move"},
usage = "[count] [direction] [leave-id]", usage = "[count] [direction] [leave-id]",
flags = "sabe", flags = "sbea",
desc = "Move the contents of the selection", desc = "Move the contents of the selection",
help = help =
"Moves the contents of the selection.\n" + "Moves the contents of the selection.\n" +
"The -s flag shifts the selection to the target location.\n" + "The -s flag shifts the selection to the target location.\n" +
" -b also copies biomes\n" + " -b also copies biomes\n" +
" -e ignores entities\n" + " -e ignores entities\n" +
"The -a flag skips air blocks.\n" + " -a ignores air\n" +
"Optionally fills the old location with <leave-id>.", "Optionally fills the old location with <leave-id>.",
min = 0, min = 0,
max = 3 max = 3
) )
@CommandPermissions("worldedit.region.move") @CommandPermissions("worldedit.region.move")
@Logging(ORIENTATION_REGION) @Logging(ORIENTATION_REGION)
public void move(FawePlayer player, EditSession editSession, LocalSession session, public void move(FawePlayer player, LocalSession session, EditSession editSession,
@Selection Region region, @Selection Region region,
@Optional("1") @Range(min = 1) int count, @Optional("1") @Range(min = 1) int count,
@Optional(Direction.AIM) @Direction(includeDiagonals = true) BlockVector3 direction, @Optional(Direction.AIM) @Direction(includeDiagonals = true) BlockVector3 direction,
@ -550,7 +550,7 @@ public class RegionCommands extends MethodCommands {
session.getRegionSelector(player.getWorld()).learnChanges(); session.getRegionSelector(player.getWorld()).learnChanges();
session.getRegionSelector(player.getWorld()).explainRegionAdjust(player.getPlayer(), session); session.getRegionSelector(player.getWorld()).explainRegionAdjust(player.getPlayer(), session);
} catch (RegionOperationException e) { } catch (RegionOperationException e) {
player.toWorldEditPlayer().printError(e.getMessage()); player.sendMessage(BBC.getPrefix() + e.getMessage());
} }
} }
@ -583,7 +583,7 @@ public class RegionCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/stack" }, aliases = {"/stack"},
usage = "[count] [direction]", usage = "[count] [direction]",
flags = "sam", flags = "sam",
desc = "Repeat the contents of the selection", desc = "Repeat the contents of the selection",
@ -597,7 +597,7 @@ public class RegionCommands extends MethodCommands {
) )
@CommandPermissions("worldedit.region.stack") @CommandPermissions("worldedit.region.stack")
@Logging(ORIENTATION_REGION) @Logging(ORIENTATION_REGION)
public void stack(FawePlayer player, EditSession editSession, LocalSession session, public void stack(FawePlayer player, LocalSession session, EditSession editSession,
@Selection Region region, @Selection Region region,
@Optional("1") @Range(min = 1) int count, @Optional("1") @Range(min = 1) int count,
@Optional(Direction.AIM) @Direction(includeDiagonals = true) BlockVector3 direction, @Optional(Direction.AIM) @Direction(includeDiagonals = true) BlockVector3 direction,
@ -620,7 +620,7 @@ public class RegionCommands extends MethodCommands {
session.getRegionSelector(player.getWorld()).learnChanges(); session.getRegionSelector(player.getWorld()).learnChanges();
session.getRegionSelector(player.getWorld()).explainRegionAdjust(player.getPlayer(), session); session.getRegionSelector(player.getWorld()).explainRegionAdjust(player.getPlayer(), session);
} catch (RegionOperationException e) { } catch (RegionOperationException e) {
player.sendMessage(e.getMessage()); player.sendMessage(BBC.getPrefix() + e.getMessage());
} }
} }
@ -629,7 +629,7 @@ public class RegionCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/deform" }, aliases = {"/deform"},
usage = "<expression>", usage = "<expression>",
desc = "Deforms a selected region with an expression", desc = "Deforms a selected region with an expression",
help = help =
@ -647,10 +647,10 @@ public class RegionCommands extends MethodCommands {
@Selection Region region, @Selection Region region,
@Text String expression, @Text String expression,
@Switch('r') boolean useRawCoords, @Switch('r') boolean useRawCoords,
@Switch('o') boolean offset, CommandContext context) throws WorldEditException { @Switch('o') boolean offset,
CommandContext context) throws WorldEditException {
final Vector3 zero; final Vector3 zero;
Vector3 unit; Vector3 unit;
if (useRawCoords) { if (useRawCoords) {
zero = Vector3.ZERO; zero = Vector3.ZERO;
unit = Vector3.ONE; unit = Vector3.ONE;
@ -676,7 +676,7 @@ public class RegionCommands extends MethodCommands {
player.findFreePosition(); player.findFreePosition();
BBC.VISITOR_BLOCK.send(fp, affected); BBC.VISITOR_BLOCK.send(fp, affected);
} catch (ExpressionException e) { } catch (ExpressionException e) {
fp.sendMessage(e.getMessage()); fp.sendMessage(BBC.getPrefix() + e.getMessage());
} }
}, getArguments(context), region, context); }, getArguments(context), region, context);
} }
@ -727,7 +727,7 @@ public class RegionCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/hollow" }, aliases = {"/hollow"},
usage = "[<thickness>[ <pattern>]]", usage = "[<thickness>[ <pattern>]]",
desc = "Hollows out the object contained in this selection", desc = "Hollows out the object contained in this selection",
help = help =
@ -751,7 +751,7 @@ public class RegionCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/forest" }, aliases = {"/forest"},
usage = "[type] [density]", usage = "[type] [density]",
desc = "Make a forest within the region", desc = "Make a forest within the region",
min = 0, min = 0,
@ -766,7 +766,7 @@ public class RegionCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/flora" }, aliases = {"/flora"},
usage = "[density]", usage = "[density]",
desc = "Make flora within the region", desc = "Make flora within the region",
min = 0, min = 0,
@ -786,4 +786,5 @@ public class RegionCommands extends MethodCommands {
}, getArguments(context), region, context); }, getArguments(context), region, context);
} }
} }

View File

@ -29,22 +29,21 @@ import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
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.Capability; import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.CommandManager; import com.sk89q.worldedit.extension.platform.CommandManager;
import com.sk89q.worldedit.scripting.CraftScriptContext; import com.sk89q.worldedit.scripting.CraftScriptContext;
import com.sk89q.worldedit.scripting.CraftScriptEngine; import com.sk89q.worldedit.scripting.CraftScriptEngine;
import com.sk89q.worldedit.scripting.RhinoCraftScriptEngine; import com.sk89q.worldedit.scripting.RhinoCraftScriptEngine;
import com.sk89q.worldedit.session.request.Request;
import org.mozilla.javascript.NativeJavaObject; import org.mozilla.javascript.NativeJavaObject;
import javax.annotation.Nullable;
import javax.script.ScriptException; import javax.script.ScriptException;
import java.io.DataInputStream; import java.io.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.minecraft.util.commands.Logging.LogMode.ALL; import static com.sk89q.minecraft.util.commands.Logging.LogMode.ALL;
@ -62,7 +61,7 @@ public class ScriptingCommands {
* *
* @param worldEdit reference to WorldEdit * @param worldEdit reference to WorldEdit
*/ */
public ScriptingCommands(WorldEdit worldEdit) { public ScriptingCommands(final WorldEdit worldEdit) {
checkNotNull(worldEdit); checkNotNull(worldEdit);
this.worldEdit = worldEdit; this.worldEdit = worldEdit;
} }
@ -79,12 +78,16 @@ public class ScriptingCommands {
} }
public static <T> T runScript(Player player, File f, String[] args) throws WorldEditException { public static <T> T runScript(Player player, File f, String[] args) throws WorldEditException {
return runScript(player, f, args, null);
}
public static <T> T runScript(Actor actor, File f, String[] args, @Nullable Function<String, String> processor) throws WorldEditException {
String filename = f.getPath(); String filename = f.getPath();
int index = filename.lastIndexOf("."); int index = filename.lastIndexOf(".");
String ext = filename.substring(index + 1); String ext = filename.substring(index + 1, filename.length());
if (!ext.equalsIgnoreCase("js")) { if (!ext.equalsIgnoreCase("js")) {
player.printError("Only .js scripts are currently supported"); actor.printError(BBC.getPrefix() + "Only .js scripts are currently supported");
return null; return null;
} }
@ -97,63 +100,69 @@ public class ScriptingCommands {
file = WorldEdit.class.getResourceAsStream("craftscripts/" + filename); file = WorldEdit.class.getResourceAsStream("craftscripts/" + filename);
if (file == null) { if (file == null) {
player.printError("Script does not exist: " + filename); actor.printError(BBC.getPrefix() + "Script does not exist: " + filename);
return null; return null;
} }
} else { } else {
file = new FileInputStream(f); file = new FileInputStream(f);
} }
byte[] data; DataInputStream in = new DataInputStream(file);
try (DataInputStream in = new DataInputStream(file)) { byte[] data = new byte[in.available()];
data = new byte[in.available()];
in.readFully(data); in.readFully(data);
} in.close();
script = new String(data, 0, data.length, StandardCharsets.UTF_8); script = new String(data, 0, data.length, "utf-8");
} catch (IOException e) { } catch (IOException e) {
player.printError("Script read error: " + e.getMessage()); actor.printError(BBC.getPrefix() + "Script read error: " + e.getMessage());
return null; return null;
} }
WorldEdit worldEdit1 = WorldEdit.getInstance(); if (processor != null) {
LocalSession session = worldEdit1.getSessionManager().get(player); script = processor.apply(script);
}
CraftScriptEngine engine; WorldEdit worldEdit = WorldEdit.getInstance();
LocalSession session = worldEdit.getSessionManager().get(actor);
CraftScriptEngine engine = null;
Object result = null; Object result = null;
try { try {
engine = new RhinoCraftScriptEngine(); engine = new RhinoCraftScriptEngine();
} catch (NoClassDefFoundError e) { } catch (NoClassDefFoundError e) {
player.printError("Failed to find an installed script engine."); actor.printError("Failed to find an installed script engine.");
player.printError("Download: https://github.com/downloads/mozilla/rhino/rhino1_7R4.zip"); actor.printError("Download: https://github.com/downloads/mozilla/rhino/rhino1_7R4.zip");
player.printError("Extract: `js.jar` to `plugins` or `mods` directory`"); actor.printError("Extract: `js.jar` to `plugins` or `mods` directory`");
player.printError("More info: https://github.com/boy0001/CraftScripts/"); actor.printError("More info: https://github.com/boy0001/CraftScripts/");
return null; return null;
} }
engine.setTimeLimit(worldEdit1.getConfiguration().scriptTimeout); engine.setTimeLimit(worldEdit.getConfiguration().scriptTimeout);
CraftScriptContext scriptContext = new CraftScriptContext(worldEdit1, worldEdit1.getPlatformManager().queryCapability(Capability.USER_COMMANDS), Player player = actor instanceof Player ? (Player) actor : null;
worldEdit1.getConfiguration(), session, player, args); CraftScriptContext scriptContext = new CraftScriptContext(worldEdit, WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.USER_COMMANDS),
WorldEdit.getInstance().getConfiguration(), session, player, args);
Map<String, Object> vars = new HashMap<>(); Map<String, Object> vars = new HashMap<>();
vars.put("argv", args); vars.put("argv", args);
vars.put("context", scriptContext); vars.put("context", scriptContext);
vars.put("actor", player); vars.put("actor", actor);
vars.put("player", player); vars.put("player", player);
try { try {
result = engine.evaluate(script, filename, vars); result = engine.evaluate(script, filename, vars);
} catch (ScriptException e) { } catch (ScriptException e) {
e.printStackTrace(); e.printStackTrace();
player.printError(BBC.getPrefix() + "Failed to execute:"); actor.printError(BBC.getPrefix() + "Failed to execute:");
player.printRaw(e.getMessage()); actor.printRaw(e.getMessage());
} catch (NumberFormatException | WorldEditException e) { } catch (NumberFormatException e) {
throw e;
} catch (WorldEditException e) {
throw e; throw e;
} catch (Throwable e) { } catch (Throwable e) {
player.printError("Failed to execute (see console):"); actor.printError(BBC.getPrefix() + "Failed to execute (see console):");
player.printRaw(e.getClass().getCanonicalName()); actor.printRaw(e.getClass().getCanonicalName());
e.printStackTrace(); e.printStackTrace();
} }
if (result instanceof NativeJavaObject) { if (result instanceof NativeJavaObject) {
@ -162,19 +171,12 @@ public class ScriptingCommands {
return (T) result; return (T) result;
} }
@Command( @Command(aliases = {"cs"}, usage = "<filename> [args...]", desc = "Execute a CraftScript", min = 1, max = -1)
aliases = { "cs" },
usage = "<filename> [args...]",
desc = "Execute a CraftScript",
min = 1,
max = -1
)
@CommandPermissions("worldedit.scripting.execute") @CommandPermissions("worldedit.scripting.execute")
@Logging(ALL) @Logging(ALL)
public void execute(Player player, LocalSession session, CommandContext args) throws WorldEditException { public void execute(final Player player, final LocalSession session, final CommandContext args) throws WorldEditException {
final String[] scriptArgs = args.getSlice(1);
String[] scriptArgs = args.getSlice(1); final String name = args.getString(0);
String name = args.getString(0);
if (!player.hasPermission("worldedit.scripting.execute." + name)) { if (!player.hasPermission("worldedit.scripting.execute." + name)) {
BBC.SCRIPTING_NO_PERM.send(player); BBC.SCRIPTING_NO_PERM.send(player);
@ -183,8 +185,8 @@ public class ScriptingCommands {
session.setLastScript(name); session.setLastScript(name);
File dir = worldEdit.getWorkingDirectoryFile(worldEdit.getConfiguration().scriptsDir); final File dir = this.worldEdit.getWorkingDirectoryFile(this.worldEdit.getConfiguration().scriptsDir);
File f = worldEdit.getSafeOpenFile(player, dir, name, "js", "js"); final File f = this.worldEdit.getSafeOpenFile(player, dir, name, "js", "js");
try { try {
new RhinoCraftScriptEngine(); new RhinoCraftScriptEngine();
} catch (NoClassDefFoundError e) { } catch (NoClassDefFoundError e) {
@ -197,13 +199,7 @@ public class ScriptingCommands {
runScript(LocationMaskedPlayerWrapper.unwrap(player), f, scriptArgs); runScript(LocationMaskedPlayerWrapper.unwrap(player), f, scriptArgs);
} }
@Command( @Command(aliases = {".s"}, usage = "[args...]", desc = "Execute last CraftScript", min = 0, max = -1)
aliases = { ".s" },
usage = "[args...]",
desc = "Execute last CraftScript",
min = 0,
max = -1
)
@CommandPermissions("worldedit.scripting.execute") @CommandPermissions("worldedit.scripting.execute")
@Logging(ALL) @Logging(ALL)
public void executeLast(Player player, LocalSession session, CommandContext args) throws WorldEditException { public void executeLast(Player player, LocalSession session, CommandContext args) throws WorldEditException {
@ -220,11 +216,17 @@ public class ScriptingCommands {
return; return;
} }
String[] scriptArgs = args.getSlice(0); final String[] scriptArgs = args.getSlice(0);
File dir = worldEdit.getWorkingDirectoryFile(worldEdit.getConfiguration().scriptsDir); final File dir = this.worldEdit.getWorkingDirectoryFile(this.worldEdit.getConfiguration().scriptsDir);
File f = worldEdit.getSafeOpenFile(player, dir, lastScript, "js", "js"); final File f = this.worldEdit.getSafeOpenFile(player, dir, lastScript, "js", "js");
worldEdit.runScript(player, f, scriptArgs); try {
this.worldEdit.runScript(LocationMaskedPlayerWrapper.unwrap(player), f, scriptArgs);
} catch (final WorldEditException ex) {
BBC.SCRIPTING_ERROR.send(player);
} }
}
} }

View File

@ -94,7 +94,7 @@ public class SelectionCommands {
} }
@Command( @Command(
aliases = { "/pos1", "posa", "/1" }, aliases = {"/pos1", "posa", "/1"},
usage = "[coordinates]", usage = "[coordinates]",
desc = "Set position 1", desc = "Set position 1",
min = 0, min = 0,
@ -123,12 +123,11 @@ public class SelectionCommands {
return; return;
} }
session.getRegionSelector(player.getWorld()) session.getRegionSelector(player.getWorld()).explainPrimarySelection(player, session, pos);
.explainPrimarySelection(player, session, pos);
} }
@Command( @Command(
aliases = { "/pos2", "posb", "/2" }, aliases = {"/pos2", "posb", "/2"},
usage = "[coordinates]", usage = "[coordinates]",
desc = "Set position 2", desc = "Set position 2",
min = 0, min = 0,
@ -163,40 +162,38 @@ public class SelectionCommands {
} }
@Command( @Command(
aliases = { "/hpos1" }, aliases = {"/hpos1"},
usage = "", usage = "",
desc = "Set position 1 to targeted block", desc = "Set position 1 to targeted block",
min = 0, min = 0,
max = 0 max = 0
) )
@CommandPermissions("worldedit.selection.hpos") @CommandPermissions("worldedit.selection.hpos")
public void hpos1(Player player, LocalSession session) throws WorldEditException { public void hpos1(Player player, LocalSession session, CommandContext args) throws WorldEditException {
BlockVector3 pos = player.getBlockTrace(300).toBlockPoint();
Location pos = player.getBlockTrace(300);
if (pos != null) { if (pos != null) {
if (!session.getRegionSelector(player.getWorld()).selectPrimary(pos.toVector().toBlockPoint(), ActorSelectorLimits.forActor(player))) { if (!session.getRegionSelector(player.getWorld()).selectPrimary(pos, ActorSelectorLimits.forActor(player))) {
BBC.SELECTOR_ALREADY_SET.send(player); BBC.SELECTOR_ALREADY_SET.send(player);
return; return;
} }
session.getRegionSelector(player.getWorld()) session.getRegionSelector(player.getWorld())
.explainPrimarySelection(player, session, pos.toVector().toBlockPoint()); .explainPrimarySelection(player, session, pos);
} else { } else {
BBC.NO_BLOCK.send(player); BBC.NO_BLOCK.send(player);
} }
} }
@Command( @Command(
aliases = { "/hpos2" }, aliases = {"/hpos2"},
usage = "", usage = "",
desc = "Set position 2 to targeted block", desc = "Set position 2 to targeted block",
min = 0, min = 0,
max = 0 max = 0
) )
@CommandPermissions("worldedit.selection.hpos") @CommandPermissions("worldedit.selection.hpos")
public void hpos2(Player player, LocalSession session) throws WorldEditException { public void hpos2(Player player, LocalSession session, CommandContext args) throws WorldEditException {
BlockVector3 pos = player.getBlockTrace(300).toBlockPoint(); BlockVector3 pos = player.getBlockTrace(300).toBlockPoint();
if (pos != null) { if (pos != null) {
@ -213,7 +210,7 @@ public class SelectionCommands {
} }
@Command( @Command(
aliases = { "/chunk" }, aliases = {"/chunk"},
usage = "[x,z coordinates]", usage = "[x,z coordinates]",
flags = "sc", flags = "sc",
desc = "Set the selection to your current chunk.", desc = "Set the selection to your current chunk.",
@ -221,7 +218,7 @@ public class SelectionCommands {
"Set the selection to the chunk you are currently in.\n" + "Set the selection to the chunk you are currently in.\n" +
"With the -s flag, your current selection is expanded\n" + "With the -s flag, your current selection is expanded\n" +
"to encompass all chunks that are part of it.\n\n" + "to encompass all chunks that are part of it.\n\n" +
"Specifying coordinates will use those instead of your\n"+ "Specifying coordinates will use those instead of your\n" +
"current position. Use -c to specify chunk coordinates,\n" + "current position. Use -c to specify chunk coordinates,\n" +
"otherwise full coordinates will be implied.\n" + "otherwise full coordinates will be implied.\n" +
"(for example, the coordinates 5,5 are the same as -c 0,0)", "(for example, the coordinates 5,5 are the same as -c 0,0)",
@ -282,7 +279,7 @@ public class SelectionCommands {
} }
@Command( @Command(
aliases = { "/wand" }, aliases = {"/wand", "/w"},
usage = "", usage = "",
desc = "Get the wand object", desc = "Get the wand object",
min = 0, min = 0,
@ -290,7 +287,6 @@ public class SelectionCommands {
) )
@CommandPermissions("worldedit.wand") @CommandPermissions("worldedit.wand")
public void wand(Player player) throws WorldEditException { public void wand(Player player) throws WorldEditException {
player.giveItem(new BaseItemStack(ItemTypes.parse(we.getConfiguration().wandItem), 1)); player.giveItem(new BaseItemStack(ItemTypes.parse(we.getConfiguration().wandItem), 1));
BBC.SELECTION_WAND.send(player); BBC.SELECTION_WAND.send(player);
if (!FawePlayer.wrap(player).hasPermission("fawe.tips")) if (!FawePlayer.wrap(player).hasPermission("fawe.tips"))
@ -298,7 +294,7 @@ public class SelectionCommands {
} }
@Command( @Command(
aliases = { "toggleeditwand" }, aliases = {"toggleeditwand"},
usage = "", usage = "",
desc = "Toggle functionality of the edit wand", desc = "Toggle functionality of the edit wand",
min = 0, min = 0,
@ -317,7 +313,7 @@ public class SelectionCommands {
} }
@Command( @Command(
aliases = { "/expand" }, aliases = {"/expand"},
usage = "<amount> [reverse-amount] <direction>", usage = "<amount> [reverse-amount] <direction>",
desc = "Expand the selection area", desc = "Expand the selection area",
min = 1, min = 1,
@ -329,8 +325,7 @@ public class SelectionCommands {
// Special syntax (//expand vert) to expand the selection between // Special syntax (//expand vert) to expand the selection between
// sky and bedrock. // sky and bedrock.
if (args.getString(0).equalsIgnoreCase("vert") if (args.getString(0).equalsIgnoreCase("vert") || args.getString(0).equalsIgnoreCase("vertical")) {
|| args.getString(0).equalsIgnoreCase("vertical")) {
Region region = session.getSelection(player.getWorld()); Region region = session.getSelection(player.getWorld());
try { try {
int oldSize = region.getArea(); int oldSize = region.getArea();
@ -347,7 +342,6 @@ public class SelectionCommands {
return; return;
} }
List<BlockVector3> dirs = new ArrayList<>(); List<BlockVector3> dirs = new ArrayList<>();
int change = args.getInteger(0); int change = args.getInteger(0);
int reverseChange = 0; int reverseChange = 0;
@ -406,12 +400,11 @@ public class SelectionCommands {
int newSize = region.getArea(); int newSize = region.getArea();
session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session); session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session);
BBC.SELECTION_EXPAND.send(player, (newSize - oldSize)); BBC.SELECTION_EXPAND.send(player, (newSize - oldSize));
} }
@Command( @Command(
aliases = { "/contract" }, aliases = {"/contract"},
usage = "<amount> [reverse-amount] [direction]", usage = "<amount> [reverse-amount] [direction]",
desc = "Contract the selection area", desc = "Contract the selection area",
min = 1, min = 1,
@ -485,7 +478,7 @@ public class SelectionCommands {
} }
@Command( @Command(
aliases = { "/shift" }, aliases = {"/shift"},
usage = "<amount> [direction]", usage = "<amount> [direction]",
desc = "Shift the selection area", desc = "Shift the selection area",
min = 1, min = 1,
@ -519,7 +512,6 @@ public class SelectionCommands {
session.getRegionSelector(player.getWorld()).learnChanges(); session.getRegionSelector(player.getWorld()).learnChanges();
session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session); session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session);
BBC.SELECTION_SHIFT.send(player); BBC.SELECTION_SHIFT.send(player);
} catch (RegionOperationException e) { } catch (RegionOperationException e) {
player.printError(e.getMessage()); player.printError(e.getMessage());
@ -527,7 +519,7 @@ public class SelectionCommands {
} }
@Command( @Command(
aliases = { "/outset" }, aliases = {"/outset"},
usage = "<amount>", usage = "<amount>",
desc = "Outset the selection area", desc = "Outset the selection area",
help = help =
@ -550,7 +542,7 @@ public class SelectionCommands {
} }
@Command( @Command(
aliases = { "/inset" }, aliases = {"/inset"},
usage = "<amount>", usage = "<amount>",
desc = "Inset the selection area", desc = "Inset the selection area",
help = help =
@ -577,22 +569,22 @@ public class SelectionCommands {
int change = args.getInteger(0); int change = args.getInteger(0);
if (!args.hasFlag('h')) { if (!args.hasFlag('h')) {
changes.add((BlockVector3.UNIT_Y).multiply(change)); changes.add((BlockVector3.at(0, 1, 0)).multiply(change));
changes.add((BlockVector3.UNIT_MINUS_Y).multiply(change)); changes.add((BlockVector3.at(0, -1, 0)).multiply(change));
} }
if (!args.hasFlag('v')) { if (!args.hasFlag('v')) {
changes.add((BlockVector3.UNIT_X).multiply(change)); changes.add((BlockVector3.at(1, 0, 0)).multiply(change));
changes.add((BlockVector3.UNIT_MINUS_X).multiply(change)); changes.add((BlockVector3.at(-1, 0, 0)).multiply(change));
changes.add((BlockVector3.UNIT_Z).multiply(change)); changes.add((BlockVector3.at(0, 0, 1)).multiply(change));
changes.add((BlockVector3.UNIT_MINUS_Z).multiply(change)); changes.add((BlockVector3.at(0, 0, -1)).multiply(change));
} }
return changes.toArray(new BlockVector3[0]); return changes.toArray(new BlockVector3[0]);
} }
@Command( @Command(
aliases = { "/size" }, aliases = {"/size"},
flags = "c", flags = "c",
usage = "", usage = "",
desc = "Get information about the selection", desc = "Get information about the selection",
@ -600,9 +592,10 @@ public class SelectionCommands {
max = 0 max = 0
) )
@CommandPermissions("worldedit.selection.size") @CommandPermissions("worldedit.selection.size")
public void size(Player player, LocalSession session, CommandContext args) throws WorldEditException { public void size(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
if (args.hasFlag('c')) { if (args.hasFlag('c')) {
ClipboardHolder root = session.getClipboard(); ClipboardHolder root = session.getClipboard();
// Clipboard clipboard = holder.getClipboard();
int index = 0; int index = 0;
for (ClipboardHolder holder : root.getHolders()) { for (ClipboardHolder holder : root.getHolders()) {
Clipboard clipboard = holder.getClipboard(); Clipboard clipboard = holder.getClipboard();
@ -675,10 +668,10 @@ public class SelectionCommands {
@Command( @Command(
aliases = { "/count" }, aliases = {"/count"},
usage = "<mask>", usage = "<mask>",
flags = "d",
desc = "Counts the number of a certain type of block", desc = "Counts the number of a certain type of block",
flags = "d",
min = 1, min = 1,
max = 1 max = 1
) )
@ -689,25 +682,23 @@ public class SelectionCommands {
} }
@Command( @Command(
aliases = { "/distr" }, aliases = {"/distr"},
usage = "", usage = "",
desc = "Get the distribution of blocks in the selection", desc = "Get the distribution of blocks in the selection",
help = help =
"Gets the distribution of blocks in the selection.\n" + "Gets the distribution of blocks in the selection.\n" +
"The -c flag gets the distribution of your clipboard.\n" + "The -c flag gets the distribution of your clipboard.",
"The -d flag separates blocks by state", flags = "c",
flags = "cd",
min = 0, min = 0,
max = 0 max = 0
) )
@CommandPermissions("worldedit.analysis.distr") @CommandPermissions("worldedit.analysis.distr")
public void distr(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException, CommandException { public void distr(Player player, LocalSession session, EditSession editSession, @Switch('c') boolean useClipboard, @Switch('d') boolean useData) throws WorldEditException, CommandException {
int size; int size;
List<Countable> distributionData; List<Countable> distributionData;
boolean separateStates = args.hasFlag('d');
Region region; Region region;
if (args.hasFlag('c')) { if (useClipboard) {
// TODO multi clipboard distribution // TODO multi clipboard distribution
Clipboard clipboard = session.getClipboard().getClipboard(); Clipboard clipboard = session.getClipboard().getClipboard();
region = clipboard.getRegion(); region = clipboard.getRegion();
@ -715,14 +706,13 @@ public class SelectionCommands {
} else { } else {
region = session.getSelection(player.getWorld()); region = session.getSelection(player.getWorld());
} }
if (separateStates) { if (useData)
distributionData = (List) editSession.getBlockDistributionWithData(region); distributionData = (List) editSession.getBlockDistributionWithData(region);
} else { else
distributionData = (List) editSession.getBlockDistribution(region); distributionData = (List) editSession.getBlockDistribution(region);
}
size = session.getSelection(player.getWorld()).getArea(); size = session.getSelection(player.getWorld()).getArea();
if (distributionData.isEmpty()) { // *Should* always be false if (distributionData.size() <= 0) {
player.printError("No blocks counted."); player.printError("No blocks counted.");
return; return;
} }
@ -739,7 +729,7 @@ public class SelectionCommands {
} }
@Command( @Command(
aliases = { "/sel", ";", "/desel", "/deselect" }, aliases = {"/sel", ";", "/desel", "/deselect"},
flags = "d", flags = "d",
usage = "[cuboid|extend|poly|ellipsoid|sphere|cyl|convex]", usage = "[cuboid|extend|poly|ellipsoid|sphere|cyl|convex]",
desc = "Choose a region selector", desc = "Choose a region selector",
@ -848,4 +838,5 @@ public class SelectionCommands {
session.dispatchCUISelection(player); session.dispatchCUISelection(player);
} }
} }

View File

@ -56,7 +56,7 @@ public class SnapshotCommands {
} }
@Command( @Command(
aliases = { "list" }, aliases = {"list"},
usage = "[num]", usage = "[num]",
desc = "List snapshots", desc = "List snapshots",
min = 0, min = 0,
@ -81,7 +81,7 @@ public class SnapshotCommands {
BBC.SNAPSHOT_LIST_HEADER.send(player, player.getWorld().getName()); BBC.SNAPSHOT_LIST_HEADER.send(player, player.getWorld().getName());
for (byte i = 0; i < Math.min(num, snapshots.size()); i++) { for (byte i = 0; i < Math.min(num, snapshots.size()); i++) {
player.print((i + 1) + ". " + snapshots.get(i).getName()); player.print(BBC.getPrefix() + (i + 1) + ". " + snapshots.get(i).getName());
} }
BBC.SNAPSHOT_LIST_FOOTER.send(player); BBC.SNAPSHOT_LIST_FOOTER.send(player);
@ -92,10 +92,10 @@ public class SnapshotCommands {
File dir = config.snapshotRepo.getDirectory(); File dir = config.snapshotRepo.getDirectory();
try { try {
WorldEdit.logger.info("WorldEdit found no snapshots: looked in: " WorldEdit.logger.info(BBC.getPrefix() + "WorldEdit found no snapshots: looked in: "
+ dir.getCanonicalPath()); + dir.getCanonicalPath());
} catch (IOException e) { } catch (IOException e) {
WorldEdit.logger.info("WorldEdit found no snapshots: looked in " WorldEdit.logger.info(BBC.getPrefix() + "WorldEdit found no snapshots: looked in "
+ "(NON-RESOLVABLE PATH - does it exist?): " + "(NON-RESOLVABLE PATH - does it exist?): "
+ dir.getPath()); + dir.getPath());
} }
@ -222,7 +222,7 @@ public class SnapshotCommands {
if (snapshot == null) { if (snapshot == null) {
dateFormat.setTimeZone(session.getTimeZone()); dateFormat.setTimeZone(session.getTimeZone());
player.printError("Couldn't find a snapshot before " player.printError(BBC.getPrefix() + "Couldn't find a snapshot before "
+ dateFormat.format(date.getTime()) + "."); + dateFormat.format(date.getTime()) + ".");
} else { } else {
session.setSnapshot(snapshot); session.setSnapshot(snapshot);
@ -260,7 +260,7 @@ public class SnapshotCommands {
Snapshot snapshot = config.snapshotRepo.getSnapshotAfter(date, player.getWorld().getName()); Snapshot snapshot = config.snapshotRepo.getSnapshotAfter(date, player.getWorld().getName());
if (snapshot == null) { if (snapshot == null) {
dateFormat.setTimeZone(session.getTimeZone()); dateFormat.setTimeZone(session.getTimeZone());
player.printError("Couldn't find a snapshot after " player.printError(BBC.getPrefix() + "Couldn't find a snapshot after "
+ dateFormat.format(date.getTime()) + "."); + dateFormat.format(date.getTime()) + ".");
} else { } else {
session.setSnapshot(snapshot); session.setSnapshot(snapshot);

View File

@ -56,7 +56,6 @@ public class SnapshotUtilCommands {
aliases = { "restore", "/restore" }, aliases = { "restore", "/restore" },
usage = "[snapshot]", usage = "[snapshot]",
desc = "Restore the selection from a snapshot", desc = "Restore the selection from a snapshot",
min = 0,
max = 1 max = 1
) )
@Logging(REGION) @Logging(REGION)
@ -112,20 +111,14 @@ public class SnapshotUtilCommands {
} }
} }
ChunkStore chunkStore = null;
// Load chunk store // Load chunk store
try { SnapshotRestore restore;
chunkStore = snapshot.getChunkStore(); try (ChunkStore chunkStore = snapshot.getChunkStore()) {
BBC.SNAPSHOT_LOADED.send(player, snapshot.getName()); BBC.SNAPSHOT_LOADED.send(player, snapshot.getName());
} catch (DataException | IOException e) {
player.printError("Failed to load snapshot: " + e.getMessage());
return;
}
try {
// Restore snapshot // Restore snapshot
SnapshotRestore restore = new SnapshotRestore(chunkStore, editSession, region); restore = new SnapshotRestore(chunkStore, editSession, region);
//player.print(restore.getChunksAffected() + " chunk(s) will be loaded."); //player.print(restore.getChunksAffected() + " chunk(s) will be loaded.");
restore.restore(); restore.restore();
@ -144,11 +137,8 @@ public class SnapshotUtilCommands {
restore.getMissingChunks().size(), restore.getMissingChunks().size(),
restore.getErrorChunks().size())); restore.getErrorChunks().size()));
} }
} finally { } catch (DataException | IOException e) {
try { player.printError("Failed to load snapshot: " + e.getMessage());
chunkStore.close();
} catch (IOException ignored) {
}
} }
} }
} }

View File

@ -41,7 +41,7 @@ public class SuperPickaxeCommands {
} }
@Command( @Command(
aliases = { "single" }, aliases = {"single"},
usage = "", usage = "",
desc = "Enable the single block super pickaxe mode", desc = "Enable the single block super pickaxe mode",
min = 0, min = 0,
@ -56,7 +56,7 @@ public class SuperPickaxeCommands {
} }
@Command( @Command(
aliases = { "area" }, aliases = {"area"},
usage = "<radius>", usage = "<radius>",
desc = "Enable the area super pickaxe pickaxe mode", desc = "Enable the area super pickaxe pickaxe mode",
min = 1, min = 1,
@ -79,7 +79,7 @@ public class SuperPickaxeCommands {
} }
@Command( @Command(
aliases = { "recur", "recursive" }, aliases = {"recur", "recursive"},
usage = "<radius>", usage = "<radius>",
desc = "Enable the recursive super pickaxe pickaxe mode", desc = "Enable the recursive super pickaxe pickaxe mode",
min = 1, min = 1,

View File

@ -60,7 +60,7 @@ public class ToolCommands {
} }
@Command( @Command(
aliases = { "info", "/info" }, aliases = {"info", "/info"},
usage = "", usage = "",
desc = "Block information tool", desc = "Block information tool",
min = 0, min = 0,
@ -68,9 +68,8 @@ public class ToolCommands {
) )
@CommandPermissions("worldedit.tool.info") @CommandPermissions("worldedit.tool.info")
public void info(Player player, LocalSession session) throws WorldEditException { public void info(Player player, LocalSession session) throws WorldEditException {
session.setTool(new QueryTool(), player);
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND); BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND);
session.setTool(itemStack.getType(), new QueryTool());
BBC.TOOL_INFO.send(player, itemStack.getType().getName()); BBC.TOOL_INFO.send(player, itemStack.getType().getName());
} }
@ -78,33 +77,33 @@ public class ToolCommands {
aliases = {"inspect"}, aliases = {"inspect"},
usage = "", usage = "",
desc = "Inspect edits within a radius", desc = "Inspect edits within a radius",
help = "Chooses the inspect brush", help =
"Chooses the inspect brush",
min = 0, min = 0,
max = 0 max = 0
) )
@CommandPermissions("worldedit.tool.inspect") @CommandPermissions("worldedit.tool.inspect")
public void inspectBrush(Player player, LocalSession session, @Optional("1") double radius) throws WorldEditException { public void inspectBrush(Player player, LocalSession session, @Optional("1") double radius) throws WorldEditException {
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND); session.setTool(new InspectBrush(), player);
session.setTool(itemStack.getType(), new InspectBrush()); BBC.TOOL_INSPECT.send(player, player.getItemInHand(HandSide.MAIN_HAND).getType().getName());
BBC.TOOL_INSPECT.send(player, itemStack.getType().getName());
} }
@Command( @Command(
aliases = { "tree" }, aliases = {"tree"},
usage = "[type]", usage = "[type]",
desc = "Tree generator tool", desc = "Tree generator tool",
min = 0, min = 0,
max = 1 max = 1
) )
@CommandPermissions("worldedit.tool.tree") @CommandPermissions("worldedit.tool.tree")
@SuppressWarnings("deprecation")
public void tree(Player player, LocalSession session, @Optional("tree") TreeGenerator.TreeType type, CommandContext args) throws WorldEditException { public void tree(Player player, LocalSession session, @Optional("tree") TreeGenerator.TreeType type, CommandContext args) throws WorldEditException {
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND); session.setTool(new TreePlanter(type), player);
session.setTool(itemStack.getType(), new TreePlanter(type)); BBC.TOOL_TREE.send(player, player.getItemInHand(HandSide.MAIN_HAND).getType().getName());
BBC.TOOL_TREE.send(player, itemStack.getType().getName());
} }
@Command( @Command(
aliases = { "repl" }, aliases = {"repl"},
usage = "<pattern>", usage = "<pattern>",
desc = "Block replacer tool", desc = "Block replacer tool",
min = 1, min = 1,
@ -112,13 +111,12 @@ public class ToolCommands {
) )
@CommandPermissions("worldedit.tool.replacer") @CommandPermissions("worldedit.tool.replacer")
public void repl(Player player, LocalSession session, Pattern pattern) throws WorldEditException { public void repl(Player player, LocalSession session, Pattern pattern) throws WorldEditException {
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND); session.setTool(new BlockReplacer(pattern), player);
session.setTool(itemStack.getType(), new BlockReplacer(pattern)); BBC.TOOL_REPL.send(player, player.getItemInHand(HandSide.MAIN_HAND).getType().getName());
BBC.TOOL_REPL.send(player, itemStack.getType().getName());
} }
@Command( @Command(
aliases = { "cycler" }, aliases = {"cycler"},
usage = "", usage = "",
desc = "Block data cycler tool", desc = "Block data cycler tool",
min = 0, min = 0,
@ -127,65 +125,56 @@ public class ToolCommands {
@CommandPermissions("worldedit.tool.data-cycler") @CommandPermissions("worldedit.tool.data-cycler")
public void cycler(Player player, LocalSession session) throws WorldEditException { public void cycler(Player player, LocalSession session) throws WorldEditException {
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND); session.setTool(new BlockDataCyler(), player);
session.setTool(itemStack.getType(), new BlockDataCyler()); BBC.TOOL_CYCLER.send(player, player.getItemInHand(HandSide.MAIN_HAND).getType().getName());
BBC.TOOL_CYCLER.send(player, itemStack.getType().getName());
} }
@Command( @Command(
aliases = { "floodfill", "flood" }, aliases = {"floodfill", "flood"},
usage = "<pattern> <range>", usage = "<pattern> <range>",
desc = "Flood fill tool", desc = "Flood fill tool",
min = 2, min = 2,
max = 2 max = 2
) )
@CommandPermissions("worldedit.tool.flood-fill") @CommandPermissions("worldedit.tool.flood-fill")
public void floodFill(Player player, LocalSession session, Pattern pattern, int range) throws WorldEditException { public void floodFill(Player player, EditSession editSession, LocalSession session, Pattern pattern, int range) throws WorldEditException {
LocalConfiguration config = we.getConfiguration(); LocalConfiguration config = we.getConfiguration();
if (range > config.maxSuperPickaxeSize) { if (range > config.maxSuperPickaxeSize) {
BBC.TOOL_RANGE_ERROR.send(player, config.maxSuperPickaxeSize); BBC.TOOL_RANGE_ERROR.send(player, config.maxSuperPickaxeSize);
return; return;
} }
session.setTool(new FloodFillTool(range, pattern), player);
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND); BBC.TOOL_FLOOD_FILL.send(player, player.getItemInHand(HandSide.MAIN_HAND).getType().getName());
session.setTool(itemStack.getType(), new FloodFillTool(range, pattern));
BBC.TOOL_FLOOD_FILL.send(player, itemStack.getType().getName());
} }
@Command( @Command(
aliases = { "deltree" }, aliases = {"deltree"},
usage = "", usage = "",
desc = "Floating tree remover tool", desc = "Floating tree remover tool",
min = 0, min = 0,
max = 0 max = 0
) )
@CommandPermissions("worldedit.tool.deltree") @CommandPermissions("worldedit.tool.deltree")
public void deltree(Player player, LocalSession session) throws WorldEditException { public void deltree(Player player, LocalSession session, CommandContext args) throws WorldEditException {
session.setTool(new FloatingTreeRemover(), player);
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND);
session.setTool(itemStack.getType(), new FloatingTreeRemover());
BBC.TOOL_DELTREE.send(player, player.getItemInHand(HandSide.MAIN_HAND).getType().getName()); BBC.TOOL_DELTREE.send(player, player.getItemInHand(HandSide.MAIN_HAND).getType().getName());
} }
@Command( @Command(
aliases = { "farwand" }, aliases = {"farwand"},
usage = "", usage = "",
desc = "Wand at a distance tool", desc = "Wand at a distance tool",
min = 0, min = 0,
max = 0 max = 0
) )
@CommandPermissions("worldedit.tool.farwand") @CommandPermissions("worldedit.tool.farwand")
public void farwand(Player player, LocalSession session) throws WorldEditException { public void farwand(Player player, LocalSession session, CommandContext args) throws WorldEditException {
session.setTool(new DistanceWand(), player);
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND); BBC.TOOL_FARWAND.send(player, player.getItemInHand(HandSide.MAIN_HAND).getType().getName());
session.setTool(itemStack.getType(), new DistanceWand());
BBC.TOOL_FARWAND.send(player, itemStack.getType().getName());
} }
@Command( @Command(
aliases = { "lrbuild", "/lrbuild" }, aliases = {"lrbuild", "/lrbuild"},
usage = "<leftclick block> <rightclick block>", usage = "<leftclick block> <rightclick block>",
desc = "Long-range building tool", desc = "Long-range building tool",
min = 2, min = 2,
@ -193,10 +182,8 @@ public class ToolCommands {
) )
@CommandPermissions("worldedit.tool.lrbuild") @CommandPermissions("worldedit.tool.lrbuild")
public void longrangebuildtool(Player player, LocalSession session, Pattern secondary, Pattern primary) throws WorldEditException { public void longrangebuildtool(Player player, LocalSession session, Pattern secondary, Pattern primary) throws WorldEditException {
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND); session.setTool(new LongRangeBuildTool(primary, secondary), player);
BBC.TOOL_LRBUILD_BOUND.send(player, player.getItemInHand(HandSide.MAIN_HAND).getType().getName());
session.setTool(itemStack.getType(), new LongRangeBuildTool(primary, secondary));
BBC.TOOL_LRBUILD_BOUND.send(player, itemStack.getType().getName());
BBC.TOOL_LRBUILD_INFO.send(player, secondary, primary); BBC.TOOL_LRBUILD_INFO.send(player, secondary, primary);
} }

View File

@ -56,7 +56,7 @@ public class ToolUtilCommands {
String newState = args.getString(0, null); String newState = args.getString(0, null);
if (session.hasSuperPickAxe()) { if (session.hasSuperPickAxe()) {
if ("on".equals(newState)) { if ("on".equals(newState)) {
player.printError("Super pick axe already enabled."); player.printError(BBC.getPrefix() + "Super pick axe already enabled.");
return; return;
} }
@ -64,7 +64,7 @@ public class ToolUtilCommands {
player.print("Super pick axe disabled."); player.print("Super pick axe disabled.");
} else { } else {
if ("off".equals(newState)) { if ("off".equals(newState)) {
player.printError("Super pick axe already disabled."); player.printError(BBC.getPrefix() + "Super pick axe already disabled.");
return; return;
} }
session.enableSuperPickAxe(); session.enableSuperPickAxe();
@ -130,7 +130,6 @@ public class ToolUtilCommands {
int radius = args.getInteger(0); int radius = args.getInteger(0);
we.checkMaxBrushRadius(radius); we.checkMaxBrushRadius(radius);
session.getBrushTool(player.getItemInHand(HandSide.MAIN_HAND).getType()).setSize(radius); session.getBrushTool(player.getItemInHand(HandSide.MAIN_HAND).getType()).setSize(radius);
player.print("Brush size set."); player.print("Brush size set.");
} }

View File

@ -110,7 +110,7 @@ public class UtilityCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "patterns" }, aliases = {"patterns"},
usage = "[page=1|search|pattern]", usage = "[page=1|search|pattern]",
desc = "View help about patterns", desc = "View help about patterns",
help = "Patterns determine what blocks are placed\n" + help = "Patterns determine what blocks are placed\n" +
@ -125,7 +125,7 @@ public class UtilityCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "masks" }, aliases = {"masks"},
usage = "[page=1|search|mask]", usage = "[page=1|search|mask]",
desc = "View help about masks", desc = "View help about masks",
help = "Masks determine if a block can be placed\n" + help = "Masks determine if a block can be placed\n" +
@ -141,7 +141,7 @@ public class UtilityCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "transforms" }, aliases = {"transforms"},
usage = "[page=1|search|transform]", usage = "[page=1|search|transform]",
desc = "View help about transforms", desc = "View help about transforms",
help = "Transforms modify how a block is placed\n" + help = "Transforms modify how a block is placed\n" +
@ -179,7 +179,7 @@ public class UtilityCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/heightmapinterface" }, aliases = {"/heightmapinterface"},
desc = "Generate the heightmap interface: https://github.com/boy0001/HeightMap" desc = "Generate the heightmap interface: https://github.com/boy0001/HeightMap"
) )
@CommandPermissions("fawe.admin") @CommandPermissions("fawe.admin")
@ -237,7 +237,7 @@ public class UtilityCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/cancel", "fcancel" }, aliases = {"/cancel", "fcancel"},
desc = "Cancel your current command", desc = "Cancel your current command",
max = 0, max = 0,
queued = false queued = false
@ -248,7 +248,7 @@ public class UtilityCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/fill" }, aliases = {"/fill"},
usage = "<pattern> <radius> [depth] [direction]", usage = "<pattern> <radius> [depth] [direction]",
desc = "Fill a hole", desc = "Fill a hole",
min = 2, min = 2,
@ -261,11 +261,11 @@ public class UtilityCommands extends MethodCommands {
BlockVector3 pos = session.getPlacementPosition(player); BlockVector3 pos = session.getPlacementPosition(player);
int affected; int affected;
affected = editSession.fillDirection(pos, pattern, radius, (int) depth, direction); affected = editSession.fillDirection(pos, pattern, radius, (int) depth, direction);
player.print(affected + " block(s) have been created."); player.print(BBC.getPrefix() + affected + " block(s) have been created.");
} }
@Command( @Command(
aliases = { "/fillr" }, aliases = {"/fillr"},
usage = "<pattern> <radius> [depth]", usage = "<pattern> <radius> [depth]",
desc = "Fill a hole recursively", desc = "Fill a hole recursively",
min = 2, min = 2,
@ -278,11 +278,11 @@ public class UtilityCommands extends MethodCommands {
BlockVector3 pos = session.getPlacementPosition(player); BlockVector3 pos = session.getPlacementPosition(player);
if (depth == -1) depth = Integer.MAX_VALUE; if (depth == -1) depth = Integer.MAX_VALUE;
int affected = editSession.fillXZ(pos, pattern, radius, (int) depth, true); int affected = editSession.fillXZ(pos, pattern, radius, (int) depth, true);
player.print(affected + " block(s) have been created."); player.print(BBC.getPrefix() + affected + " block(s) have been created.");
} }
@Command( @Command(
aliases = { "/drain" }, aliases = {"/drain"},
usage = "<radius>", usage = "<radius>",
desc = "Drain a pool", desc = "Drain a pool",
min = 1, min = 1,
@ -294,11 +294,11 @@ public class UtilityCommands extends MethodCommands {
worldEdit.checkMaxRadius(radius); worldEdit.checkMaxRadius(radius);
int affected = editSession.drainArea( int affected = editSession.drainArea(
session.getPlacementPosition(player), radius); session.getPlacementPosition(player), radius);
player.print(affected + " block(s) have been changed."); player.print(BBC.getPrefix() + affected + " block(s) have been changed.");
} }
@Command( @Command(
aliases = { "/fixlava", "fixlava" }, aliases = {"/fixlava", "fixlava"},
usage = "<radius>", usage = "<radius>",
desc = "Fix lava to be stationary", desc = "Fix lava to be stationary",
min = 1, min = 1,
@ -307,14 +307,14 @@ public class UtilityCommands extends MethodCommands {
@CommandPermissions("worldedit.fixlava") @CommandPermissions("worldedit.fixlava")
@Logging(PLACEMENT) @Logging(PLACEMENT)
public void fixLava(Player player, LocalSession session, EditSession editSession, @Range(min = 0) double radius) throws WorldEditException { public void fixLava(Player player, LocalSession session, EditSession editSession, @Range(min = 0) double radius) throws WorldEditException {
worldEdit.checkMaxRadius(radius); worldEdit.checkMaxRadius(radius);
int affected = editSession.fixLiquid(session.getPlacementPosition(player), radius, BlockTypes.LAVA); int affected = editSession.fixLiquid(
player.print(affected + " block(s) have been changed."); session.getPlacementPosition(player), radius, BlockTypes.LAVA);
player.print(BBC.getPrefix() + affected + " block(s) have been changed.");
} }
@Command( @Command(
aliases = { "/fixwater", "fixwater" }, aliases = {"/fixwater", "fixwater"},
usage = "<radius>", usage = "<radius>",
desc = "Fix water to be stationary", desc = "Fix water to be stationary",
min = 1, min = 1,
@ -330,7 +330,7 @@ public class UtilityCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/removeabove", "removeabove" }, aliases = {"/removeabove", "removeabove"},
usage = "[size] [height]", usage = "[size] [height]",
desc = "Remove blocks above your head.", desc = "Remove blocks above your head.",
min = 0, min = 0,
@ -345,7 +345,7 @@ public class UtilityCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/removebelow", "removebelow" }, aliases = {"/removebelow", "removebelow"},
usage = "[size] [height]", usage = "[size] [height]",
desc = "Remove blocks below you.", desc = "Remove blocks below you.",
min = 0, min = 0,
@ -360,7 +360,7 @@ public class UtilityCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/removenear", "removenear" }, aliases = {"/removenear", "removenear"},
usage = "<mask> [size]", usage = "<mask> [size]",
desc = "Remove blocks near you.", desc = "Remove blocks near you.",
min = 1, min = 1,
@ -376,7 +376,7 @@ public class UtilityCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/replacenear", "replacenear" }, aliases = {"/replacenear", "replacenear"},
usage = "<size> <from-id> <to-id>", usage = "<size> <from-id> <to-id>",
desc = "Replace nearby blocks", desc = "Replace nearby blocks",
flags = "f", flags = "f",
@ -400,7 +400,7 @@ public class UtilityCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/snow", "snow" }, aliases = {"/snow", "snow"},
usage = "[radius]", usage = "[radius]",
desc = "Simulates snow", desc = "Simulates snow",
min = 0, min = 0,
@ -413,11 +413,11 @@ public class UtilityCommands extends MethodCommands {
we.checkMaxRadius(size); we.checkMaxRadius(size);
int affected = editSession.simulateSnow(session.getPlacementPosition(player), size); int affected = editSession.simulateSnow(session.getPlacementPosition(player), size);
player.print(affected + " surfaces covered. Let it snow~"); player.print(BBC.getPrefix() + affected + " surfaces covered. Let it snow~");
} }
@Command( @Command(
aliases = { "/thaw", "thaw" }, aliases = {"/thaw", "thaw"},
usage = "[radius]", usage = "[radius]",
desc = "Thaws the area", desc = "Thaws the area",
min = 0, min = 0,
@ -430,11 +430,11 @@ public class UtilityCommands extends MethodCommands {
we.checkMaxRadius(size); we.checkMaxRadius(size);
int affected = editSession.thaw(session.getPlacementPosition(player), size); int affected = editSession.thaw(session.getPlacementPosition(player), size);
player.print(affected + " surfaces thawed."); player.print(BBC.getPrefix() + affected + " surfaces thawed.");
} }
@Command( @Command(
aliases = { "/green", "green" }, aliases = {"/green", "green"},
usage = "[radius]", usage = "[radius]",
desc = "Greens the area", desc = "Greens the area",
help = "Converts dirt to grass blocks. -f also converts coarse dirt.", help = "Converts dirt to grass blocks. -f also converts coarse dirt.",
@ -454,7 +454,7 @@ public class UtilityCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/ex", "/ext", "/extinguish", "ex", "ext", "extinguish" }, aliases = {"/ex", "/ext", "/extinguish", "ex", "ext", "extinguish"},
usage = "[radius]", usage = "[radius]",
desc = "Extinguish nearby fire", desc = "Extinguish nearby fire",
min = 0, min = 0,
@ -476,7 +476,7 @@ public class UtilityCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "butcher" }, aliases = {"butcher"},
usage = "[radius]", usage = "[radius]",
flags = "plangbtfr", flags = "plangbtfr",
desc = "Kill all or nearby mobs", desc = "Kill all or nearby mobs",
@ -562,7 +562,7 @@ public class UtilityCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "remove", "rem", "rement" }, aliases = {"remove", "rem", "rement"},
usage = "<type> <radius>", usage = "<type> <radius>",
desc = "Remove all entities of a type", desc = "Remove all entities of a type",
min = 2, min = 2,
@ -622,7 +622,7 @@ public class UtilityCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/calc", "/calculate", "/eval", "/evaluate", "/solve" }, aliases = {"/calc", "/calculate", "/eval", "/evaluate", "/solve"},
usage = "<expression>", usage = "<expression>",
desc = "Evaluate a mathematical expression" desc = "Evaluate a mathematical expression"
) )
@ -646,7 +646,7 @@ public class UtilityCommands extends MethodCommands {
} }
executor.shutdownNow(); executor.shutdownNow();
actor.print("= " + result); actor.print(BBC.getPrefix() + "= " + result);
} catch (EvaluationException e) { } catch (EvaluationException e) {
actor.printError(String.format( actor.printError(String.format(
"'%s' could not be evaluated (error: %s)", input, e.getMessage())); "'%s' could not be evaluated (error: %s)", input, e.getMessage()));
@ -657,7 +657,7 @@ public class UtilityCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/confirm" }, aliases = {"/confirm"},
desc = "Confirm a command" desc = "Confirm a command"
) )
public void confirm(FawePlayer fp) throws WorldEditException { public void confirm(FawePlayer fp) throws WorldEditException {
@ -667,14 +667,13 @@ public class UtilityCommands extends MethodCommands {
} }
@Command( @Command(
aliases = { "/help" }, aliases = {"/help"},
usage = "[<command>]", usage = "[<command>]",
desc = "Displays help for WorldEdit commands", desc = "Displays help for WorldEdit commands",
min = 0, min = 0,
max = -1, max = -1,
queued = false queued = false
) )
@CommandPermissions("worldedit.help")
public void help(Actor actor, CommandContext args) throws WorldEditException { public void help(Actor actor, CommandContext args) throws WorldEditException {
help(args, worldEdit, actor); help(args, worldEdit, actor);
} }

View File

@ -1,31 +1,12 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.command.tool; package com.sk89q.worldedit.command.tool;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
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.extension.platform.Platform; import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
@ -49,11 +30,11 @@ public class AreaPickaxe implements BlockTool {
} }
@Override @Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, com.sk89q.worldedit.util.Location clicked) { public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked) {
int ox = clicked.getBlockX(); int ox = clicked.getBlockX();
int oy = clicked.getBlockY(); int oy = clicked.getBlockY();
int oz = clicked.getBlockZ(); int oz = clicked.getBlockZ();
BlockType initialType = clicked.getExtent().getBlock(clicked.toVector().toBlockPoint()).getBlockType(); BlockType initialType = clicked.getExtent().getBlock(clicked.toBlockPoint()).getBlockType();
if (initialType.getMaterial().isAir()) { if (initialType.getMaterial().isAir()) {
return true; return true;
@ -64,9 +45,8 @@ public class AreaPickaxe implements BlockTool {
} }
try (EditSession editSession = session.createEditSession(player)) { try (EditSession editSession = session.createEditSession(player)) {
editSession.getSurvivalExtent().setToolUse(config.superPickaxeManyDrop);
try { try {
editSession.getSurvivalExtent().setToolUse(config.superPickaxeManyDrop);
for (int x = ox - range; x <= ox + range; ++x) { for (int x = ox - range; x <= ox + range; ++x) {
for (int z = oz - range; z <= oz + range; ++z) { for (int z = oz - range; z <= oz + range; ++z) {
for (int y = oy + range; y >= oy - range; --y) { for (int y = oy + range; y >= oy - range; --y) {
@ -78,14 +58,10 @@ public class AreaPickaxe implements BlockTool {
} }
} }
editSession.flushQueue(); editSession.flushQueue();
} catch (MaxChangedBlocksException e) {
player.printError("Max blocks change limit reached.");
} finally { } finally {
session.remember(editSession); session.remember(editSession);
} }
} }
return true; return true;
} }
} }

View File

@ -56,7 +56,8 @@ public class BlockDataCyler implements DoubleActionBlockTool {
World world = (World) clicked.getExtent(); World world = (World) clicked.getExtent();
BlockVector3 blockPoint = clicked.toVector().toBlockPoint(); // BlockStateHolder block = world.getBlock(clicked);
BlockVector3 blockPoint = clicked.toBlockPoint();
BlockState block = world.getBlock(blockPoint); BlockState block = world.getBlock(blockPoint);
if (!config.allowedDataCycleBlocks.isEmpty() if (!config.allowedDataCycleBlocks.isEmpty()
@ -84,24 +85,24 @@ public class BlockDataCyler implements DoubleActionBlockTool {
Property<Object> objProp = (Property<Object>) currentProperty; Property<Object> objProp = (Property<Object>) currentProperty;
BlockState newBlock = block.with(objProp, currentProperty.getValues().get(index)); BlockState newBlock = block.with(objProp, currentProperty.getValues().get(index));
try (EditSession editSession = session.createEditSession(player)) { try {
EditSession editSession = session.createEditSession(player);
try { try {
editSession.setBlock(blockPoint, newBlock); editSession.setBlock(blockPoint, newBlock);
player.print("Value of " + currentProperty.getName() + " is now " + currentProperty.getValues().get(index).toString()); player.print(BBC.getPrefix() + "Value of " + currentProperty.getName() + " is now " + currentProperty.getValues().get(index).toString());
} catch (MaxChangedBlocksException e) { } catch (MaxChangedBlocksException e) {
BBC.BLOCK_CYCLER_LIMIT.send(player); BBC.BLOCK_CYCLER_LIMIT.send(player);
} finally { } finally {
session.remember(editSession); session.remember(editSession);
} }
} catch (Exception e) { }catch (Exception e) {}
}
} else { } else {
List<Property<?>> properties = Lists.newArrayList(block.getStates().keySet()); List<Property<?>> properties = Lists.newArrayList(block.getStates().keySet());
int index = properties.indexOf(currentProperty); int index = properties.indexOf(currentProperty);
index = (index + 1) % properties.size(); index = (index + 1) % properties.size();
currentProperty = properties.get(index); currentProperty = properties.get(index);
selectedProperties.put(player.getUniqueId(), currentProperty); selectedProperties.put(player.getUniqueId(), currentProperty);
player.print("Now cycling " + currentProperty.getName()); player.print(BBC.getPrefix() + "Now cycling " + currentProperty.getName());
} }
} }

View File

@ -19,6 +19,7 @@
package com.sk89q.worldedit.command.tool; package com.sk89q.worldedit.command.tool;
import com.boydti.fawe.config.BBC;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
@ -31,9 +32,10 @@ import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
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.BlockType;
/** /**
* A mode that replaces one block.
*/ */
public class BlockReplacer implements DoubleActionBlockTool { public class BlockReplacer implements DoubleActionBlockTool {
@ -72,11 +74,13 @@ public class BlockReplacer implements DoubleActionBlockTool {
@Override @Override
public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session, com.sk89q.worldedit.util.Location clicked) { public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session, com.sk89q.worldedit.util.Location clicked) {
BlockState targetBlock = player.getWorld().getBlock(clicked.toVector().toBlockPoint()); EditSession editSession = session.createEditSession(player);
BlockStateHolder targetBlock = (editSession).getBlock(clicked.toBlockPoint());
BlockType type = targetBlock.getBlockType();
if (targetBlock != null) { if (type != null) {
pattern = new BlockPattern(targetBlock); this.pattern = targetBlock;
player.print("Replacer tool switched to: " + targetBlock.getBlockType().getName()); player.print(BBC.getPrefix() + "Replacer tool switched to: " + type.getName());
} }
return true; return true;

View File

@ -1,22 +1,3 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.command.tool; package com.sk89q.worldedit.command.tool;
import com.boydti.fawe.Fawe; import com.boydti.fawe.Fawe;
@ -263,6 +244,15 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool
return getContext().getMask(); return getContext().getMask();
} }
/**
* Get the filter.
*
* @return the filter
*/
public Mask getSourceMask() {
return getContext().getSourceMask();
}
@Override @Override
public boolean reset() { public boolean reset() {
Brush br = getBrush(); Brush br = getBrush();
@ -337,7 +327,8 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool
* *
* @return the material * @return the material
*/ */
@Nullable public Pattern getMaterial() { @Nullable
public Pattern getMaterial() {
return getContext().getMaterial(); return getContext().getMaterial();
} }
@ -433,7 +424,8 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool
return TaskManager.IMP.sync(new RunnableVal<Vector3>() { return TaskManager.IMP.sync(new RunnableVal<Vector3>() {
@Override @Override
public void run(Vector3 value) { public void run(Vector3 value) {
this.value = tb.getMaskedTargetBlock(useLastBlock); Location result = tb.getMaskedTargetBlock(useLastBlock);
this.value = result;
} }
}); });
} }
@ -466,7 +458,6 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool
BBC.NO_BLOCK.send(player); BBC.NO_BLOCK.send(player);
return false; return false;
} }
BlockBag bag = session.getBlockBag(player); BlockBag bag = session.getBlockBag(player);
Request.request().setEditSession(editSession); Request.request().setEditSession(editSession);
Mask mask = current.getMask(); Mask mask = current.getMask();
@ -496,7 +487,7 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool
double size = current.getSize(); double size = current.getSize();
WorldEdit.getInstance().checkMaxBrushRadius(size); WorldEdit.getInstance().checkMaxBrushRadius(size);
brush.build(editSession, target, current.getMaterial(), size); brush.build(editSession, target, current.getMaterial(), size);
} catch (MaxChangedBlocksException e) { } catch (WorldEditException e) {
player.printError("Max blocks change limit reached."); // Never happens player.printError("Max blocks change limit reached."); // Never happens
} finally { } finally {
if (bag != null) { if (bag != null) {
@ -519,6 +510,12 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool
} }
public void setScrollAction(ScrollAction scrollAction) {
this.getContext().setScrollAction(scrollAction);
update();
}
public void setTargetOffset(int targetOffset) { public void setTargetOffset(int targetOffset) {
this.targetOffset = targetOffset; this.targetOffset = targetOffset;
update(); update();
@ -560,6 +557,10 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool
return targetOffset; return targetOffset;
} }
public Mask getTargetMask() {
return targetMask;
}
public VisualMode getVisualMode() { public VisualMode getVisualMode() {
return visualMode; return visualMode;
} }

View File

@ -69,7 +69,7 @@ public class DistanceWand extends BrushTool implements DoubleActionTraceTool {
if (target == null) return true; if (target == null) return true;
RegionSelector selector = session.getRegionSelector(player.getWorld()); RegionSelector selector = session.getRegionSelector(player.getWorld());
BlockVector3 blockPoint = target.toVector().toBlockPoint(); BlockVector3 blockPoint = target.toBlockPoint();
if (selector.selectSecondary(blockPoint, ActorSelectorLimits.forActor(player))) { if (selector.selectSecondary(blockPoint, ActorSelectorLimits.forActor(player))) {
selector.explainSecondarySelection(player, session, blockPoint); selector.explainSecondarySelection(player, session, blockPoint);
} }

View File

@ -19,6 +19,7 @@
package com.sk89q.worldedit.command.tool; package com.sk89q.worldedit.command.tool;
import com.boydti.fawe.object.collection.BlockVectorSet;
import com.boydti.fawe.config.BBC; import com.boydti.fawe.config.BBC;
import com.boydti.fawe.object.collection.LocalBlockVectorSet; import com.boydti.fawe.object.collection.LocalBlockVectorSet;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
@ -37,7 +38,9 @@ import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set; import java.util.Set;
/** /**
@ -118,7 +121,7 @@ public class FloatingTreeRemover implements BlockTool {
* @return a set containing all blocks in the tree/shroom or null if this is not a floating tree/shroom. * @return a set containing all blocks in the tree/shroom or null if this is not a floating tree/shroom.
*/ */
private Set<BlockVector3> bfs(World world, BlockVector3 origin) throws MaxChangedBlocksException { private Set<BlockVector3> bfs(World world, BlockVector3 origin) throws MaxChangedBlocksException {
final Set<BlockVector3> visited = new LocalBlockVectorSet(); final LocalBlockVectorSet visited = new LocalBlockVectorSet();
final LocalBlockVectorSet queue = new LocalBlockVectorSet(); final LocalBlockVectorSet queue = new LocalBlockVectorSet();
queue.add(origin); queue.add(origin);

View File

@ -64,7 +64,7 @@ public class FloodFillTool implements BlockTool {
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked) { public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked) {
World world = (World) clicked.getExtent(); World world = (World) clicked.getExtent();
BlockVector3 origin = clicked.toVector().toBlockPoint(); BlockVector3 origin = clicked.toBlockPoint();
BlockType initialType = world.getBlock(origin).getBlockType(); BlockType initialType = world.getBlock(origin).getBlockType();
if (initialType.getMaterial().isAir()) { if (initialType.getMaterial().isAir()) {
@ -88,7 +88,6 @@ public class FloodFillTool implements BlockTool {
session.remember(editSession); session.remember(editSession);
} }
} }
return true; return true;
} }
@ -121,4 +120,5 @@ public class FloodFillTool implements BlockTool {
origin, size, initialType, visited); origin, size, initialType, visited);
} }
} }

View File

@ -1,29 +1,9 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.command.tool; package com.sk89q.worldedit.command.tool;
import com.boydti.fawe.object.mask.IdMask; import com.boydti.fawe.object.mask.IdMask;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
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.extension.platform.Platform; import com.sk89q.worldedit.extension.platform.Platform;
@ -37,14 +17,11 @@ import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
import java.util.Set;
/** /**
* A pickaxe mode that recursively finds adjacent blocks within range of * A pickaxe mode that recursively finds adjacent blocks within range of
* an initial block and of the same type. * an initial block and of the same type.
*/ */
public class RecursivePickaxe implements BlockTool { public class RecursivePickaxe implements BlockTool {
private double range; private double range;
public RecursivePickaxe(double range) { public RecursivePickaxe(double range) {
@ -59,66 +36,32 @@ public class RecursivePickaxe implements BlockTool {
@Override @Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, com.sk89q.worldedit.util.Location clicked) { public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, com.sk89q.worldedit.util.Location clicked) {
World world = (World) clicked.getExtent(); World world = (World) clicked.getExtent();
final BlockVector3 pos = clicked.toBlockPoint();
EditSession editSession = session.createEditSession(player);
BlockVector3 origin = clicked.toBlockPoint(); BlockVector3 origin = clicked.toBlockPoint();
BlockType initialType = world.getBlock(origin).getBlockType(); BlockType initialType = world.getBlock(origin).getBlockType();
if (initialType.getMaterial().isAir()) { BlockStateHolder block = editSession.getBlock(pos);
if (block.getBlockType().getMaterial().isAir()) {
return true; return true;
} }
if (initialType == BlockTypes.BEDROCK && !player.canDestroyBedrock()) { if (block.getBlockType() == BlockTypes.BEDROCK && !player.canDestroyBedrock()) {
return true; return true;
} }
try (EditSession editSession = session.createEditSession(player)) {
editSession.getSurvivalExtent().setToolUse(config.superPickaxeManyDrop); editSession.getSurvivalExtent().setToolUse(config.superPickaxeManyDrop);
final int radius = (int) range; final int radius = (int) range;
final BlockReplace replace = new BlockReplace(editSession, (editSession.nullBlock)); final BlockReplace replace = new BlockReplace(editSession, (editSession.nullBlock));
editSession.setMask((Mask) null); editSession.setMask((Mask) null);
RecursiveVisitor visitor = new RecursiveVisitor(new IdMask(editSession), replace, radius, editSession); RecursiveVisitor visitor = new RecursiveVisitor(new IdMask(editSession), replace, radius, editSession);
visitor.visit(clicked.toBlockPoint()); visitor.visit(pos);
Operations.completeBlindly(visitor); Operations.completeBlindly(visitor);
editSession.flushQueue(); editSession.flushQueue();
session.remember(editSession); session.remember(editSession);
player.printError("Max blocks change limit reached.");
}
return true; return true;
} }
private static void recurse(Platform server, EditSession editSession, World world, BlockVector3 pos,
BlockVector3 origin, double size, BlockType initialType, Set<BlockVector3> visited) throws MaxChangedBlocksException {
final double distanceSq = origin.distanceSq(pos);
if (distanceSq > size*size || visited.contains(pos)) {
return;
}
visited.add(pos);
if (editSession.getBlock(pos).getBlockType() != initialType) {
return;
}
world.queueBlockBreakEffect(server, pos, initialType, distanceSq);
editSession.setBlock(pos, BlockTypes.AIR.getDefaultState());
recurse(server, editSession, world, pos.add(1, 0, 0),
origin, size, initialType, visited);
recurse(server, editSession, world, pos.add(-1, 0, 0),
origin, size, initialType, visited);
recurse(server, editSession, world, pos.add(0, 0, 1),
origin, size, initialType, visited);
recurse(server, editSession, world, pos.add(0, 0, -1),
origin, size, initialType, visited);
recurse(server, editSession, world, pos.add(0, 1, 0),
origin, size, initialType, visited);
recurse(server, editSession, world, pos.add(0, -1, 0),
origin, size, initialType, visited);
}
} }

View File

@ -37,7 +37,7 @@ public class HollowCylinderBrush implements Brush {
@Override @Override
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException { public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException {
if (pattern == null) { if (pattern == null) {
pattern = new BlockPattern(BlockTypes.COBBLESTONE.getDefaultState()); pattern = (BlockTypes.COBBLESTONE.getDefaultState());
} }
editSession.makeCylinder(position, pattern, size, size, height, false); editSession.makeCylinder(position, pattern, size, size, height, false);
} }

View File

@ -31,7 +31,7 @@ public class HollowSphereBrush implements Brush {
@Override @Override
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException { public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException {
if (pattern == null) { if (pattern == null) {
pattern = new BlockPattern(BlockTypes.COBBLESTONE.getDefaultState()); pattern = (BlockTypes.COBBLESTONE.getDefaultState());
} }
editSession.makeSphere(position, pattern, size, size, size, false); editSession.makeSphere(position, pattern, size, size, size, false);
} }

View File

@ -53,7 +53,7 @@ public class SmoothBrush implements Brush {
Vector3 posDouble = position.toVector3(); Vector3 posDouble = position.toVector3();
Location min = new Location(editSession.getWorld(), posDouble.subtract(size, size, size)); Location min = new Location(editSession.getWorld(), posDouble.subtract(size, size, size));
BlockVector3 max = posDouble.add(size, size + 10, size).toBlockPoint(); BlockVector3 max = posDouble.add(size, size + 10, size).toBlockPoint();
Region region = new CuboidRegion(editSession.getWorld(), min.toVector().toBlockPoint(), max); Region region = new CuboidRegion(editSession.getWorld(), min.toBlockPoint(), max);
HeightMap heightMap = new HeightMap(editSession, region, mask); HeightMap heightMap = new HeightMap(editSession, region, mask);
HeightMapFilter filter = new HeightMapFilter(new GaussianKernel(5, 1.0)); HeightMapFilter filter = new HeightMapFilter(new GaussianKernel(5, 1.0));
heightMap.applyFilter(filter, iterations); heightMap.applyFilter(filter, iterations);

View File

@ -31,7 +31,7 @@ public class SphereBrush implements Brush {
@Override @Override
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException { public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException {
if (pattern == null) { if (pattern == null) {
pattern = new BlockPattern(BlockTypes.COBBLESTONE.getDefaultState()); pattern = (BlockTypes.COBBLESTONE.getDefaultState());
} }
editSession.makeSphere(position, pattern, size, size, size, true); editSession.makeSphere(position, pattern, size, size, size, true);
} }

View File

@ -19,9 +19,6 @@
package com.sk89q.worldedit.event.extent; package com.sk89q.worldedit.event.extent;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.EditSession.Stage;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.event.Cancellable; import com.sk89q.worldedit.event.Cancellable;
import com.sk89q.worldedit.event.Event; import com.sk89q.worldedit.event.Event;
@ -31,20 +28,24 @@ import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.EditSession.Stage;
/** /**
* Raised (several times) when a new {@link EditSession} is being instantiated. * Raised (several times) when a new {@link EditSession} is being instantiated.
* * <p>
* <p></p>Block loggers, as well as block set interceptors, can use this event to wrap * <p></p>Block loggers, as well as block set interceptors, can use this event to wrap
* the given {@link Extent} with their own, which would allow them to intercept * the given {@link Extent} with their own, which would allow them to intercept
* all changes made to the world. For example, the code below would wrap the * all changes made to the world. For example, the code below would wrap the
* existing extent with a custom one, and the custom extent would receive * existing extent with a custom one, and the custom extent would receive
* all method calls <strong>before</strong> the extent fetched from * all method calls <strong>before</strong> the extent fetched from
* {@link #getExtent()} would.</p> * {@link #getExtent()} would.</p>
* * <p>
* <pre> * <pre>
* event.setExtent(new MyExtent(event.getExtent()) * event.setExtent(new MyExtent(event.getExtent())
* </pre> * </pre>
* * <p>
* <p></p>This event is fired several times during the creation of a single * <p></p>This event is fired several times during the creation of a single
* {@link EditSession}, but {@link #getStage()} will differ each time. * {@link EditSession}, but {@link #getStage()} will differ each time.
* The stage determines at which point {@link Extent}s added to this event * The stage determines at which point {@link Extent}s added to this event
@ -96,7 +97,9 @@ public class EditSessionEvent extends Event implements Cancellable {
* *
* @return the actor, which may be null if unavailable * @return the actor, which may be null if unavailable
*/ */
public @Nullable Actor getActor() { public
@Nullable
Actor getActor() {
return actor; return actor;
} }
@ -105,7 +108,9 @@ public class EditSessionEvent extends Event implements Cancellable {
* *
* @return the world * @return the world
*/ */
public @Nullable World getWorld() { public
@Nullable
World getWorld() {
return world; return world;
} }
@ -164,7 +169,10 @@ public class EditSessionEvent extends Event implements Cancellable {
* @return a new event * @return a new event
*/ */
public EditSessionEvent clone(Stage stage) { public EditSessionEvent clone(Stage stage) {
return new EditSessionEvent(world, actor, maxBlocks, stage); EditSessionEvent clone = new EditSessionEvent(world, actor, maxBlocks, stage);
clone.setEditSession(session);
return clone;
} }
} }

View File

@ -25,7 +25,6 @@ import com.boydti.fawe.jnbt.JSON2NBT;
import com.boydti.fawe.jnbt.NBTException; import com.boydti.fawe.jnbt.NBTException;
import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.StringMan; import com.boydti.fawe.util.StringMan;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.IncompleteRegionException; import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.NotABlockException; import com.sk89q.worldedit.NotABlockException;
@ -43,6 +42,7 @@ import com.sk89q.worldedit.extension.input.NoMatchException;
import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.extent.inventory.SlottableBlockBag; import com.sk89q.worldedit.extent.inventory.SlottableBlockBag;
import com.sk89q.worldedit.internal.registry.InputParser; import com.sk89q.worldedit.internal.registry.InputParser;
@ -59,6 +59,7 @@ import com.sk89q.worldedit.world.block.FuzzyBlockState;
import com.sk89q.worldedit.world.registry.LegacyMapper; import com.sk89q.worldedit.world.registry.LegacyMapper;
import java.util.Arrays; import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;

View File

@ -55,7 +55,7 @@ public class ExpressionMaskParser extends InputParser<Mask> {
if (context.getActor() instanceof SessionOwner) { if (context.getActor() instanceof SessionOwner) {
SessionOwner owner = (SessionOwner) context.getActor(); SessionOwner owner = (SessionOwner) context.getActor();
IntSupplier timeout = () -> WorldEdit.getInstance().getSessionManager().get(owner).getTimeout(); IntSupplier timeout = () -> WorldEdit.getInstance().getSessionManager().get(owner).getTimeout();
return new ExpressionMask(exp, timeout); // TODO timeout
} }
return new ExpressionMask(exp); return new ExpressionMask(exp);
} catch (ExpressionException e) { } catch (ExpressionException e) {

View File

@ -69,10 +69,10 @@ public class BlockCategoryPatternParser extends InputParser<Pattern> {
if (anyState) { if (anyState) {
blocks.stream().flatMap(blockType -> blockType.getAllStates().stream()).forEach(state -> blocks.stream().flatMap(blockType -> blockType.getAllStates().stream()).forEach(state ->
randomPattern.add(new BlockPattern(state), 1.0)); randomPattern.add((state), 1.0));
} else { } else {
for (BlockType blockType : blocks) { for (BlockType blockType : blocks) {
randomPattern.add(new BlockPattern(blockType.getDefaultState()), 1.0); randomPattern.add((blockType.getDefaultState()), 1.0);
} }
} }

View File

@ -83,5 +83,4 @@ public class ClipboardPatternParser extends InputParser<Pattern> {
throw new InputParseException("No session is available, so no clipboard is available"); throw new InputParseException("No session is available, so no clipboard is available");
} }
} }
} }

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.extension.factory.parser.pattern;
import com.sk89q.util.StringUtil; import com.sk89q.util.StringUtil;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.factory.BlockFactory;
import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;

View File

@ -44,7 +44,7 @@ public class RandomStatePatternParser extends InputParser<Pattern> {
context.setPreferringWildcard(wasFuzzy); context.setPreferringWildcard(wasFuzzy);
if (block.getStates().size() == block.getBlockType().getPropertyMap().size()) { if (block.getStates().size() == block.getBlockType().getPropertyMap().size()) {
// they requested random with *, but didn't leave any states empty - simplify // they requested random with *, but didn't leave any states empty - simplify
return new BlockPattern(block); return (block);
} else { } else {
return null; // only should happen if parseLogic changes return null; // only should happen if parseLogic changes
} }

View File

@ -34,7 +34,7 @@ public class SingleBlockPatternParser extends InputParser<Pattern> {
@Override @Override
public Pattern parseFromInput(String input, ParserContext context) throws InputParseException { public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
return new BlockPattern(worldEdit.getBlockFactory().parseFromInput(input, context)); return (worldEdit.getBlockFactory().parseFromInput(input, context));
} }
} }

View File

@ -25,6 +25,7 @@ import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.internal.cui.CUIEvent; import com.sk89q.worldedit.internal.cui.CUIEvent;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.MutableBlockVector3;
import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.HandSide; import com.sk89q.worldedit.util.HandSide;
@ -35,6 +36,7 @@ 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.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypeUtil;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.gamemode.GameMode; import com.sk89q.worldedit.world.gamemode.GameMode;
import com.sk89q.worldedit.world.gamemode.GameModes; import com.sk89q.worldedit.world.gamemode.GameModes;
@ -100,23 +102,22 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
Extent world = searchPos.getExtent(); Extent world = searchPos.getExtent();
int x = searchPos.getBlockX(); int x = searchPos.getBlockX();
int y = Math.max(0, searchPos.getBlockY()); int y = Math.max(0, searchPos.getBlockY());
int origY = y;
int z = searchPos.getBlockZ(); int z = searchPos.getBlockZ();
byte free = 0; byte free = 0;
BlockVector3 mutablePos = MutableBlockVector3.at(0, 0, 0);
while (y <= world.getMaximumPoint().getBlockY() + 2) { while (y <= world.getMaximumPoint().getBlockY() + 2) {
if (!world.getBlock(BlockVector3.at(x, y, z)).getBlockType().getMaterial().isMovementBlocker()) { if (!world.getBlock(mutablePos.setComponents(x, y, z)).getBlockType().getMaterial().isMovementBlocker()) {
++free; ++free;
} else { } else {
free = 0; free = 0;
} }
if (free == 2) { if (free == 2) {
if (y - 1 != origY) { final BlockVector3 pos = mutablePos.setComponents(x, y - 2, z);
setPosition(Vector3.at(x + 0.5, y - 2 + 1, z + 0.5)); final BlockStateHolder state = world.getBlock(pos);
} setPosition(new Location(world, Vector3.at(x + 0.5, y - 2 + BlockTypeUtil.centralTopLimit(state), z + 0.5)));
return; return;
} }

View File

@ -332,9 +332,7 @@ public class PlatformManager {
return; return;
} }
FawePlayer<?> fp = FawePlayer.wrap(player); FawePlayer<?> fp = FawePlayer.wrap(player);
RegionSelector selector = session.getRegionSelector(player.getWorld()); RegionSelector selector = session.getRegionSelector(player.getWorld());
final Player maskedPlayerWrapper = final Player maskedPlayerWrapper =
new LocationMaskedPlayerWrapper(PlayerWrapper.wrap((Player) actor), new LocationMaskedPlayerWrapper(PlayerWrapper.wrap((Player) actor),
((Player) actor).getLocation()); ((Player) actor).getLocation());
@ -361,8 +359,7 @@ public class PlatformManager {
return; return;
} }
} }
Tool tool = session.getTool(player);
Tool tool = session.getTool(player.getItemInHand(HandSide.MAIN_HAND).getType());
if (tool instanceof DoubleActionBlockTool) { if (tool instanceof DoubleActionBlockTool) {
if (tool.canUse(player)) { if (tool.canUse(player)) {
FawePlayer<?> fp = FawePlayer.wrap(player); FawePlayer<?> fp = FawePlayer.wrap(player);
@ -385,7 +382,6 @@ public class PlatformManager {
} }
FawePlayer<?> fp = FawePlayer.wrap(player); FawePlayer<?> fp = FawePlayer.wrap(player);
if (fp.checkAction()) { if (fp.checkAction()) {
RegionSelector selector = session.getRegionSelector(player.getWorld()); RegionSelector selector = session.getRegionSelector(player.getWorld());
Player maskedPlayerWrapper = new LocationMaskedPlayerWrapper( Player maskedPlayerWrapper = new LocationMaskedPlayerWrapper(
PlayerWrapper.wrap((Player) actor), PlayerWrapper.wrap((Player) actor),
@ -404,7 +400,7 @@ public class PlatformManager {
return; return;
} }
Tool tool = session.getTool(player.getItemInHand(HandSide.MAIN_HAND).getType()); Tool tool = session.getTool(player);
if (tool instanceof BlockTool) { if (tool instanceof BlockTool) {
if (tool.canUse(player)) { if (tool.canUse(player)) {
FawePlayer<?> fp = FawePlayer.wrap(player); FawePlayer<?> fp = FawePlayer.wrap(player);
@ -475,7 +471,7 @@ public class PlatformManager {
return; return;
} }
Tool tool = session.getTool(player.getItemInHand(HandSide.MAIN_HAND).getType()); Tool tool = session.getTool(player);
if (tool instanceof DoubleActionTraceTool) { if (tool instanceof DoubleActionTraceTool) {
if (tool.canUse(player)) { if (tool.canUse(player)) {
FawePlayer<?> fp = FawePlayer.wrap(player); FawePlayer<?> fp = FawePlayer.wrap(player);
@ -502,7 +498,7 @@ public class PlatformManager {
return; return;
} }
Tool tool = session.getTool(player.getItemInHand(HandSide.MAIN_HAND).getType()); Tool tool = session.getTool(player);
if (tool instanceof TraceTool) { if (tool instanceof TraceTool) {
if (tool.canUse(player)) { if (tool.canUse(player)) {
FawePlayer<?> fp = FawePlayer.wrap(player); FawePlayer<?> fp = FawePlayer.wrap(player);

View File

@ -19,11 +19,11 @@
package com.sk89q.worldedit.extent; package com.sk89q.worldedit.extent;
import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.jnbt.anvil.generator.GenBase; import com.boydti.fawe.jnbt.anvil.generator.GenBase;
import com.boydti.fawe.jnbt.anvil.generator.Resource; import com.boydti.fawe.jnbt.anvil.generator.Resource;
import com.boydti.fawe.object.extent.LightingExtent; import com.boydti.fawe.object.extent.LightingExtent;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
@ -41,7 +41,7 @@ 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.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.registry.BundledBlockData;
import java.util.List; import java.util.List;
import javax.annotation.Nullable; import javax.annotation.Nullable;

View File

@ -19,6 +19,9 @@
package com.sk89q.worldedit.extent; package com.sk89q.worldedit.extent;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockState;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;

View File

@ -22,10 +22,12 @@ package com.sk89q.worldedit.extent;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
/** /**

View File

@ -61,7 +61,7 @@ public interface Clipboard extends Extent {
/** /**
* Returns true if the clipboard has biome data. This can be checked since {@link Extent#getBiome(BlockVector2)} * Returns true if the clipboard has biome data. This can be checked since {@link Extent#getBiome(BlockVector2)}
* strongly suggests returning {@link com.sk89q.worldedit.world.biome.BiomeTypes#OCEAN} instead of {@code null} * strongly suggests returning {@link com.sk89q.worldedit.world.biome.BiomeTypes.OCEAN} instead of {@code null}
* if biomes aren't present. However, it might not be desired to set areas to ocean if the clipboard is defaulting * if biomes aren't present. However, it might not be desired to set areas to ocean if the clipboard is defaulting
* to ocean, instead of having biomes explicitly set. * to ocean, instead of having biomes explicitly set.
* *

Some files were not shown because too many files have changed in this diff Show More