mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2024-11-28 21:56:33 +01:00
Various
Reduce max memory allocation size - Uses multiple byte arrays instead of one large one for streams - Faster read/write as less dependent on arraycopy Remove world compression (it was buggy / there was no interest)\ EditSession can now be used as a world Fix pos1/pos2 being allowed outside the world Fixed liquid mask not being thread safe Fixed plot upload Reduce packet sending - Increase delay to being able to see blocks, but more efficient
This commit is contained in:
parent
911e7e7751
commit
f55a58a3f3
@ -23,7 +23,7 @@ ext {
|
|||||||
git = org.ajoberstar.grgit.Grgit.open(file(".git"))
|
git = org.ajoberstar.grgit.Grgit.open(file(".git"))
|
||||||
revision = "-${git.head().abbreviatedId}"
|
revision = "-${git.head().abbreviatedId}"
|
||||||
parents = git.head().parentIds;
|
parents = git.head().parentIds;
|
||||||
index = -43; // Offset to mach CI
|
index = -45; // Offset to mach CI
|
||||||
for (;parents != null && !parents.isEmpty();index++) {
|
for (;parents != null && !parents.isEmpty();index++) {
|
||||||
commit = git.getResolve().toCommit(parents.get(0));
|
commit = git.getResolve().toCommit(parents.get(0));
|
||||||
parents = commit.getParentIds();
|
parents = commit.getParentIds();
|
||||||
|
@ -2,29 +2,8 @@ package com.boydti.fawe.bukkit.v1_10;
|
|||||||
|
|
||||||
import com.boydti.fawe.bukkit.ABukkitMain;
|
import com.boydti.fawe.bukkit.ABukkitMain;
|
||||||
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
||||||
import com.boydti.fawe.config.Settings;
|
|
||||||
import com.boydti.fawe.object.FaweQueue;
|
import com.boydti.fawe.object.FaweQueue;
|
||||||
import com.boydti.fawe.object.io.BufferedRandomAccessFile;
|
|
||||||
import com.boydti.fawe.object.io.FastByteArrayInputStream;
|
|
||||||
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
|
||||||
import com.boydti.fawe.util.ReflectionUtils;
|
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.BufferedOutputStream;
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.RandomAccessFile;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.zip.Deflater;
|
|
||||||
import java.util.zip.DeflaterOutputStream;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
|
||||||
import java.util.zip.InflaterInputStream;
|
|
||||||
import net.minecraft.server.v1_10_R1.RegionFile;
|
|
||||||
import net.minecraft.server.v1_10_R1.RegionFileCache;
|
|
||||||
|
|
||||||
public class BukkitMain_110 extends ABukkitMain {
|
public class BukkitMain_110 extends ABukkitMain {
|
||||||
@Override
|
@Override
|
||||||
@ -40,128 +19,5 @@ public class BukkitMain_110 extends ABukkitMain {
|
|||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
super.onEnable();
|
super.onEnable();
|
||||||
if (Settings.EXPERIMENTAL.WORLD_COMPRESSION != -1) {
|
|
||||||
try {
|
|
||||||
ReflectionUtils.setFailsafeFieldValue(RegionFileCache.class.getDeclaredField("a"), null, new ConcurrentHashMap<File, RegionFile>(8, 0.9f, 1) {
|
|
||||||
@Override
|
|
||||||
public RegionFile get(Object key) {
|
|
||||||
RegionFile existing = super.get(key);
|
|
||||||
if (existing != null) {
|
|
||||||
return existing;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
File file = (File) key;
|
|
||||||
if (!file.exists()) {
|
|
||||||
file.getParentFile().mkdirs();
|
|
||||||
}
|
|
||||||
if (size() >= 256) {
|
|
||||||
RegionFileCache.a();
|
|
||||||
}
|
|
||||||
RegionFile regionFile = new RegionFile(file) {
|
|
||||||
|
|
||||||
private int[] d = ReflectionUtils.getField(RegionFile.class.getDeclaredField("d"), this);
|
|
||||||
private int[] e = ReflectionUtils.getField(RegionFile.class.getDeclaredField("e"), this);
|
|
||||||
private List<Boolean> f = ReflectionUtils.getField(RegionFile.class.getDeclaredField("f"), this);
|
|
||||||
public RandomAccessFile c = null;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DataOutputStream b(final int i, final int j) {
|
|
||||||
if (i < 0 || i >= 32 || j < 0 || j >= 32) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// if (Settings.EXPERIMENTAL.FAST_WORLD_COMPRESSION) {
|
|
||||||
// try {
|
|
||||||
// return new DataOutputStream(new AsyncBufferedOutputStream(new LZ4OutputStream(new FastByteArrayOutputStream() {
|
|
||||||
// @Override
|
|
||||||
// public void close() {
|
|
||||||
// try {
|
|
||||||
// super.close();
|
|
||||||
// } catch (IOException e1) {
|
|
||||||
// e1.printStackTrace();
|
|
||||||
// }
|
|
||||||
// a(i, j, array, length);
|
|
||||||
// }
|
|
||||||
// }, 16000)));
|
|
||||||
// } catch (Throwable e) {
|
|
||||||
// e.printStackTrace();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
return new DataOutputStream(new BufferedOutputStream(new DeflaterOutputStream(new FastByteArrayOutputStream() {
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
super.close();
|
|
||||||
a(i, j, this.array, length);
|
|
||||||
}
|
|
||||||
}, new Deflater(Settings.EXPERIMENTAL.WORLD_COMPRESSION))));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized DataInputStream a(int i, int j) {
|
|
||||||
if ((i < 0) || (i >= 32) || (j < 0) || (j >= 32)) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
int k = d[(i + j * 32)];
|
|
||||||
if (k == 0) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
int l = k >> 8;
|
|
||||||
int i1 = k & 255;
|
|
||||||
if (l + i1 > f.size()) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
c.seek((long) (l * 4096));
|
|
||||||
int j1 = this.c.readInt();
|
|
||||||
if (j1 > 4096 * i1) {
|
|
||||||
return null;
|
|
||||||
} else if (j1 <= 0) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
byte b0 = c.readByte();
|
|
||||||
byte[] abyte;
|
|
||||||
if (b0 == 1) {
|
|
||||||
abyte = new byte[j1 - 1];
|
|
||||||
c.read(abyte);
|
|
||||||
return new DataInputStream(new BufferedInputStream(new GZIPInputStream(new FastByteArrayInputStream(abyte))));
|
|
||||||
} else if (b0 == 2) {
|
|
||||||
abyte = new byte[j1 - 1];
|
|
||||||
c.read(abyte);
|
|
||||||
// if (Settings.EXPERIMENTAL.FAST_WORLD_COMPRESSION) {
|
|
||||||
// return new DataInputStream(new LZ4InputStream(new FastByteArrayInputStream(abyte)));
|
|
||||||
// }
|
|
||||||
return new DataInputStream(new BufferedInputStream(new InflaterInputStream(new FastByteArrayInputStream(abyte))));
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException var9) {
|
|
||||||
var9.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Field field = RegionFile.class.getDeclaredField("c");
|
|
||||||
field.setAccessible(true);
|
|
||||||
RandomAccessFile raf2 = (RandomAccessFile) field.get(regionFile);
|
|
||||||
raf2.close();
|
|
||||||
final BufferedRandomAccessFile raf = new BufferedRandomAccessFile(file, "rw");
|
|
||||||
ReflectionUtils.setFailsafeFieldValue(field, regionFile, raf);
|
|
||||||
put(file, regionFile);
|
|
||||||
regionFile.getClass().getDeclaredField("c").set(regionFile, raf);
|
|
||||||
return regionFile;
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
;
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -199,11 +199,6 @@ public class Settings extends Config {
|
|||||||
"Directly modify the region files.",
|
"Directly modify the region files.",
|
||||||
})
|
})
|
||||||
public static boolean ANVIL_QUEUE_MODE = false;
|
public static boolean ANVIL_QUEUE_MODE = false;
|
||||||
@Comment({
|
|
||||||
"Set the default world compression",
|
|
||||||
" - Only supports Bukkit 1.10 right now"
|
|
||||||
})
|
|
||||||
public static int WORLD_COMPRESSION = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class WEB {
|
public static class WEB {
|
||||||
|
@ -206,7 +206,6 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
|||||||
|
|
||||||
public void end(FaweChunk chunk) {
|
public void end(FaweChunk chunk) {
|
||||||
chunk.end();
|
chunk.end();
|
||||||
sendChunk(chunk);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -259,7 +259,7 @@ public class MCAFile {
|
|||||||
}
|
}
|
||||||
FastByteArrayOutputStream baos = new FastByteArrayOutputStream(0);
|
FastByteArrayOutputStream baos = new FastByteArrayOutputStream(0);
|
||||||
fieldBuf4.set(baos, buffer3);
|
fieldBuf4.set(baos, buffer3);
|
||||||
DeflaterOutputStream deflater = new DeflaterOutputStream(baos, new Deflater(Settings.EXPERIMENTAL.WORLD_COMPRESSION), 1, true);
|
DeflaterOutputStream deflater = new DeflaterOutputStream(baos, new Deflater(6), 1, true);
|
||||||
fieldBuf5.set(deflater, buffer2);
|
fieldBuf5.set(deflater, buffer2);
|
||||||
BufferedOutputStream bos = new BufferedOutputStream(deflater, 1);
|
BufferedOutputStream bos = new BufferedOutputStream(deflater, 1);
|
||||||
fieldBuf6.set(bos, buffer1);
|
fieldBuf6.set(bos, buffer1);
|
||||||
|
@ -3,8 +3,8 @@ package com.boydti.fawe.object.changeset;
|
|||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.FaweInputStream;
|
import com.boydti.fawe.object.FaweInputStream;
|
||||||
import com.boydti.fawe.object.FaweOutputStream;
|
import com.boydti.fawe.object.FaweOutputStream;
|
||||||
import com.boydti.fawe.object.io.FastByteArrayInputStream;
|
|
||||||
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
||||||
|
import com.boydti.fawe.object.io.FastByteArraysInputStream;
|
||||||
import com.boydti.fawe.util.MainUtil;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
import com.sk89q.jnbt.NBTInputStream;
|
import com.sk89q.jnbt.NBTInputStream;
|
||||||
import com.sk89q.jnbt.NBTOutputStream;
|
import com.sk89q.jnbt.NBTOutputStream;
|
||||||
@ -21,23 +21,24 @@ import java.io.OutputStream;
|
|||||||
*/
|
*/
|
||||||
public class MemoryOptimizedHistory extends FaweStreamChangeSet {
|
public class MemoryOptimizedHistory extends FaweStreamChangeSet {
|
||||||
|
|
||||||
private byte[] ids;
|
private int size = 0;
|
||||||
|
private byte[][] ids;
|
||||||
private FastByteArrayOutputStream idsStream;
|
private FastByteArrayOutputStream idsStream;
|
||||||
private FaweOutputStream idsStreamZip;
|
private FaweOutputStream idsStreamZip;
|
||||||
|
|
||||||
private byte[] entC;
|
private byte[][] entC;
|
||||||
private FastByteArrayOutputStream entCStream;
|
private FastByteArrayOutputStream entCStream;
|
||||||
private NBTOutputStream entCStreamZip;
|
private NBTOutputStream entCStreamZip;
|
||||||
|
|
||||||
private byte[] entR;
|
private byte[][] entR;
|
||||||
private FastByteArrayOutputStream entRStream;
|
private FastByteArrayOutputStream entRStream;
|
||||||
private NBTOutputStream entRStreamZip;
|
private NBTOutputStream entRStreamZip;
|
||||||
|
|
||||||
private byte[] tileC;
|
private byte[][] tileC;
|
||||||
private FastByteArrayOutputStream tileCStream;
|
private FastByteArrayOutputStream tileCStream;
|
||||||
private NBTOutputStream tileCStreamZip;
|
private NBTOutputStream tileCStreamZip;
|
||||||
|
|
||||||
private byte[] tileR;
|
private byte[][] tileR;
|
||||||
private FastByteArrayOutputStream tileRStream;
|
private FastByteArrayOutputStream tileRStream;
|
||||||
private NBTOutputStream tileRStreamZip;
|
private NBTOutputStream tileRStreamZip;
|
||||||
|
|
||||||
@ -51,31 +52,32 @@ public class MemoryOptimizedHistory extends FaweStreamChangeSet {
|
|||||||
try {
|
try {
|
||||||
if (idsStream != null) {
|
if (idsStream != null) {
|
||||||
idsStreamZip.close();
|
idsStreamZip.close();
|
||||||
ids = idsStream.toByteArray();
|
size = idsStream.getSize();
|
||||||
|
ids = idsStream.toByteArrays();
|
||||||
idsStream = null;
|
idsStream = null;
|
||||||
idsStreamZip = null;
|
idsStreamZip = null;
|
||||||
}
|
}
|
||||||
if (entCStream != null) {
|
if (entCStream != null) {
|
||||||
entCStreamZip.close();
|
entCStreamZip.close();
|
||||||
entC = entCStream.toByteArray();
|
entC = entCStream.toByteArrays();
|
||||||
entCStream = null;
|
entCStream = null;
|
||||||
entCStreamZip = null;
|
entCStreamZip = null;
|
||||||
}
|
}
|
||||||
if (entRStream != null) {
|
if (entRStream != null) {
|
||||||
entRStreamZip.close();
|
entRStreamZip.close();
|
||||||
entR = entRStream.toByteArray();
|
entR = entRStream.toByteArrays();
|
||||||
entRStream = null;
|
entRStream = null;
|
||||||
entRStreamZip = null;
|
entRStreamZip = null;
|
||||||
}
|
}
|
||||||
if (tileCStream != null) {
|
if (tileCStream != null) {
|
||||||
tileCStreamZip.close();
|
tileCStreamZip.close();
|
||||||
tileC = tileCStream.toByteArray();
|
tileC = tileCStream.toByteArrays();
|
||||||
tileCStream = null;
|
tileCStream = null;
|
||||||
tileCStreamZip = null;
|
tileCStreamZip = null;
|
||||||
}
|
}
|
||||||
if (tileRStream != null) {
|
if (tileRStream != null) {
|
||||||
tileRStreamZip.close();
|
tileRStreamZip.close();
|
||||||
tileR = tileRStream.toByteArray();
|
tileR = tileRStream.toByteArrays();
|
||||||
tileRStream = null;
|
tileRStream = null;
|
||||||
tileRStreamZip = null;
|
tileRStreamZip = null;
|
||||||
}
|
}
|
||||||
@ -115,7 +117,7 @@ public class MemoryOptimizedHistory extends FaweStreamChangeSet {
|
|||||||
if (ids == null) {
|
if (ids == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
FaweInputStream result = MainUtil.getCompressedIS(new FastByteArrayInputStream(ids));
|
FaweInputStream result = MainUtil.getCompressedIS(new FastByteArraysInputStream(ids));
|
||||||
result.skip(FaweStreamChangeSet.HEADER_SIZE);
|
result.skip(FaweStreamChangeSet.HEADER_SIZE);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -158,21 +160,21 @@ public class MemoryOptimizedHistory extends FaweStreamChangeSet {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NBTInputStream getEntityCreateIS() throws IOException {
|
public NBTInputStream getEntityCreateIS() throws IOException {
|
||||||
return entC == null ? null : new NBTInputStream(MainUtil.getCompressedIS(new FastByteArrayInputStream(entC)));
|
return entC == null ? null : new NBTInputStream(MainUtil.getCompressedIS(new FastByteArraysInputStream(entC)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NBTInputStream getEntityRemoveIS() throws IOException {
|
public NBTInputStream getEntityRemoveIS() throws IOException {
|
||||||
return entR == null ? null : new NBTInputStream(MainUtil.getCompressedIS(new FastByteArrayInputStream(entR)));
|
return entR == null ? null : new NBTInputStream(MainUtil.getCompressedIS(new FastByteArraysInputStream(entR)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NBTInputStream getTileCreateIS() throws IOException {
|
public NBTInputStream getTileCreateIS() throws IOException {
|
||||||
return tileC == null ? null : new NBTInputStream(MainUtil.getCompressedIS(new FastByteArrayInputStream(tileC)));
|
return tileC == null ? null : new NBTInputStream(MainUtil.getCompressedIS(new FastByteArraysInputStream(tileC)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NBTInputStream getTileRemoveIS() throws IOException {
|
public NBTInputStream getTileRemoveIS() throws IOException {
|
||||||
return tileR == null ? null : new NBTInputStream(MainUtil.getCompressedIS(new FastByteArrayInputStream(tileR)));
|
return tileR == null ? null : new NBTInputStream(MainUtil.getCompressedIS(new FastByteArraysInputStream(tileR)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,96 +1,245 @@
|
|||||||
package com.boydti.fawe.object.io;
|
package com.boydti.fawe.object.io;
|
||||||
|
|
||||||
import com.boydti.fawe.util.ByteArrays;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.ExecutorCompletionService;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A speedy implementation of ByteArrayOutputStream. It's not synchronized, and it
|
||||||
|
* does not copy buffers when it's expanded. There's also no copying of the internal buffer
|
||||||
|
* if it's contents is extracted with the writeTo(stream) method.
|
||||||
|
*
|
||||||
|
* @author Rickard ?berg
|
||||||
|
* @author Brat Baker (Atlassian)
|
||||||
|
* @author Alexey
|
||||||
|
* @version $Date: 2008-01-19 10:09:56 +0800 (Sat, 19 Jan 2008) $ $Id: FastByteArrayOutputStream.java 3000 2008-01-19 02:09:56Z tm_jee $
|
||||||
|
*/
|
||||||
public class FastByteArrayOutputStream extends OutputStream {
|
public class FastByteArrayOutputStream extends OutputStream {
|
||||||
|
|
||||||
/**
|
private static final int DEFAULT_BLOCK_SIZE = 8192;
|
||||||
* The array backing the output stream.
|
|
||||||
*/
|
|
||||||
public final static int DEFAULT_INITIAL_CAPACITY = 16;
|
|
||||||
|
|
||||||
/**
|
private ArrayDeque<byte[]> buffers = new ArrayDeque<>();
|
||||||
* The array backing the output stream.
|
|
||||||
*/
|
|
||||||
public byte[] array;
|
|
||||||
|
|
||||||
/**
|
private byte[] buffer;
|
||||||
* The number of valid bytes in {@link #array}.
|
private int blockSize;
|
||||||
*/
|
private int index;
|
||||||
public int length;
|
private int size;
|
||||||
|
|
||||||
/**
|
|
||||||
* The current writing position.
|
|
||||||
*/
|
|
||||||
private int position;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new array output stream with an initial capacity of {@link #DEFAULT_INITIAL_CAPACITY} bytes.
|
|
||||||
*/
|
|
||||||
public FastByteArrayOutputStream() {
|
public FastByteArrayOutputStream() {
|
||||||
this(DEFAULT_INITIAL_CAPACITY);
|
this(DEFAULT_BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public FastByteArrayOutputStream(int aSize) {
|
||||||
* Creates a new array output stream with a given initial capacity.
|
blockSize = aSize;
|
||||||
*
|
buffer = new byte[blockSize];
|
||||||
* @param initialCapacity the initial length of the backing array.
|
|
||||||
*/
|
|
||||||
public FastByteArrayOutputStream(final int initialCapacity) {
|
|
||||||
array = new byte[initialCapacity];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new array output stream wrapping a given byte array.
|
public int getSize() {
|
||||||
*
|
return size + index;
|
||||||
* @param a the byte array to wrap.
|
|
||||||
*/
|
|
||||||
public FastByteArrayOutputStream(final byte[] a) {
|
|
||||||
array = a;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public byte[][] toByteArrays() {
|
||||||
* Marks this array output stream as empty.
|
if (index > 0) {
|
||||||
*/
|
byte[] buf2 = new byte[index];
|
||||||
public void reset() {
|
System.arraycopy(buffer, 0, buf2, 0, index);
|
||||||
length = 0;
|
buffers.addLast(buf2);
|
||||||
position = 0;
|
size += index;
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
byte[][] res = new byte[buffers.size()][];
|
||||||
|
int i = 0;
|
||||||
|
for (byte[] bytes : buffers) {
|
||||||
|
res[i++] = bytes;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void trim() {
|
public byte[] toByteArray(ExecutorCompletionService service) {
|
||||||
this.array = ByteArrays.trim(this.array, this.length);
|
if (buffers.size() < 8) {
|
||||||
|
return toByteArray();
|
||||||
|
}
|
||||||
|
final byte[] data = new byte[getSize()];
|
||||||
|
// Check if we have a list of buffers
|
||||||
|
int pos = 0;
|
||||||
|
int count = 0;
|
||||||
|
if (buffers != null) {
|
||||||
|
for (final byte[] bytes : buffers) {
|
||||||
|
final int finalPos = pos;
|
||||||
|
count++;
|
||||||
|
service.submit(new Callable() {
|
||||||
|
@Override
|
||||||
|
public Object call() throws Exception {
|
||||||
|
System.arraycopy(bytes, 0, data, finalPos, bytes.length);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
pos += bytes.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
service.take();
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
// write the internal buffer directly
|
||||||
|
System.arraycopy(buffer, 0, data, pos, index);
|
||||||
|
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] toByteArray() {
|
public byte[] toByteArray() {
|
||||||
trim();
|
byte[] data = new byte[getSize()];
|
||||||
return array;
|
|
||||||
|
// Check if we have a list of buffers
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
if (buffers != null) {
|
||||||
|
for (byte[] bytes : buffers) {
|
||||||
|
System.arraycopy(bytes, 0, data, pos, bytes.length);
|
||||||
|
pos += bytes.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// write the internal buffer directly
|
||||||
|
System.arraycopy(buffer, 0, data, pos, index);
|
||||||
|
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void write(final int b) {
|
public String toString() {
|
||||||
if (position >= array.length) array = ByteArrays.grow(array, position + 1, length);
|
return new String(toByteArray());
|
||||||
array[position++] = (byte) b;
|
|
||||||
if (length < position) length = position;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void write(final byte[] b, final int off, final int len) throws IOException {
|
@Override
|
||||||
ByteArrays.ensureOffsetLength(b, off, len);
|
public void write(byte[] b) throws IOException {
|
||||||
if (position + len > array.length) array = ByteArrays.grow(array, position + len, position);
|
if (b.length > blockSize) {
|
||||||
System.arraycopy(b, off, array, position, len);
|
if (index > 0) {
|
||||||
if (position + len > length) length = position += len;
|
byte[] buf2 = new byte[index];
|
||||||
|
System.arraycopy(buffer, 0, buf2, 0, index);
|
||||||
|
buffer = buf2;
|
||||||
|
addBuffer();
|
||||||
|
}
|
||||||
|
size += b.length;
|
||||||
|
buffers.addLast(b);
|
||||||
|
} else {
|
||||||
|
write(b, 0, b.length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void position(long newPosition) {
|
public void write(int datum) {
|
||||||
if (position > Integer.MAX_VALUE) throw new IllegalArgumentException("Position too large: " + newPosition);
|
if (index == blockSize) {
|
||||||
position = (int) newPosition;
|
addBuffer();
|
||||||
|
}
|
||||||
|
// store the byte
|
||||||
|
buffer[index++] = (byte) datum;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long position() {
|
public void write(byte[] data, int offset, int length) throws IOException {
|
||||||
return position;
|
if ((offset < 0) || ((offset + length) > data.length) || (length < 0)) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
} else {
|
||||||
|
if ((index + length) > blockSize) {
|
||||||
|
int copyLength;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (index == blockSize) {
|
||||||
|
addBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
copyLength = blockSize - index;
|
||||||
|
|
||||||
|
if (length < copyLength) {
|
||||||
|
copyLength = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.arraycopy(data, offset, buffer, index, copyLength);
|
||||||
|
offset += copyLength;
|
||||||
|
index += copyLength;
|
||||||
|
length -= copyLength;
|
||||||
|
} while (length > 0);
|
||||||
|
} else {
|
||||||
|
// Copy in the subarray
|
||||||
|
System.arraycopy(data, offset, buffer, index, length);
|
||||||
|
index += length;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public long length() throws IOException {
|
public void writeTo(OutputStream out) throws IOException {
|
||||||
return length;
|
// Check if we have a list of buffers
|
||||||
|
if (buffers != null) {
|
||||||
|
Iterator iter = buffers.iterator();
|
||||||
|
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
byte[] bytes = (byte[]) iter.next();
|
||||||
|
out.write(bytes, 0, blockSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// write the internal buffer directly
|
||||||
|
out.write(buffer, 0, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeTo(RandomAccessFile out) throws IOException {
|
||||||
|
// Check if we have a list of buffers
|
||||||
|
if (buffers != null) {
|
||||||
|
Iterator iter = buffers.iterator();
|
||||||
|
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
byte[] bytes = (byte[]) iter.next();
|
||||||
|
out.write(bytes, 0, blockSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// write the internal buffer directly
|
||||||
|
out.write(buffer, 0, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeTo(Writer out, String encoding) throws IOException {
|
||||||
|
if (buffers != null) {
|
||||||
|
writeToViaSmoosh(out, encoding);
|
||||||
|
} else {
|
||||||
|
writeToViaString(out, encoding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeToViaString(Writer out, String encoding) throws IOException {
|
||||||
|
byte[] bufferToWrite = buffer; // this is always the last buffer to write
|
||||||
|
int bufferToWriteLen = index; // index points to our place in the last buffer
|
||||||
|
writeToImpl(out, encoding, bufferToWrite, bufferToWriteLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeToViaSmoosh(Writer out, String encoding) throws IOException {
|
||||||
|
byte[] bufferToWrite = toByteArray();
|
||||||
|
int bufferToWriteLen = bufferToWrite.length;
|
||||||
|
writeToImpl(out, encoding, bufferToWrite, bufferToWriteLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeToImpl(Writer out, String encoding, byte[] bufferToWrite, int bufferToWriteLen)
|
||||||
|
throws IOException {
|
||||||
|
String writeStr;
|
||||||
|
if (encoding != null) {
|
||||||
|
writeStr = new String(bufferToWrite, 0, bufferToWriteLen, encoding);
|
||||||
|
} else {
|
||||||
|
writeStr = new String(bufferToWrite, 0, bufferToWriteLen);
|
||||||
|
}
|
||||||
|
out.write(writeStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addBuffer() {
|
||||||
|
buffers.addLast(buffer);
|
||||||
|
buffer = new byte[blockSize];
|
||||||
|
size += index;
|
||||||
|
index = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,110 @@
|
|||||||
|
package com.boydti.fawe.object.io;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
public class FastByteArraysInputStream extends InputStream {
|
||||||
|
private final byte[][] buffers;
|
||||||
|
private final int length;
|
||||||
|
|
||||||
|
private byte[] current;
|
||||||
|
|
||||||
|
private int layer;
|
||||||
|
private int localIndex;
|
||||||
|
private int globalIndex;
|
||||||
|
private int curLen;
|
||||||
|
|
||||||
|
|
||||||
|
public FastByteArraysInputStream(byte[][] buffers) {
|
||||||
|
this.buffers = buffers;
|
||||||
|
int size = 0;
|
||||||
|
for (byte[] bytes : buffers) {
|
||||||
|
size += bytes.length;
|
||||||
|
}
|
||||||
|
this.length = size;
|
||||||
|
current = buffers.length == 0 ? new byte[layer++] : buffers[layer++];
|
||||||
|
curLen = current.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean markSupported() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mark(int dummy) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int available() {
|
||||||
|
return this.length - this.globalIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long skip(long n) {
|
||||||
|
if (n <= this.length - this.globalIndex) {
|
||||||
|
this.globalIndex += (int) n;
|
||||||
|
this.localIndex += (int) n;
|
||||||
|
ensureBuffer();
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
n = this.length - this.globalIndex;
|
||||||
|
layer = buffers.length - 1;
|
||||||
|
this.current = buffers[layer];
|
||||||
|
this.curLen = current.length;
|
||||||
|
this.localIndex = current.length;
|
||||||
|
this.globalIndex = this.length;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read() {
|
||||||
|
if (curLen != localIndex) {
|
||||||
|
globalIndex++;
|
||||||
|
return this.current[localIndex++] & 0xFF;
|
||||||
|
} else if (length == globalIndex) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
localIndex = 0;
|
||||||
|
current = buffers[layer++];
|
||||||
|
curLen = current.length;
|
||||||
|
globalIndex++;
|
||||||
|
return this.current[localIndex++] & 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(byte[] b, int offset, int length) {
|
||||||
|
if (this.length <= this.globalIndex) {
|
||||||
|
return length == 0 ? 0 : -1;
|
||||||
|
}
|
||||||
|
int n = Math.min(length, this.length - this.globalIndex);
|
||||||
|
int read = 0;
|
||||||
|
int amount = Math.min(curLen - localIndex, n - read);
|
||||||
|
System.arraycopy(this.current, localIndex, b, offset + read, amount);
|
||||||
|
read += amount;
|
||||||
|
localIndex += amount;
|
||||||
|
globalIndex += amount;
|
||||||
|
ensureBuffer();
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ensureBuffer() {
|
||||||
|
while (localIndex >= curLen && layer < buffers.length) {
|
||||||
|
localIndex -= curLen;
|
||||||
|
current = buffers[layer++];
|
||||||
|
this.curLen = current.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public long length() {
|
||||||
|
return this.length;
|
||||||
|
}
|
||||||
|
}
|
@ -59,7 +59,7 @@ public class FaweSchematicHandler extends SchematicHandler {
|
|||||||
Location pos1 = corners[0];
|
Location pos1 = corners[0];
|
||||||
Location pos2 = corners[1];
|
Location pos2 = corners[1];
|
||||||
final CuboidRegion region = new CuboidRegion(new Vector(pos1.getX(), pos1.getY(), pos1.getZ()), new Vector(pos2.getX(), pos2.getY(), pos2.getZ()));
|
final CuboidRegion region = new CuboidRegion(new Vector(pos1.getX(), pos1.getY(), pos1.getZ()), new Vector(pos2.getX(), pos2.getY(), pos2.getZ()));
|
||||||
final EditSession editSession = new EditSessionBuilder(pos1.getWorld()).checkMemory(false).fastmode(true).limitUnlimited().changeSetNull().autoQueue(false).build();
|
final EditSession editSession = new EditSessionBuilder(world).checkMemory(false).fastmode(true).limitUnlimited().changeSetNull().autoQueue(false).build();
|
||||||
|
|
||||||
final int mx = pos1.getX();
|
final int mx = pos1.getX();
|
||||||
final int my = pos1.getY();
|
final int my = pos1.getY();
|
||||||
@ -144,12 +144,13 @@ public class FaweSchematicHandler extends SchematicHandler {
|
|||||||
@Override
|
@Override
|
||||||
public void run(OutputStream output) {
|
public void run(OutputStream output) {
|
||||||
try {
|
try {
|
||||||
GZIPOutputStream gzip = new GZIPOutputStream(output, true);
|
try (GZIPOutputStream gzip = new GZIPOutputStream(output, true)) {
|
||||||
com.sk89q.jnbt.CompoundTag weTag = (com.sk89q.jnbt.CompoundTag) FaweCache.asTag(tag);
|
com.sk89q.jnbt.CompoundTag weTag = (com.sk89q.jnbt.CompoundTag) FaweCache.asTag(tag);
|
||||||
NBTOutputStream nos = new NBTOutputStream(gzip);
|
try (NBTOutputStream nos = new NBTOutputStream(gzip)) {
|
||||||
Map<String, com.sk89q.jnbt.Tag> map = weTag.getValue();
|
Map<String, com.sk89q.jnbt.Tag> map = weTag.getValue();
|
||||||
nos.writeNamedTag("Schematic", map.containsKey("Schematic") ? map.get("Schematic") : weTag);
|
nos.writeNamedTag("Schematic", map.containsKey("Schematic") ? map.get("Schematic") : weTag);
|
||||||
gzip.flush();
|
}
|
||||||
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package com.boydti.fawe.util;
|
package com.boydti.fawe.util;
|
||||||
|
|
||||||
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.FaweLimit;
|
||||||
@ -20,10 +19,12 @@ import java.util.UUID;
|
|||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
public class EditSessionBuilder {
|
public class EditSessionBuilder {
|
||||||
private World world;
|
private World world;
|
||||||
|
private String worldName;
|
||||||
private FaweQueue queue;
|
private FaweQueue queue;
|
||||||
private FawePlayer player;
|
private FawePlayer player;
|
||||||
private FaweLimit limit;
|
private FaweLimit limit;
|
||||||
@ -57,8 +58,9 @@ public class EditSessionBuilder {
|
|||||||
this.world = world;
|
this.world = world;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EditSessionBuilder(@Nonnull String world) {
|
public EditSessionBuilder(@Nonnull String worldName) {
|
||||||
this(FaweAPI.getWorld(world));
|
checkNotNull(worldName);
|
||||||
|
this.worldName = worldName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EditSessionBuilder player(@Nullable FawePlayer player) {
|
public EditSessionBuilder player(@Nullable FawePlayer player) {
|
||||||
@ -164,6 +166,6 @@ public class EditSessionBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public EditSession build() {
|
public EditSession build() {
|
||||||
return new EditSession(world, queue, player, limit, changeSet, allowedRegions, autoQueue, fastmode, checkMemory, combineStages, blockBag, eventBus, event);
|
return new EditSession(worldName, world, queue, player, limit, changeSet, allowedRegions, autoQueue, fastmode, checkMemory, combineStages, blockBag, eventBus, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.boydti.fawe.util;
|
package com.boydti.fawe.util;
|
||||||
|
|
||||||
|
import com.boydti.fawe.object.RunnableVal;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -16,17 +17,15 @@ public class HastebinUtility {
|
|||||||
public static final String BIN_URL = "http://hastebin.com/documents", USER_AGENT = "Mozilla/5.0";
|
public static final String BIN_URL = "http://hastebin.com/documents", USER_AGENT = "Mozilla/5.0";
|
||||||
public static final Pattern PATTERN = Pattern.compile("\\{\"key\":\"([\\S\\s]*)\"\\}");
|
public static final Pattern PATTERN = Pattern.compile("\\{\"key\":\"([\\S\\s]*)\"\\}");
|
||||||
|
|
||||||
public static String upload(final String string) throws IOException {
|
public static String upload(final RunnableVal<DataOutputStream> writeTask) throws IOException {
|
||||||
final URL url = new URL(BIN_URL);
|
final URL url = new URL(BIN_URL);
|
||||||
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||||
|
|
||||||
connection.setRequestMethod("POST");
|
connection.setRequestMethod("POST");
|
||||||
connection.setRequestProperty("User-Agent", USER_AGENT);
|
connection.setRequestProperty("User-Agent", USER_AGENT);
|
||||||
connection.setDoOutput(true);
|
connection.setDoOutput(true);
|
||||||
|
try (DataOutputStream os = new DataOutputStream(connection.getOutputStream())) {
|
||||||
try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) {
|
writeTask.run(os);
|
||||||
outputStream.write(string.getBytes());
|
|
||||||
outputStream.flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder response;
|
StringBuilder response;
|
||||||
@ -47,6 +46,19 @@ public class HastebinUtility {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String upload(final String s) throws IOException {
|
||||||
|
return upload(new RunnableVal<DataOutputStream>() {
|
||||||
|
@Override
|
||||||
|
public void run(DataOutputStream value) {
|
||||||
|
try {
|
||||||
|
value.writeChars(s);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public static String upload(final File file) throws IOException {
|
public static String upload(final File file) throws IOException {
|
||||||
final StringBuilder content = new StringBuilder();
|
final StringBuilder content = new StringBuilder();
|
||||||
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
||||||
@ -57,6 +69,7 @@ public class HastebinUtility {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return upload(content.toString());
|
return upload(content.toString());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,10 @@ package com.boydti.fawe.wrappers;
|
|||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
import com.boydti.fawe.object.RunnableVal;
|
import com.boydti.fawe.object.RunnableVal;
|
||||||
import com.boydti.fawe.util.MainUtil;
|
|
||||||
import com.boydti.fawe.util.TaskManager;
|
import com.boydti.fawe.util.TaskManager;
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
import com.sk89q.worldedit.EditSessionFactory;
|
import com.sk89q.worldedit.EditSessionFactory;
|
||||||
import com.sk89q.worldedit.LocalSession;
|
import com.sk89q.worldedit.LocalSession;
|
||||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
|
||||||
import com.sk89q.worldedit.PlayerDirection;
|
import com.sk89q.worldedit.PlayerDirection;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
@ -202,14 +200,10 @@ public class PlayerWrapper implements Player {
|
|||||||
public void floatAt(final int x, final int y, final int z, final boolean alwaysGlass) {
|
public void floatAt(final int x, final int y, final int z, final boolean alwaysGlass) {
|
||||||
EditSessionFactory factory = WorldEdit.getInstance().getEditSessionFactory();
|
EditSessionFactory factory = WorldEdit.getInstance().getEditSessionFactory();
|
||||||
final EditSession edit = factory.getEditSession(parent.getWorld(), -1, null, this);
|
final EditSession edit = factory.getEditSession(parent.getWorld(), -1, null, this);
|
||||||
try {
|
edit.setBlockFast(new Vector(x, y - 1, z), new BaseBlock( BlockType.GLASS.getID()));
|
||||||
edit.setBlock(new Vector(x, y - 1, z), new BaseBlock( BlockType.GLASS.getID()));
|
LocalSession session = Fawe.get().getWorldEdit().getSession(this);
|
||||||
LocalSession session = Fawe.get().getWorldEdit().getSession(this);
|
if (session != null) {
|
||||||
if (session != null) {
|
session.remember(edit, true, false, FawePlayer.wrap(this).getLimit().MAX_HISTORY);
|
||||||
session.remember(edit, true, false, FawePlayer.wrap(this).getLimit().MAX_HISTORY);
|
|
||||||
}
|
|
||||||
} catch (MaxChangedBlocksException e) {
|
|
||||||
MainUtil.handleError(e);
|
|
||||||
}
|
}
|
||||||
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
package com.boydti.fawe.wrappers;
|
package com.boydti.fawe.wrappers;
|
||||||
|
|
||||||
import com.boydti.fawe.FaweCache;
|
|
||||||
import com.boydti.fawe.object.FaweQueue;
|
|
||||||
import com.boydti.fawe.object.RunnableVal;
|
import com.boydti.fawe.object.RunnableVal;
|
||||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
|
||||||
import com.boydti.fawe.object.extent.FaweRegionExtent;
|
|
||||||
import com.boydti.fawe.util.MainUtil;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
import com.boydti.fawe.util.TaskManager;
|
import com.boydti.fawe.util.TaskManager;
|
||||||
import com.sk89q.worldedit.BlockVector2D;
|
import com.sk89q.worldedit.BlockVector2D;
|
||||||
@ -22,7 +18,6 @@ import com.sk89q.worldedit.entity.Entity;
|
|||||||
import com.sk89q.worldedit.extension.platform.Platform;
|
import com.sk89q.worldedit.extension.platform.Platform;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import com.sk89q.worldedit.function.operation.Operation;
|
import com.sk89q.worldedit.function.operation.Operation;
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.util.Direction;
|
import com.sk89q.worldedit.util.Direction;
|
||||||
import com.sk89q.worldedit.util.Location;
|
import com.sk89q.worldedit.util.Location;
|
||||||
@ -31,7 +26,6 @@ import com.sk89q.worldedit.world.AbstractWorld;
|
|||||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||||
import com.sk89q.worldedit.world.registry.WorldData;
|
import com.sk89q.worldedit.world.registry.WorldData;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class WorldWrapper extends LocalWorld {
|
public class WorldWrapper extends LocalWorld {
|
||||||
@ -250,101 +244,7 @@ public class WorldWrapper extends LocalWorld {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean regenerate(final Region region, final EditSession session) {
|
public boolean regenerate(final Region region, final EditSession session) {
|
||||||
final FaweQueue queue = session.getQueue();
|
return session.regenerate(region);
|
||||||
queue.setChangeTask(null);
|
|
||||||
final FaweChangeSet fcs = (FaweChangeSet) session.getChangeSet();
|
|
||||||
final FaweRegionExtent fe = session.getRegionExtent();
|
|
||||||
session.setSize(1);
|
|
||||||
final boolean cuboid = region instanceof CuboidRegion;
|
|
||||||
Set<Vector2D> chunks = region.getChunks();
|
|
||||||
for (Vector2D chunk : chunks) {
|
|
||||||
final int cx = chunk.getBlockX();
|
|
||||||
final int cz = chunk.getBlockZ();
|
|
||||||
final int bx = cx << 4;
|
|
||||||
final int bz = cz << 4;
|
|
||||||
Vector cmin = new Vector(bx, 0, bz);
|
|
||||||
Vector cmax = cmin.add(15, getMaxY(), 15);
|
|
||||||
final boolean containsBot1 = (fe == null || fe.contains(cmin.getBlockX(), cmin.getBlockY(), cmin.getBlockZ()));
|
|
||||||
final boolean containsBot2 = region.contains(cmin);
|
|
||||||
final boolean containsTop1 = (fe == null || fe.contains(cmax.getBlockX(), cmax.getBlockY(), cmax.getBlockZ()));
|
|
||||||
final boolean containsTop2 = region.contains(cmax);
|
|
||||||
if ((containsBot2 && containsTop2 && !containsBot1 && !containsTop1)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
RunnableVal<Vector2D> r = new RunnableVal<Vector2D>() {
|
|
||||||
@Override
|
|
||||||
public void run(Vector2D chunk) {
|
|
||||||
if (cuboid && containsBot1 && containsBot2 && containsTop1 && containsTop2) {
|
|
||||||
if (fcs != null) {
|
|
||||||
for (int x = 0; x < 16; x++) {
|
|
||||||
int xx = x + bx;
|
|
||||||
for (int z = 0; z < 16; z++) {
|
|
||||||
int zz = z + bz;
|
|
||||||
for (int y = 0; y < getMaxY() + 1; y++) {
|
|
||||||
int from = queue.getCombinedId4DataDebug(xx, y, zz, 0, session);
|
|
||||||
if (!FaweCache.hasNBT(from >> 4)) {
|
|
||||||
fcs.add(xx, y, zz, from, 0);
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
Vector loc = new Vector(xx, y, zz);
|
|
||||||
BaseBlock block = getLazyBlock(loc);
|
|
||||||
fcs.add(loc, block, FaweCache.CACHE_BLOCK[0]);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
fcs.add(xx, y, zz, from, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Vector mutable = new Vector(0,0,0);
|
|
||||||
for (int x = 0; x < 16; x++) {
|
|
||||||
int xx = x + bx;
|
|
||||||
mutable.x = xx;
|
|
||||||
for (int z = 0; z < 16; z++) {
|
|
||||||
int zz = z + bz;
|
|
||||||
mutable.z = zz;
|
|
||||||
for (int y = 0; y < getMaxY() + 1; y++) {
|
|
||||||
mutable.y = y;
|
|
||||||
int from = queue.getCombinedId4Data(xx, y, zz);
|
|
||||||
boolean contains = (fe == null || fe.contains(xx, y, zz)) && region.contains(mutable);
|
|
||||||
if (contains) {
|
|
||||||
if (fcs != null) {
|
|
||||||
if (!FaweCache.hasNBT(from >> 4)) {
|
|
||||||
fcs.add(xx, y, zz, from, 0);
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
BaseBlock block = getLazyBlock(mutable);
|
|
||||||
fcs.add(mutable, block, FaweCache.CACHE_BLOCK[0]);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
fcs.add(xx, y, zz, from, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
short id = (short) (from >> 4);
|
|
||||||
byte data = (byte) (from & 0xf);
|
|
||||||
queue.setBlock(xx, y, zz, id, data);
|
|
||||||
if (FaweCache.hasNBT(id)) {
|
|
||||||
BaseBlock block = getBlock(new Vector(xx, y, zz));
|
|
||||||
if (block.hasNbtData()) {
|
|
||||||
queue.setTile(xx, y, zz, block.getNbtData());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
queue.regenerateChunk(cx, cz);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
r.value = chunk;
|
|
||||||
TaskManager.IMP.sync(r);
|
|
||||||
}
|
|
||||||
session.flushQueue();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -689,7 +689,7 @@ public class CuboidClipboard {
|
|||||||
if (noAir && block.isAir()) {
|
if (noAir && block.isAir()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
editSession.setBlock(new Vector(x, y, z).add(newOrigin), block);
|
editSession.setBlockFast(new Vector(x, y, z).add(newOrigin), block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
package com.sk89q.worldedit;
|
package com.sk89q.worldedit;
|
||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
|
import com.boydti.fawe.FaweAPI;
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.boydti.fawe.config.BBC;
|
import com.boydti.fawe.config.BBC;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
@ -33,6 +34,7 @@ import com.boydti.fawe.object.FaweQueue;
|
|||||||
import com.boydti.fawe.object.HistoryExtent;
|
import com.boydti.fawe.object.HistoryExtent;
|
||||||
import com.boydti.fawe.object.NullChangeSet;
|
import com.boydti.fawe.object.NullChangeSet;
|
||||||
import com.boydti.fawe.object.RegionWrapper;
|
import com.boydti.fawe.object.RegionWrapper;
|
||||||
|
import com.boydti.fawe.object.RunnableVal;
|
||||||
import com.boydti.fawe.object.changeset.CPUOptimizedChangeSet;
|
import com.boydti.fawe.object.changeset.CPUOptimizedChangeSet;
|
||||||
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;
|
||||||
@ -46,8 +48,11 @@ import com.boydti.fawe.util.ExtentTraverser;
|
|||||||
import com.boydti.fawe.util.MemUtil;
|
import com.boydti.fawe.util.MemUtil;
|
||||||
import com.boydti.fawe.util.Perm;
|
import com.boydti.fawe.util.Perm;
|
||||||
import com.boydti.fawe.util.SetQueue;
|
import com.boydti.fawe.util.SetQueue;
|
||||||
|
import com.boydti.fawe.util.TaskManager;
|
||||||
import com.boydti.fawe.wrappers.WorldWrapper;
|
import com.boydti.fawe.wrappers.WorldWrapper;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||||
import com.sk89q.worldedit.blocks.BlockID;
|
import com.sk89q.worldedit.blocks.BlockID;
|
||||||
import com.sk89q.worldedit.blocks.BlockType;
|
import com.sk89q.worldedit.blocks.BlockType;
|
||||||
import com.sk89q.worldedit.entity.BaseEntity;
|
import com.sk89q.worldedit.entity.BaseEntity;
|
||||||
@ -144,7 +149,7 @@ import static com.sk89q.worldedit.regions.Regions.minimumBlockY;
|
|||||||
* {@link Extent}s that are chained together. For example, history is logged
|
* {@link Extent}s that are chained together. For example, history is logged
|
||||||
* using the {@link ChangeSetExtent}.</p>
|
* using the {@link ChangeSetExtent}.</p>
|
||||||
*/
|
*/
|
||||||
public class EditSession implements Extent {
|
public class EditSession extends AbstractWorld {
|
||||||
/**
|
/**
|
||||||
* Used by {@link #setBlock(Vector, BaseBlock, Stage)} to
|
* Used by {@link #setBlock(Vector, BaseBlock, Stage)} to
|
||||||
* determine which {@link Extent}s should be bypassed.
|
* determine which {@link Extent}s should be bypassed.
|
||||||
@ -154,6 +159,7 @@ public class EditSession implements Extent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private World world;
|
private World world;
|
||||||
|
private String worldName;
|
||||||
private FaweQueue queue;
|
private FaweQueue queue;
|
||||||
private AbstractDelegateExtent extent;
|
private AbstractDelegateExtent extent;
|
||||||
private HistoryExtent history;
|
private HistoryExtent history;
|
||||||
@ -182,7 +188,14 @@ public class EditSession implements Extent {
|
|||||||
PlayerDirection.UP.vector(),
|
PlayerDirection.UP.vector(),
|
||||||
PlayerDirection.DOWN.vector(), };
|
PlayerDirection.DOWN.vector(), };
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public EditSession(@Nonnull World world, @Nullable FaweQueue queue, @Nullable FawePlayer player, @Nullable FaweLimit limit, @Nullable FaweChangeSet changeSet, @Nullable RegionWrapper[] allowedRegions, @Nullable Boolean autoQueue, @Nullable Boolean fastmode, @Nullable Boolean checkMemory, @Nullable Boolean combineStages, @Nullable BlockBag blockBag, @Nullable EventBus bus, @Nullable EditSessionEvent event) {
|
public EditSession(@Nonnull World world, @Nullable FaweQueue queue, @Nullable FawePlayer player, @Nullable FaweLimit limit, @Nullable FaweChangeSet changeSet, @Nullable RegionWrapper[] allowedRegions, @Nullable Boolean autoQueue, @Nullable Boolean fastmode, @Nullable Boolean checkMemory, @Nullable Boolean combineStages, @Nullable BlockBag blockBag, @Nullable EventBus bus, @Nullable EditSessionEvent event) {
|
||||||
|
this(null, world, queue, player, limit, changeSet, allowedRegions, autoQueue, fastmode, checkMemory, combineStages, blockBag, bus, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EditSession(@Nullable String worldName, @Nullable World world, @Nullable FaweQueue queue, @Nullable FawePlayer player, @Nullable FaweLimit limit, @Nullable FaweChangeSet changeSet, @Nullable RegionWrapper[] allowedRegions, @Nullable Boolean autoQueue, @Nullable Boolean fastmode, @Nullable Boolean checkMemory, @Nullable Boolean combineStages, @Nullable BlockBag blockBag, @Nullable EventBus bus, @Nullable EditSessionEvent event) {
|
||||||
|
this.worldName = worldName == null ? world == null ? queue == null ? "" : queue.getWorldName() : world.getName() : worldName;
|
||||||
|
if (world == null && this.worldName != null) world = FaweAPI.getWorld(this.worldName);
|
||||||
this.world = world = WorldWrapper.wrap((AbstractWorld) world);
|
this.world = world = WorldWrapper.wrap((AbstractWorld) world);
|
||||||
if (bus == null) {
|
if (bus == null) {
|
||||||
bus = WorldEdit.getInstance().getEventBus();
|
bus = WorldEdit.getInstance().getEventBus();
|
||||||
@ -255,7 +268,7 @@ public class EditSession implements Extent {
|
|||||||
if (world instanceof MCAWorld) {
|
if (world instanceof MCAWorld) {
|
||||||
queue = ((MCAWorld) world).getQueue();
|
queue = ((MCAWorld) world).getQueue();
|
||||||
} else {
|
} else {
|
||||||
queue = SetQueue.IMP.getNewQueue(world, fastmode, autoQueue);
|
queue = SetQueue.IMP.getNewQueue(this, fastmode, autoQueue);
|
||||||
}
|
}
|
||||||
} else if (Settings.EXPERIMENTAL.ANVIL_QUEUE_MODE && !(queue instanceof MCAQueue)) {
|
} else if (Settings.EXPERIMENTAL.ANVIL_QUEUE_MODE && !(queue instanceof MCAQueue)) {
|
||||||
queue = new MCAQueue(queue);
|
queue = new MCAQueue(queue);
|
||||||
@ -283,7 +296,7 @@ public class EditSession implements Extent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.extent = wrapExtent(this.extent, bus, event, Stage.BEFORE_HISTORY);
|
this.extent = wrapExtent(this.extent, bus, event, Stage.BEFORE_HISTORY);
|
||||||
this.maxY = this.world == null ? 255 : world.getMaxY();
|
this.maxY = getWorld() == null ? 255 : world.getMaxY();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -791,7 +804,9 @@ public class EditSession implements Extent {
|
|||||||
* @param naturalOnly look at natural blocks or all blocks
|
* @param naturalOnly look at natural blocks or all blocks
|
||||||
* @return height of highest block found or 'minY'
|
* @return height of highest block found or 'minY'
|
||||||
*/
|
*/
|
||||||
public int getHighestTerrainBlock(final int x, final int z, final int minY, final int maxY, final boolean naturalOnly) {
|
public int getHighestTerrainBlock(final int x, final int z, int minY, int maxY, final boolean naturalOnly) {
|
||||||
|
maxY = Math.min(getMaximumPoint().getBlockY(), Math.max(0, maxY));
|
||||||
|
minY = Math.max(0, minY);
|
||||||
for (int y = maxY; y >= minY; --y) {
|
for (int y = maxY; y >= minY; --y) {
|
||||||
BaseBlock block = getLazyBlock(x, y, z);
|
BaseBlock block = getLazyBlock(x, y, z);
|
||||||
final int id = block.getId();
|
final int id = block.getId();
|
||||||
@ -956,7 +971,11 @@ public class EditSession implements Extent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setBlock(final Vector position, final BaseBlock block) throws MaxChangedBlocksException {
|
public boolean setBlock(final Vector position, final BaseBlock block, final boolean ignorePhysics) throws MaxChangedBlocksException {
|
||||||
|
return setBlockFast(position, block);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setBlockFast(final Vector position, final BaseBlock block) {
|
||||||
this.changes++;
|
this.changes++;
|
||||||
try {
|
try {
|
||||||
return this.extent.setBlock(position, block);
|
return this.extent.setBlock(position, block);
|
||||||
@ -975,7 +994,7 @@ public class EditSession implements Extent {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public boolean setBlock(final Vector position, final Pattern pattern) throws MaxChangedBlocksException {
|
public boolean setBlock(final Vector position, final Pattern pattern) throws MaxChangedBlocksException {
|
||||||
return this.setBlock(position, pattern.next(position));
|
return this.setBlockFast(position, pattern.next(position));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1020,7 +1039,7 @@ public class EditSession implements Extent {
|
|||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public boolean setBlockIfAir(final Vector position, final BaseBlock block) throws MaxChangedBlocksException {
|
public boolean setBlockIfAir(final Vector position, final BaseBlock block) throws MaxChangedBlocksException {
|
||||||
return this.getBlock(position).isAir() && this.setBlock(position, block);
|
return this.getBlock(position).isAir() && this.setBlockFast(position, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1756,15 +1775,16 @@ public class EditSession implements Extent {
|
|||||||
checkNotNull(origin);
|
checkNotNull(origin);
|
||||||
checkArgument(radius >= 0, "radius >= 0 required");
|
checkArgument(radius >= 0, "radius >= 0 required");
|
||||||
Mask liquidMask;
|
Mask liquidMask;
|
||||||
if (getWorld() != null) {
|
// Not thread safe, use hardcoded liquidmask
|
||||||
liquidMask = getWorld().createLiquidMask();
|
// if (getWorld() != null) {
|
||||||
} else {
|
// liquidMask = getWorld().createLiquidMask();
|
||||||
|
// } else {
|
||||||
liquidMask = new BlockMask(this,
|
liquidMask = new BlockMask(this,
|
||||||
new BaseBlock(BlockID.STATIONARY_LAVA, -1),
|
new BaseBlock(BlockID.STATIONARY_LAVA, -1),
|
||||||
new BaseBlock(BlockID.LAVA, -1),
|
new BaseBlock(BlockID.LAVA, -1),
|
||||||
new BaseBlock(BlockID.STATIONARY_WATER, -1),
|
new BaseBlock(BlockID.STATIONARY_WATER, -1),
|
||||||
new BaseBlock(BlockID.WATER, -1));
|
new BaseBlock(BlockID.WATER, -1));
|
||||||
}
|
// }
|
||||||
final MaskIntersection mask = new MaskIntersection(
|
final MaskIntersection mask = new MaskIntersection(
|
||||||
new BoundedHeightMask(0, EditSession.this.getMaximumPoint().getBlockY()),
|
new BoundedHeightMask(0, EditSession.this.getMaximumPoint().getBlockY()),
|
||||||
new RegionMask(
|
new RegionMask(
|
||||||
@ -2471,7 +2491,7 @@ public class EditSession implements Extent {
|
|||||||
// read block from world
|
// read block from world
|
||||||
BaseBlock material = FaweCache.CACHE_BLOCK[this.queue.getCombinedId4DataDebug(sourcePosition.getBlockX(), sourcePosition.getBlockY(), sourcePosition.getBlockZ(), 0, this)];
|
BaseBlock material = FaweCache.CACHE_BLOCK[this.queue.getCombinedId4DataDebug(sourcePosition.getBlockX(), sourcePosition.getBlockY(), sourcePosition.getBlockZ(), 0, this)];
|
||||||
// queue operation
|
// queue operation
|
||||||
this.setBlock(position, material);
|
this.setBlockFast(position, material);
|
||||||
}
|
}
|
||||||
return changes;
|
return changes;
|
||||||
}
|
}
|
||||||
@ -2545,7 +2565,7 @@ public class EditSession implements Extent {
|
|||||||
continue outer;
|
continue outer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.setBlock(position, pattern.next(position));
|
this.setBlockFast(position, pattern.next(position));
|
||||||
}
|
}
|
||||||
|
|
||||||
return changes;
|
return changes;
|
||||||
@ -2812,6 +2832,156 @@ public class EditSession implements Extent {
|
|||||||
return (x * x) + (z * z);
|
return (x * x) + (z * z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return worldName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBlockLightLevel(Vector position) {
|
||||||
|
return queue.getEmmittedLight((int) position.x, (int) position.y, (int) position.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean clearContainerBlockContents(Vector position) {
|
||||||
|
BaseBlock block = getBlock(position);
|
||||||
|
CompoundTag nbt = block.getNbtData();
|
||||||
|
if (nbt != null) {
|
||||||
|
if (nbt.containsKey("items")) {
|
||||||
|
block.setNbtData(null);
|
||||||
|
try {
|
||||||
|
return setBlock(position, block);
|
||||||
|
} catch (WorldEditException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean regenerate(final Region region) {
|
||||||
|
return regenerate(region, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean regenerate(final Region region, final EditSession session) {
|
||||||
|
final FaweQueue queue = session.getQueue();
|
||||||
|
queue.setChangeTask(null);
|
||||||
|
final FaweChangeSet fcs = (FaweChangeSet) session.getChangeSet();
|
||||||
|
final FaweRegionExtent fe = session.getRegionExtent();
|
||||||
|
session.setSize(1);
|
||||||
|
final boolean cuboid = region instanceof CuboidRegion;
|
||||||
|
Set<Vector2D> chunks = region.getChunks();
|
||||||
|
for (Vector2D chunk : chunks) {
|
||||||
|
final int cx = chunk.getBlockX();
|
||||||
|
final int cz = chunk.getBlockZ();
|
||||||
|
final int bx = cx << 4;
|
||||||
|
final int bz = cz << 4;
|
||||||
|
Vector cmin = new Vector(bx, 0, bz);
|
||||||
|
Vector cmax = cmin.add(15, getMaxY(), 15);
|
||||||
|
final boolean containsBot1 = (fe == null || fe.contains(cmin.getBlockX(), cmin.getBlockY(), cmin.getBlockZ()));
|
||||||
|
final boolean containsBot2 = region.contains(cmin);
|
||||||
|
final boolean containsTop1 = (fe == null || fe.contains(cmax.getBlockX(), cmax.getBlockY(), cmax.getBlockZ()));
|
||||||
|
final boolean containsTop2 = region.contains(cmax);
|
||||||
|
if ((containsBot2 && containsTop2 && !containsBot1 && !containsTop1)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
RunnableVal<Vector2D> r = new RunnableVal<Vector2D>() {
|
||||||
|
@Override
|
||||||
|
public void run(Vector2D chunk) {
|
||||||
|
if (cuboid && containsBot1 && containsBot2 && containsTop1 && containsTop2) {
|
||||||
|
if (fcs != null) {
|
||||||
|
for (int x = 0; x < 16; x++) {
|
||||||
|
int xx = x + bx;
|
||||||
|
for (int z = 0; z < 16; z++) {
|
||||||
|
int zz = z + bz;
|
||||||
|
for (int y = 0; y < getMaxY() + 1; y++) {
|
||||||
|
int from = queue.getCombinedId4DataDebug(xx, y, zz, 0, session);
|
||||||
|
if (!FaweCache.hasNBT(from >> 4)) {
|
||||||
|
fcs.add(xx, y, zz, from, 0);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
Vector loc = new Vector(xx, y, zz);
|
||||||
|
BaseBlock block = getLazyBlock(loc);
|
||||||
|
fcs.add(loc, block, FaweCache.CACHE_BLOCK[0]);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
fcs.add(xx, y, zz, from, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Vector mutable = new Vector(0,0,0);
|
||||||
|
for (int x = 0; x < 16; x++) {
|
||||||
|
int xx = x + bx;
|
||||||
|
mutable.x = xx;
|
||||||
|
for (int z = 0; z < 16; z++) {
|
||||||
|
int zz = z + bz;
|
||||||
|
mutable.z = zz;
|
||||||
|
for (int y = 0; y < getMaxY() + 1; y++) {
|
||||||
|
mutable.y = y;
|
||||||
|
int from = queue.getCombinedId4Data(xx, y, zz);
|
||||||
|
boolean contains = (fe == null || fe.contains(xx, y, zz)) && region.contains(mutable);
|
||||||
|
if (contains) {
|
||||||
|
if (fcs != null) {
|
||||||
|
if (!FaweCache.hasNBT(from >> 4)) {
|
||||||
|
fcs.add(xx, y, zz, from, 0);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
BaseBlock block = getLazyBlock(mutable);
|
||||||
|
fcs.add(mutable, block, FaweCache.CACHE_BLOCK[0]);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
fcs.add(xx, y, zz, from, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
short id = (short) (from >> 4);
|
||||||
|
byte data = (byte) (from & 0xf);
|
||||||
|
queue.setBlock(xx, y, zz, id, data);
|
||||||
|
if (FaweCache.hasNBT(id)) {
|
||||||
|
BaseBlock block = getBlock(new Vector(xx, y, zz));
|
||||||
|
if (block.hasNbtData()) {
|
||||||
|
queue.setTile(xx, y, zz, block.getNbtData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
queue.regenerateChunk(cx, cz);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
r.value = chunk;
|
||||||
|
TaskManager.IMP.sync(r);
|
||||||
|
}
|
||||||
|
session.flushQueue();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dropItem(Vector position, BaseItemStack item) {
|
||||||
|
if (getWorld() != null) {
|
||||||
|
getWorld().dropItem(position, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean generateTree(TreeGenerator.TreeType type, Vector position) throws MaxChangedBlocksException {
|
||||||
|
return generateTree(type, this, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean generateTree(TreeGenerator.TreeType type, EditSession editSession, Vector position) throws MaxChangedBlocksException {
|
||||||
|
if (getWorld() != null) {
|
||||||
|
return getWorld().generateTree(type, editSession, position);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static Class<?> inject() {
|
public static Class<?> inject() {
|
||||||
return EditSession.class;
|
return EditSession.class;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,6 @@ import com.sk89q.minecraft.util.commands.Logging;
|
|||||||
import com.sk89q.worldedit.BlockVector;
|
import com.sk89q.worldedit.BlockVector;
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
import com.sk89q.worldedit.LocalSession;
|
import com.sk89q.worldedit.LocalSession;
|
||||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
@ -353,11 +352,7 @@ public class ClipboardCommands {
|
|||||||
pos.x += relx;
|
pos.x += relx;
|
||||||
pos.y += rely;
|
pos.y += rely;
|
||||||
pos.z += relz;
|
pos.z += relz;
|
||||||
try {
|
editSession.setBlockFast(pos, block);
|
||||||
editSession.setBlock(pos, block);
|
|
||||||
} catch (MaxChangedBlocksException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, !ignoreAirBlocks);
|
}, !ignoreAirBlocks);
|
||||||
} else {
|
} else {
|
||||||
|
@ -99,14 +99,13 @@ public class SelectionCommands {
|
|||||||
} else {
|
} else {
|
||||||
pos = player.getBlockIn();
|
pos = player.getBlockIn();
|
||||||
}
|
}
|
||||||
|
pos = pos.clampY(0, editSession.getMaximumPoint().getBlockY());
|
||||||
if (!session.getRegionSelector(player.getWorld()).selectPrimary(pos, 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);
|
||||||
.explainPrimarySelection(player, session, pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -134,7 +133,7 @@ public class SelectionCommands {
|
|||||||
} else {
|
} else {
|
||||||
pos = player.getBlockIn();
|
pos = player.getBlockIn();
|
||||||
}
|
}
|
||||||
|
pos = pos.clampY(0, editSession.getMaximumPoint().getBlockY());
|
||||||
if (!session.getRegionSelector(player.getWorld()).selectSecondary(pos, ActorSelectorLimits.forActor(player))) {
|
if (!session.getRegionSelector(player.getWorld()).selectSecondary(pos, ActorSelectorLimits.forActor(player))) {
|
||||||
BBC.SELECTOR_ALREADY_SET.send(player);
|
BBC.SELECTOR_ALREADY_SET.send(player);
|
||||||
return;
|
return;
|
||||||
|
@ -50,18 +50,13 @@ public class LongRangeBuildTool extends BrushTool implements DoubleActionTraceTo
|
|||||||
WorldVectorFace pos = getTargetFace(player);
|
WorldVectorFace pos = getTargetFace(player);
|
||||||
if (pos == null) return false;
|
if (pos == null) return false;
|
||||||
EditSession eS = session.createEditSession(player);
|
EditSession eS = session.createEditSession(player);
|
||||||
try {
|
if (secondary.getType() == BlockID.AIR) {
|
||||||
if (secondary.getType() == BlockID.AIR) {
|
eS.setBlockFast(pos, secondary);
|
||||||
eS.setBlock(pos, secondary);
|
} else {
|
||||||
} else {
|
eS.setBlockFast(pos.getFaceVector(), secondary);
|
||||||
eS.setBlock(pos.getFaceVector(), secondary);
|
|
||||||
}
|
|
||||||
eS.flushQueue();
|
|
||||||
return true;
|
|
||||||
} catch (MaxChangedBlocksException e) {
|
|
||||||
// one block? eat it
|
|
||||||
}
|
}
|
||||||
return false;
|
eS.flushQueue();
|
||||||
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,18 +65,13 @@ public class LongRangeBuildTool extends BrushTool implements DoubleActionTraceTo
|
|||||||
WorldVectorFace pos = getTargetFace(player);
|
WorldVectorFace pos = getTargetFace(player);
|
||||||
if (pos == null) return false;
|
if (pos == null) return false;
|
||||||
EditSession eS = session.createEditSession(player);
|
EditSession eS = session.createEditSession(player);
|
||||||
try {
|
if (primary.getType() == BlockID.AIR) {
|
||||||
if (primary.getType() == BlockID.AIR) {
|
eS.setBlockFast(pos, primary);
|
||||||
eS.setBlock(pos, primary);
|
} else {
|
||||||
} else {
|
eS.setBlockFast(pos.getFaceVector(), primary);
|
||||||
eS.setBlock(pos.getFaceVector(), primary);
|
|
||||||
}
|
|
||||||
eS.flushQueue();
|
|
||||||
return true;
|
|
||||||
} catch (MaxChangedBlocksException e) {
|
|
||||||
// one block? eat it
|
|
||||||
}
|
}
|
||||||
return false;
|
eS.flushQueue();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public WorldVectorFace getTargetFace(Player player) {
|
public WorldVectorFace getTargetFace(Player player) {
|
||||||
|
@ -66,9 +66,9 @@ public class GravityBrush implements Brush {
|
|||||||
if (block != EditSession.nullBlock && (mask == null || mask.test(mutablePos))) {
|
if (block != EditSession.nullBlock && (mask == null || mask.test(mutablePos))) {
|
||||||
if (freeSpot != y) {
|
if (freeSpot != y) {
|
||||||
mutablePos.y = freeSpot;
|
mutablePos.y = freeSpot;
|
||||||
editSession.setBlock(mutablePos, block);
|
editSession.setBlockFast(mutablePos, block);
|
||||||
mutablePos.y = y;
|
mutablePos.y = y;
|
||||||
editSession.setBlock(mutablePos, EditSession.nullBlock);
|
editSession.setBlockFast(mutablePos, EditSession.nullBlock);
|
||||||
}
|
}
|
||||||
freeSpot++;
|
freeSpot++;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.jpountz.lz4;
|
package net.jpountz.lz4;
|
||||||
|
|
||||||
import com.boydti.fawe.object.io.FastByteArrayInputStream;
|
|
||||||
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
||||||
|
import com.boydti.fawe.object.io.FastByteArraysInputStream;
|
||||||
import com.boydti.fawe.util.MainUtil;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@ -19,7 +19,7 @@ public class LZ4StreamTest {
|
|||||||
private Random rand;
|
private Random rand;
|
||||||
|
|
||||||
private byte randomContent[];
|
private byte randomContent[];
|
||||||
private byte compressedOutput[];
|
private byte compressedOutput[][];
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws IOException {
|
public void setUp() throws IOException {
|
||||||
@ -69,13 +69,13 @@ public class LZ4StreamTest {
|
|||||||
|
|
||||||
os.close();
|
os.close();
|
||||||
|
|
||||||
compressedOutput = compressedOutputStream.toByteArray();
|
compressedOutput = compressedOutputStream.toByteArrays();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void randomizedTest() throws IOException {
|
public void randomizedTest() throws IOException {
|
||||||
try {
|
try {
|
||||||
InputStream is = new LZ4InputStream(new FastByteArrayInputStream(compressedOutput));
|
InputStream is = new LZ4InputStream(new FastByteArraysInputStream(compressedOutput));
|
||||||
|
|
||||||
int currentContentPosition = 0;
|
int currentContentPosition = 0;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user