geforkt von Mirrors/FastAsyncWorldEdit
merge
Dieser Commit ist enthalten in:
Ursprung
74fe88ae01
Commit
a3c58a187e
@ -18,29 +18,38 @@ import java.util.concurrent.Future;
|
|||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Single threaded implementation for IQueueExtent (still abstract)
|
* Single threaded implementation for IQueueExtent (still abstract) - Does not implement creation of
|
||||||
* - Does not implement creation of chunks (that has to implemented by the platform e.g. Bukkit)
|
* chunks (that has to implemented by the platform e.g. Bukkit)
|
||||||
*
|
* <p>
|
||||||
* This queue is reusable {@link #init(WorldChunkCache)}
|
* This queue is reusable {@link #init(WorldChunkCache)}
|
||||||
*/
|
*/
|
||||||
public abstract class SingleThreadQueueExtent implements IQueueExtent {
|
public abstract class SingleThreadQueueExtent implements IQueueExtent {
|
||||||
|
|
||||||
|
// Pool discarded chunks for reuse (can safely be cleared by another thread)
|
||||||
|
private static final ConcurrentLinkedQueue<IChunk> CHUNK_POOL = new ConcurrentLinkedQueue<>();
|
||||||
|
// Chunks currently being queued / worked on
|
||||||
|
private final Long2ObjectLinkedOpenHashMap<IChunk> chunks = new Long2ObjectLinkedOpenHashMap<>();
|
||||||
private WorldChunkCache cache;
|
private WorldChunkCache cache;
|
||||||
private Thread currentThread;
|
private Thread currentThread;
|
||||||
private ConcurrentLinkedQueue<Future> submissions = new ConcurrentLinkedQueue<>();
|
private ConcurrentLinkedQueue<Future> submissions = new ConcurrentLinkedQueue<>();
|
||||||
|
// Last access pointers
|
||||||
|
private IChunk lastChunk;
|
||||||
|
private long lastPair = Long.MAX_VALUE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Safety check to ensure that the thread being used matches the one being initialized on.
|
* Safety check to ensure that the thread being used matches the one being initialized on. - Can
|
||||||
* - Can be removed later
|
* be removed later
|
||||||
*/
|
*/
|
||||||
private void checkThread() {
|
private void checkThread() {
|
||||||
if (Thread.currentThread() != currentThread && currentThread != null) {
|
if (Thread.currentThread() != currentThread && currentThread != null) {
|
||||||
throw new UnsupportedOperationException("This class must be used from a single thread. Use multiple queues for concurrent operations");
|
throw new UnsupportedOperationException(
|
||||||
|
"This class must be used from a single thread. Use multiple queues for concurrent operations");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IChunkGet getCachedGet(int X, int Z, Supplier<IChunkGet> supplier) {
|
public IChunkGet getCachedGet(int x, int z, Supplier<IChunkGet> supplier) {
|
||||||
return cache.get(MathMan.pairInt(X, Z), supplier);
|
return cache.get(MathMan.pairInt(x, z), supplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,10 +69,11 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the queue
|
* Initialize the queue
|
||||||
|
*
|
||||||
* @param cache
|
* @param cache
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public synchronized void init(final WorldChunkCache cache) {
|
public synchronized void init(WorldChunkCache cache) {
|
||||||
if (this.cache != null) {
|
if (this.cache != null) {
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
@ -72,15 +82,7 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
|
|||||||
this.cache = cache;
|
this.cache = cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last access pointers
|
public void returnToPool(IChunk chunk) {
|
||||||
private IChunk lastChunk;
|
|
||||||
private long lastPair = Long.MAX_VALUE;
|
|
||||||
// Chunks currently being queued / worked on
|
|
||||||
private final Long2ObjectLinkedOpenHashMap<IChunk> chunks = new Long2ObjectLinkedOpenHashMap<>();
|
|
||||||
// Pool discarded chunks for reuse (can safely be cleared by another thread)
|
|
||||||
private static final ConcurrentLinkedQueue<IChunk> CHUNK_POOL = new ConcurrentLinkedQueue<>();
|
|
||||||
|
|
||||||
public void returnToPool(final IChunk chunk) {
|
|
||||||
CHUNK_POOL.add(chunk);
|
CHUNK_POOL.add(chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,7 +97,7 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends Future<T>> T submit(final IChunk<T> chunk) {
|
public <T extends Future<T>> T submit(IChunk<T> chunk) {
|
||||||
if (lastChunk == chunk) {
|
if (lastChunk == chunk) {
|
||||||
lastPair = Long.MAX_VALUE;
|
lastPair = Long.MAX_VALUE;
|
||||||
lastChunk = null;
|
lastChunk = null;
|
||||||
@ -107,11 +109,12 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Submit without first checking that it has been removed from the chunk map
|
* Submit without first checking that it has been removed from the chunk map
|
||||||
|
*
|
||||||
* @param chunk
|
* @param chunk
|
||||||
* @param <T>
|
* @param <T>
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private <T extends Future<T>> T submitUnchecked(final IChunk<T> chunk) {
|
private <T extends Future<T>> T submitUnchecked(IChunk<T> chunk) {
|
||||||
if (chunk.isEmpty()) {
|
if (chunk.isEmpty()) {
|
||||||
CHUNK_POOL.add(chunk);
|
CHUNK_POOL.add(chunk);
|
||||||
return (T) (Future) Futures.immediateFuture(null);
|
return (T) (Future) Futures.immediateFuture(null);
|
||||||
@ -125,7 +128,7 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized boolean trim(final boolean aggressive) {
|
public synchronized boolean trim(boolean aggressive) {
|
||||||
// TODO trim individial chunk sections
|
// TODO trim individial chunk sections
|
||||||
CHUNK_POOL.clear();
|
CHUNK_POOL.clear();
|
||||||
if (Thread.currentThread() == currentThread) {
|
if (Thread.currentThread() == currentThread) {
|
||||||
@ -146,13 +149,14 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a new IChunk from either the pool, or create a new one<br>
|
* Get a new IChunk from either the pool, or create a new one<br> + Initialize it at the
|
||||||
* + Initialize it at the coordinates
|
* coordinates
|
||||||
|
*
|
||||||
* @param X
|
* @param X
|
||||||
* @param Z
|
* @param Z
|
||||||
* @return IChunk
|
* @return IChunk
|
||||||
*/
|
*/
|
||||||
private IChunk poolOrCreate(final int X, final int Z) {
|
private IChunk poolOrCreate(int X, int Z) {
|
||||||
IChunk next = CHUNK_POOL.poll();
|
IChunk next = CHUNK_POOL.poll();
|
||||||
if (next == null) {
|
if (next == null) {
|
||||||
next = create(false);
|
next = create(false);
|
||||||
@ -162,21 +166,23 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final IChunk getCachedChunk(final int X, final int Z) {
|
public final IChunk getCachedChunk(int x, int z) {
|
||||||
final long pair = (((long) X) << 32) | (Z & 0xffffffffL);
|
final long pair = (long) x << 32 | z & 0xffffffffL;
|
||||||
if (pair == lastPair) {
|
if (pair == lastPair) {
|
||||||
return lastChunk;
|
return lastChunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
IChunk chunk = chunks.get(pair);
|
IChunk chunk = chunks.get(pair);
|
||||||
if (chunk instanceof ReferenceChunk) {
|
if (chunk instanceof ReferenceChunk) {
|
||||||
chunk = ((ReferenceChunk) (chunk)).getParent();
|
chunk = ((ReferenceChunk) chunk).getParent();
|
||||||
}
|
}
|
||||||
if (chunk != null) {
|
if (chunk != null) {
|
||||||
lastPair = pair;
|
lastPair = pair;
|
||||||
lastChunk = chunk;
|
lastChunk = chunk;
|
||||||
}
|
}
|
||||||
if (chunk != null) return chunk;
|
if (chunk != null) {
|
||||||
|
return chunk;
|
||||||
|
}
|
||||||
|
|
||||||
checkThread();
|
checkThread();
|
||||||
final int size = chunks.size();
|
final int size = chunks.size();
|
||||||
@ -195,7 +201,7 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
|
|||||||
submissions.add(future);
|
submissions.add(future);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
chunk = poolOrCreate(X, Z);
|
chunk = poolOrCreate(x, z);
|
||||||
chunk = wrap(chunk);
|
chunk = wrap(chunk);
|
||||||
|
|
||||||
chunks.put(pair, chunk);
|
chunks.put(pair, chunk);
|
||||||
@ -205,14 +211,15 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
|
|||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pollSubmissions(final int targetSize, final boolean aggressive) {
|
private void pollSubmissions(int targetSize, boolean aggressive) {
|
||||||
final int overflow = submissions.size() - targetSize;
|
final int overflow = submissions.size() - targetSize;
|
||||||
if (aggressive) {
|
if (aggressive) {
|
||||||
for (int i = 0; i < overflow; i++) {
|
for (int i = 0; i < overflow; i++) {
|
||||||
Future first = submissions.poll();
|
Future first = submissions.poll();
|
||||||
try {
|
try {
|
||||||
while ((first = (Future) first.get()) != null) ;
|
while ((first = (Future) first.get()) != null) {
|
||||||
} catch (final InterruptedException | ExecutionException e) {
|
}
|
||||||
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -223,7 +230,7 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
|
|||||||
if (next.isDone()) {
|
if (next.isDone()) {
|
||||||
try {
|
try {
|
||||||
next = (Future) next.get();
|
next = (Future) next.get();
|
||||||
} catch (final InterruptedException | ExecutionException e) {
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -240,7 +247,7 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
|
|||||||
checkThread();
|
checkThread();
|
||||||
if (!chunks.isEmpty()) {
|
if (!chunks.isEmpty()) {
|
||||||
if (MemUtil.isMemoryLimited()) {
|
if (MemUtil.isMemoryLimited()) {
|
||||||
for (final IChunk chunk : chunks.values()) {
|
for (IChunk chunk : chunks.values()) {
|
||||||
final Future future = submitUnchecked(chunk);
|
final Future future = submitUnchecked(chunk);
|
||||||
if (future != null && !future.isDone()) {
|
if (future != null && !future.isDone()) {
|
||||||
pollSubmissions(Settings.IMP.QUEUE.PARALLEL_THREADS, true);
|
pollSubmissions(Settings.IMP.QUEUE.PARALLEL_THREADS, true);
|
||||||
@ -248,7 +255,7 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (final IChunk chunk : chunks.values()) {
|
for (IChunk chunk : chunks.values()) {
|
||||||
final Future future = submitUnchecked(chunk);
|
final Future future = submitUnchecked(chunk);
|
||||||
if (future != null && !future.isDone()) {
|
if (future != null && !future.isDone()) {
|
||||||
submissions.add(future);
|
submissions.add(future);
|
||||||
|
@ -6,19 +6,19 @@ import com.sk89q.worldedit.world.World;
|
|||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectIterator;
|
import it.unimi.dsi.fastutil.objects.ObjectIterator;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IGetBlocks may be cached by the WorldChunkCache so that it can be used between multiple IQueueExtents
|
* IGetBlocks may be cached by the WorldChunkCache so that it can be used between multiple
|
||||||
* - avoids conversion between palette and raw data on every block get
|
* IQueueExtents - avoids conversion between palette and raw data on every block get
|
||||||
*/
|
*/
|
||||||
public class WorldChunkCache implements Trimable {
|
public class WorldChunkCache implements Trimable {
|
||||||
|
|
||||||
protected final Long2ObjectLinkedOpenHashMap<WeakReference<IChunkGet>> getCache;
|
protected final Long2ObjectLinkedOpenHashMap<WeakReference<IChunkGet>> getCache;
|
||||||
private final World world;
|
private final World world;
|
||||||
|
|
||||||
protected WorldChunkCache(final World world) {
|
protected WorldChunkCache(World world) {
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.getCache = new Long2ObjectLinkedOpenHashMap<>();
|
this.getCache = new Long2ObjectLinkedOpenHashMap<>();
|
||||||
}
|
}
|
||||||
@ -33,15 +33,18 @@ public class WorldChunkCache implements Trimable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get or create the IGetBlocks
|
* Get or create the IGetBlocks
|
||||||
|
*
|
||||||
* @param index chunk index {@link com.boydti.fawe.util.MathMan#pairInt(int, int)}
|
* @param index chunk index {@link com.boydti.fawe.util.MathMan#pairInt(int, int)}
|
||||||
* @param provider used to create if it isn't already cached
|
* @param provider used to create if it isn't already cached
|
||||||
* @return cached IGetBlocks
|
* @return cached IGetBlocks
|
||||||
*/
|
*/
|
||||||
public synchronized IChunkGet get(final long index, final Supplier<IChunkGet> provider) {
|
public synchronized IChunkGet get(long index, Supplier<IChunkGet> provider) {
|
||||||
final WeakReference<IChunkGet> ref = getCache.get(index);
|
final WeakReference<IChunkGet> ref = getCache.get(index);
|
||||||
if (ref != null) {
|
if (ref != null) {
|
||||||
final IChunkGet blocks = ref.get();
|
final IChunkGet blocks = ref.get();
|
||||||
if (blocks != null) return blocks;
|
if (blocks != null) {
|
||||||
|
return blocks;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
final IChunkGet blocks = provider.get();
|
final IChunkGet blocks = provider.get();
|
||||||
getCache.put(index, new WeakReference<>(blocks));
|
getCache.put(index, new WeakReference<>(blocks));
|
||||||
@ -49,18 +52,22 @@ public class WorldChunkCache implements Trimable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized boolean trim(final boolean aggressive) {
|
public synchronized boolean trim(boolean aggressive) {
|
||||||
boolean result = true;
|
boolean result = true;
|
||||||
if (!getCache.isEmpty()) {
|
if (!getCache.isEmpty()) {
|
||||||
final ObjectIterator<Long2ObjectMap.Entry<WeakReference<IChunkGet>>> iter = getCache.long2ObjectEntrySet().fastIterator();
|
final ObjectIterator<Long2ObjectMap.Entry<WeakReference<IChunkGet>>> iter = getCache
|
||||||
|
.long2ObjectEntrySet().fastIterator();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
final Long2ObjectMap.Entry<WeakReference<IChunkGet>> entry = iter.next();
|
final Long2ObjectMap.Entry<WeakReference<IChunkGet>> entry = iter.next();
|
||||||
final WeakReference<IChunkGet> value = entry.getValue();
|
final WeakReference<IChunkGet> value = entry.getValue();
|
||||||
final IChunkGet igb = value.get();
|
final IChunkGet igb = value.get();
|
||||||
if (igb == null) iter.remove();
|
if (igb == null) {
|
||||||
else {
|
iter.remove();
|
||||||
|
} else {
|
||||||
result = false;
|
result = false;
|
||||||
if (!aggressive) return result;
|
if (!aggressive) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
synchronized (igb) {
|
synchronized (igb) {
|
||||||
igb.trim(aggressive);
|
igb.trim(aggressive);
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,17 @@
|
|||||||
package com.boydti.fawe.beta.implementation.blocks;
|
package com.boydti.fawe.beta.implementation.blocks;
|
||||||
|
|
||||||
import com.boydti.fawe.FaweCache;
|
|
||||||
import com.boydti.fawe.beta.IChunkSet;
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
import com.boydti.fawe.object.collection.BitArray4096;
|
|
||||||
import com.boydti.fawe.object.collection.BlockSet;
|
|
||||||
import com.boydti.fawe.object.collection.MemBlockSet;
|
import com.boydti.fawe.object.collection.MemBlockSet;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
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 java.util.Arrays;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class BitSetBlocks implements IChunkSet {
|
public class BitSetBlocks implements IChunkSet {
|
||||||
|
|
||||||
private final MemBlockSet.RowZ row;
|
private final MemBlockSet.RowZ row;
|
||||||
private final BlockState blockState;
|
private final BlockState blockState;
|
||||||
|
|
||||||
@ -43,13 +38,16 @@ public class BitSetBlocks implements IChunkSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTile(int x, int y, int z, CompoundTag tile) {}
|
public void setTile(int x, int y, int z, CompoundTag tile) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setEntity(CompoundTag tag) {}
|
public void setEntity(CompoundTag tag) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeEntity(UUID uuid) {}
|
public void removeEntity(UUID uuid) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getBlock(int x, int y, int z) {
|
public BlockState getBlock(int x, int y, int z) {
|
||||||
|
@ -4,6 +4,26 @@ import com.boydti.fawe.beta.IBlocks;
|
|||||||
import com.boydti.fawe.beta.IChunkSet;
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
|
|
||||||
public class CharBlocks implements IBlocks {
|
public class CharBlocks implements IBlocks {
|
||||||
|
|
||||||
|
public static final Section FULL = new Section() {
|
||||||
|
@Override
|
||||||
|
public final char[] get(CharBlocks blocks, int layer) {
|
||||||
|
return blocks.blocks[layer];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
public static final Section EMPTY = new Section() {
|
||||||
|
@Override
|
||||||
|
public final char[] get(CharBlocks blocks, int layer) {
|
||||||
|
blocks.sections[layer] = FULL;
|
||||||
|
char[] arr = blocks.blocks[layer];
|
||||||
|
if (arr == null) {
|
||||||
|
arr = blocks.blocks[layer] = blocks.load(layer);
|
||||||
|
} else {
|
||||||
|
blocks.blocks[layer] = blocks.load(layer, arr);
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
};
|
||||||
public final char[][] blocks;
|
public final char[][] blocks;
|
||||||
public final Section[] sections;
|
public final Section[] sections;
|
||||||
|
|
||||||
@ -15,11 +35,13 @@ public class CharBlocks implements IBlocks {
|
|||||||
public CharBlocks() {
|
public CharBlocks() {
|
||||||
blocks = new char[16][];
|
blocks = new char[16][];
|
||||||
sections = new Section[16];
|
sections = new Section[16];
|
||||||
for (int i = 0; i < 16; i++) sections[i] = EMPTY;
|
for (int i = 0; i < 16; i++) {
|
||||||
|
sections[i] = EMPTY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean trim(final boolean aggressive) {
|
public boolean trim(boolean aggressive) {
|
||||||
boolean result = true;
|
boolean result = true;
|
||||||
for (int i = 0; i < 16; i++) {
|
for (int i = 0; i < 16; i++) {
|
||||||
if (sections[i] == EMPTY) {
|
if (sections[i] == EMPTY) {
|
||||||
@ -33,82 +55,67 @@ public class CharBlocks implements IBlocks {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IChunkSet reset() {
|
public IChunkSet reset() {
|
||||||
for (int i = 0; i < 16; i++) sections[i] = EMPTY;
|
for (int i = 0; i < 16; i++) {
|
||||||
|
sections[i] = EMPTY;
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reset(final int layer) {
|
public void reset(int layer) {
|
||||||
sections[layer] = EMPTY;
|
sections[layer] = EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public char[] load(final int layer) {
|
public char[] load(int layer) {
|
||||||
return new char[4096];
|
return new char[4096];
|
||||||
}
|
}
|
||||||
|
|
||||||
public char[] load(final int layer, final char[] data) {
|
public char[] load(int layer, char[] data) {
|
||||||
for (int i = 0; i < 4096; i++) data[i] = 0;
|
for (int i = 0; i < 4096; i++) {
|
||||||
|
data[i] = 0;
|
||||||
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasSection(final int layer) {
|
public boolean hasSection(int layer) {
|
||||||
return sections[layer] == FULL;
|
return sections[layer] == FULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public char get(final int x, final int y, final int z) {
|
public char get(int x, int y, int z) {
|
||||||
final int layer = y >> 4;
|
final int layer = y >> 4;
|
||||||
final int index = ((y & 15) << 8) | (z << 4) | (x);
|
final int index = (y & 15) << 8 | z << 4 | x;
|
||||||
return sections[layer].get(this, layer, index);
|
return sections[layer].get(this, layer, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(final int x, final int y, final int z, final char value) {
|
public void set(int x, int y, int z, char value) {
|
||||||
final int layer = y >> 4;
|
final int layer = y >> 4;
|
||||||
final int index = ((y & 15) << 8) | (z << 4) | (x);
|
final int index = (y & 15) << 8 | z << 4 | x;
|
||||||
set(layer, index, value);
|
set(layer, index, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final char get(final int layer, final int index) {
|
|
||||||
return sections[layer].get(this, layer, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void set(final int layer, final int index, final char value) {
|
|
||||||
sections[layer].set(this, layer, index, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Section
|
Section
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
public final char get(int layer, int index) {
|
||||||
|
return sections[layer].get(this, layer, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void set(int layer, int index, char value) {
|
||||||
|
sections[layer].set(this, layer, index, value);
|
||||||
|
}
|
||||||
|
|
||||||
public static abstract class Section {
|
public static abstract class Section {
|
||||||
|
|
||||||
public abstract char[] get(CharBlocks blocks, int layer);
|
public abstract char[] get(CharBlocks blocks, int layer);
|
||||||
|
|
||||||
public final char get(final CharBlocks blocks, final int layer, final int index) {
|
public final char get(CharBlocks blocks, int layer, int index) {
|
||||||
return get(blocks, layer)[index];
|
return get(blocks, layer)[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void set(final CharBlocks blocks, final int layer, final int index, final char value) {
|
public final void set(CharBlocks blocks, int layer, int index,
|
||||||
|
char value) {
|
||||||
get(blocks, layer)[index] = value;
|
get(blocks, layer)[index] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Section EMPTY = new Section() {
|
|
||||||
@Override
|
|
||||||
public final char[] get(final CharBlocks blocks, final int layer) {
|
|
||||||
blocks.sections[layer] = FULL;
|
|
||||||
char[] arr = blocks.blocks[layer];
|
|
||||||
if (arr == null) {
|
|
||||||
arr = blocks.blocks[layer] = blocks.load(layer);
|
|
||||||
} else {
|
|
||||||
blocks.blocks[layer] = blocks.load(layer, arr);
|
|
||||||
}
|
|
||||||
return arr;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public static final Section FULL = new Section() {
|
|
||||||
@Override
|
|
||||||
public final char[] get(final CharBlocks blocks, final int layer) {
|
|
||||||
return blocks.blocks[layer];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
@ -7,18 +7,19 @@ import com.sk89q.worldedit.world.block.BlockState;
|
|||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
|
|
||||||
public abstract class CharGetBlocks extends CharBlocks implements IChunkGet {
|
public abstract class CharGetBlocks extends CharBlocks implements IChunkGet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseBlock getFullBlock(final int x, final int y, final int z) {
|
public BaseBlock getFullBlock(int x, int y, int z) {
|
||||||
return BlockTypes.states[get(x, y, z)].toBaseBlock();
|
return BlockTypes.states[get(x, y, z)].toBaseBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getBlock(final int x, final int y, final int z) {
|
public BlockState getBlock(int x, int y, int z) {
|
||||||
return BlockTypes.states[get(x, y, z)];
|
return BlockTypes.states[get(x, y, z)];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean trim(final boolean aggressive) {
|
public boolean trim(boolean aggressive) {
|
||||||
for (int i = 0; i < 16; i++) {
|
for (int i = 0; i < 16; i++) {
|
||||||
sections[i] = EMPTY;
|
sections[i] = EMPTY;
|
||||||
blocks[i] = null;
|
blocks[i] = null;
|
||||||
|
@ -7,7 +7,6 @@ import com.sk89q.worldedit.world.biome.BiomeType;
|
|||||||
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.BlockTypes;
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -15,6 +14,7 @@ import java.util.Set;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class CharSetBlocks extends CharBlocks implements IChunkSet {
|
public class CharSetBlocks extends CharBlocks implements IChunkSet {
|
||||||
|
|
||||||
public BiomeType[] biomes;
|
public BiomeType[] biomes;
|
||||||
public HashMap<Short, CompoundTag> tiles;
|
public HashMap<Short, CompoundTag> tiles;
|
||||||
public HashSet<CompoundTag> entities;
|
public HashSet<CompoundTag> entities;
|
||||||
@ -57,7 +57,7 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setBiome(final int x, final int y, final int z, final BiomeType biome) {
|
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
||||||
if (biomes == null) {
|
if (biomes == null) {
|
||||||
biomes = new BiomeType[256];
|
biomes = new BiomeType[256];
|
||||||
}
|
}
|
||||||
@ -71,13 +71,13 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setBlock(final int x, final int y, final int z, final BlockStateHolder holder) {
|
public boolean setBlock(int x, int y, int z, BlockStateHolder holder) {
|
||||||
set(x, y, z, holder.getOrdinalChar());
|
set(x, y, z, holder.getOrdinalChar());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTile(final int x, final int y, final int z, final CompoundTag tile) {
|
public void setTile(int x, int y, int z, CompoundTag tile) {
|
||||||
if (tiles == null) {
|
if (tiles == null) {
|
||||||
tiles = new HashMap<>();
|
tiles = new HashMap<>();
|
||||||
}
|
}
|
||||||
@ -86,7 +86,7 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setEntity(final CompoundTag tag) {
|
public void setEntity(CompoundTag tag) {
|
||||||
if (entities == null) {
|
if (entities == null) {
|
||||||
entities = new HashSet<>();
|
entities = new HashSet<>();
|
||||||
}
|
}
|
||||||
@ -94,7 +94,7 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeEntity(final UUID uuid) {
|
public void removeEntity(UUID uuid) {
|
||||||
if (entityRemoves == null) {
|
if (entityRemoves == null) {
|
||||||
entityRemoves = new HashSet<>();
|
entityRemoves = new HashSet<>();
|
||||||
}
|
}
|
||||||
@ -103,7 +103,9 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
if (biomes != null) return false;
|
if (biomes != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
for (int i = 0; i < 16; i++) {
|
for (int i = 0; i < 16; i++) {
|
||||||
if (hasSection(i)) {
|
if (hasSection(i)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -16,14 +16,150 @@ import com.sk89q.worldedit.world.biome.BiomeType;
|
|||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract IChunk class that implements basic get/set blocks
|
* An abstract {@link IChunk} class that implements basic get/set blocks
|
||||||
*/
|
*/
|
||||||
public abstract class ChunkHolder implements IChunk, Supplier<IChunkGet> {
|
public abstract class ChunkHolder implements IChunk, Supplier<IChunkGet> {
|
||||||
|
|
||||||
|
public static final IBlockDelegate BOTH = new IBlockDelegate() {
|
||||||
|
@Override
|
||||||
|
public boolean setBiome(ChunkHolder chunk, int x, int y, int z,
|
||||||
|
BiomeType biome) {
|
||||||
|
return chunk.set.setBiome(x, y, z, biome);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBlock(ChunkHolder chunk, int x, int y, int z,
|
||||||
|
BlockStateHolder block) {
|
||||||
|
return chunk.set.setBlock(x, y, z, block);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeType getBiome(ChunkHolder chunk, int x, int z) {
|
||||||
|
return chunk.get.getBiomeType(x, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getBlock(ChunkHolder chunk, int x, int y, int z) {
|
||||||
|
return chunk.get.getBlock(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseBlock getFullBlock(ChunkHolder chunk, int x, int y,
|
||||||
|
int z) {
|
||||||
|
return chunk.get.getFullBlock(x, y, z);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
public static final IBlockDelegate GET = new IBlockDelegate() {
|
||||||
|
@Override
|
||||||
|
public boolean setBiome(ChunkHolder chunk, int x, int y, int z,
|
||||||
|
BiomeType biome) {
|
||||||
|
chunk.getOrCreateSet();
|
||||||
|
chunk.delegate = BOTH;
|
||||||
|
return chunk.setBiome(x, y, z, biome);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBlock(ChunkHolder chunk, int x, int y, int z,
|
||||||
|
BlockStateHolder block) {
|
||||||
|
chunk.getOrCreateSet();
|
||||||
|
chunk.delegate = BOTH;
|
||||||
|
return chunk.setBlock(x, y, z, block);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeType getBiome(ChunkHolder chunk, int x, int z) {
|
||||||
|
return chunk.get.getBiomeType(x, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getBlock(ChunkHolder chunk, int x, int y, int z) {
|
||||||
|
return chunk.get.getBlock(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseBlock getFullBlock(ChunkHolder chunk, int x, int y,
|
||||||
|
int z) {
|
||||||
|
return chunk.get.getFullBlock(x, y, z);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
public static final IBlockDelegate SET = new IBlockDelegate() {
|
||||||
|
@Override
|
||||||
|
public boolean setBiome(ChunkHolder chunk, int x, int y, int z,
|
||||||
|
BiomeType biome) {
|
||||||
|
return chunk.set.setBiome(x, y, z, biome);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBlock(ChunkHolder chunk, int x, int y, int z,
|
||||||
|
BlockStateHolder block) {
|
||||||
|
return chunk.set.setBlock(x, y, z, block);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeType getBiome(ChunkHolder chunk, int x, int z) {
|
||||||
|
chunk.getOrCreateGet();
|
||||||
|
chunk.delegate = BOTH;
|
||||||
|
return chunk.getBiomeType(x, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getBlock(ChunkHolder chunk, int x, int y, int z) {
|
||||||
|
chunk.getOrCreateGet();
|
||||||
|
chunk.delegate = BOTH;
|
||||||
|
return chunk.getBlock(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseBlock getFullBlock(ChunkHolder chunk, int x, int y,
|
||||||
|
int z) {
|
||||||
|
chunk.getOrCreateGet();
|
||||||
|
chunk.delegate = BOTH;
|
||||||
|
return chunk.getFullBlock(x, y, z);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
public static final IBlockDelegate NULL = new IBlockDelegate() {
|
||||||
|
@Override
|
||||||
|
public boolean setBiome(ChunkHolder chunk, int x, int y, int z,
|
||||||
|
BiomeType biome) {
|
||||||
|
chunk.getOrCreateSet();
|
||||||
|
chunk.delegate = SET;
|
||||||
|
return chunk.setBiome(x, y, z, biome);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBlock(ChunkHolder chunk, int x, int y, int z,
|
||||||
|
BlockStateHolder block) {
|
||||||
|
chunk.getOrCreateSet();
|
||||||
|
chunk.delegate = SET;
|
||||||
|
return chunk.setBlock(x, y, z, block);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeType getBiome(ChunkHolder chunk, int x, int z) {
|
||||||
|
chunk.getOrCreateGet();
|
||||||
|
chunk.delegate = GET;
|
||||||
|
return chunk.getBiomeType(x, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getBlock(ChunkHolder chunk, int x, int y, int z) {
|
||||||
|
chunk.getOrCreateGet();
|
||||||
|
chunk.delegate = GET;
|
||||||
|
return chunk.getBlock(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseBlock getFullBlock(ChunkHolder chunk, int x, int y,
|
||||||
|
int z) {
|
||||||
|
chunk.getOrCreateGet();
|
||||||
|
chunk.delegate = GET;
|
||||||
|
return chunk.getFullBlock(x, y, z);
|
||||||
|
}
|
||||||
|
};
|
||||||
private IChunkGet get;
|
private IChunkGet get;
|
||||||
private IChunkSet set;
|
private IChunkSet set;
|
||||||
private IBlockDelegate delegate;
|
private IBlockDelegate delegate;
|
||||||
@ -35,7 +171,7 @@ public abstract class ChunkHolder implements IChunk, Supplier<IChunkGet> {
|
|||||||
this.delegate = NULL;
|
this.delegate = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChunkHolder(final IBlockDelegate delegate) {
|
public ChunkHolder(IBlockDelegate delegate) {
|
||||||
this.delegate = delegate;
|
this.delegate = delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +182,8 @@ public abstract class ChunkHolder implements IChunk, Supplier<IChunkGet> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundTag getTag(int x, int y, int z) {
|
public CompoundTag getTag(int x, int y, int z) {
|
||||||
return delegate.getFullBlock(this, x, y, z).getNbtData(); // TODO NOT IMPLEMENTED (add getTag delegate)
|
return delegate.getFullBlock(this, x, y, z)
|
||||||
|
.getNbtData(); // TODO NOT IMPLEMENTED (add getTag delegate)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -55,7 +192,7 @@ public abstract class ChunkHolder implements IChunk, Supplier<IChunkGet> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void filterBlocks(final Filter filter, ChunkFilterBlock block, @Nullable Region region) {
|
public void filterBlocks(Filter filter, ChunkFilterBlock block, @Nullable Region region) {
|
||||||
final IChunkGet get = getOrCreateGet();
|
final IChunkGet get = getOrCreateGet();
|
||||||
final IChunkSet set = getOrCreateSet();
|
final IChunkSet set = getOrCreateSet();
|
||||||
try {
|
try {
|
||||||
@ -64,7 +201,9 @@ public abstract class ChunkHolder implements IChunk, Supplier<IChunkGet> {
|
|||||||
} else {
|
} else {
|
||||||
block = block.init(chunkX, chunkZ, get);
|
block = block.init(chunkX, chunkZ, get);
|
||||||
for (int layer = 0; layer < 16; layer++) {
|
for (int layer = 0; layer < 16; layer++) {
|
||||||
if (!get.hasSection(layer) || !filter.appliesLayer(this, layer)) continue;
|
if (!get.hasSection(layer) || !filter.appliesLayer(this, layer)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
block.init(get, set, layer);
|
block.init(get, set, layer);
|
||||||
block.filter(filter);
|
block.filter(filter);
|
||||||
}
|
}
|
||||||
@ -75,7 +214,7 @@ public abstract class ChunkHolder implements IChunk, Supplier<IChunkGet> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean trim(final boolean aggressive) {
|
public boolean trim(boolean aggressive) {
|
||||||
if (set != null) {
|
if (set != null) {
|
||||||
final boolean result = set.trim(aggressive);
|
final boolean result = set.trim(aggressive);
|
||||||
if (result) {
|
if (result) {
|
||||||
@ -104,12 +243,16 @@ public abstract class ChunkHolder implements IChunk, Supplier<IChunkGet> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final IChunkGet getOrCreateGet() {
|
public final IChunkGet getOrCreateGet() {
|
||||||
if (get == null) get = newGet();
|
if (get == null) {
|
||||||
|
get = newGet();
|
||||||
|
}
|
||||||
return get;
|
return get;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final IChunkSet getOrCreateSet() {
|
public final IChunkSet getOrCreateSet() {
|
||||||
if (set == null) set = set();
|
if (set == null) {
|
||||||
|
set = set();
|
||||||
|
}
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +271,7 @@ public abstract class ChunkHolder implements IChunk, Supplier<IChunkGet> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(final IQueueExtent extent, final int chunkX, final int chunkZ) {
|
public void init(IQueueExtent extent, int chunkX, int chunkZ) {
|
||||||
this.extent = extent;
|
this.extent = extent;
|
||||||
this.chunkX = chunkX;
|
this.chunkX = chunkX;
|
||||||
this.chunkZ = chunkZ;
|
this.chunkZ = chunkZ;
|
||||||
@ -156,167 +299,42 @@ public abstract class ChunkHolder implements IChunk, Supplier<IChunkGet> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setBiome(final int x, final int y, final int z, final BiomeType biome) {
|
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
||||||
return delegate.setBiome(this, x, y, z, biome);
|
return delegate.setBiome(this, x, y, z, biome);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setBlock(final int x, final int y, final int z, final BlockStateHolder block) {
|
public boolean setBlock(int x, int y, int z, BlockStateHolder block) {
|
||||||
return delegate.setBlock(this, x, y, z, block);
|
return delegate.setBlock(this, x, y, z, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BiomeType getBiomeType(final int x, final int z) {
|
public BiomeType getBiomeType(int x, int z) {
|
||||||
return delegate.getBiome(this, x, z);
|
return delegate.getBiome(this, x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getBlock(final int x, final int y, final int z) {
|
public BlockState getBlock(int x, int y, int z) {
|
||||||
return delegate.getBlock(this, x, y, z);
|
return delegate.getBlock(this, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseBlock getFullBlock(final int x, final int y, final int z) {
|
public BaseBlock getFullBlock(int x, int y, int z) {
|
||||||
return delegate.getFullBlock(this, x, y, z);
|
return delegate.getFullBlock(this, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IBlockDelegate {
|
public interface IBlockDelegate {
|
||||||
boolean setBiome(final ChunkHolder chunk, final int x, final int y, final int z, final BiomeType biome);
|
|
||||||
|
|
||||||
boolean setBlock(final ChunkHolder chunk, final int x, final int y, final int z, final BlockStateHolder holder);
|
boolean setBiome(ChunkHolder chunk, int x, int y, int z,
|
||||||
|
BiomeType biome);
|
||||||
|
|
||||||
BiomeType getBiome(final ChunkHolder chunk, final int x, final int z);
|
boolean setBlock(ChunkHolder chunk, int x, int y, int z,
|
||||||
|
BlockStateHolder holder);
|
||||||
|
|
||||||
BlockState getBlock(final ChunkHolder chunk, final int x, final int y, final int z);
|
BiomeType getBiome(ChunkHolder chunk, int x, int z);
|
||||||
|
|
||||||
BaseBlock getFullBlock(final ChunkHolder chunk, final int x, final int y, final int z);
|
BlockState getBlock(ChunkHolder chunk, int x, int y, int z);
|
||||||
|
|
||||||
|
BaseBlock getFullBlock(ChunkHolder chunk, int x, int y, int z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final IBlockDelegate NULL = new IBlockDelegate() {
|
|
||||||
@Override
|
|
||||||
public boolean setBiome(final ChunkHolder chunk, final int x, final int y, final int z, final BiomeType biome) {
|
|
||||||
chunk.getOrCreateSet();
|
|
||||||
chunk.delegate = SET;
|
|
||||||
return chunk.setBiome(x, y, z, biome);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean setBlock(final ChunkHolder chunk, final int x, final int y, final int z, final BlockStateHolder block) {
|
|
||||||
chunk.getOrCreateSet();
|
|
||||||
chunk.delegate = SET;
|
|
||||||
return chunk.setBlock(x, y, z, block);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BiomeType getBiome(final ChunkHolder chunk, final int x, final int z) {
|
|
||||||
chunk.getOrCreateGet();
|
|
||||||
chunk.delegate = GET;
|
|
||||||
return chunk.getBiomeType(x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getBlock(final ChunkHolder chunk, final int x, final int y, final int z) {
|
|
||||||
chunk.getOrCreateGet();
|
|
||||||
chunk.delegate = GET;
|
|
||||||
return chunk.getBlock(x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BaseBlock getFullBlock(final ChunkHolder chunk, final int x, final int y, final int z) {
|
|
||||||
chunk.getOrCreateGet();
|
|
||||||
chunk.delegate = GET;
|
|
||||||
return chunk.getFullBlock(x, y, z);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public static final IBlockDelegate GET = new IBlockDelegate() {
|
|
||||||
@Override
|
|
||||||
public boolean setBiome(final ChunkHolder chunk, final int x, final int y, final int z, final BiomeType biome) {
|
|
||||||
chunk.getOrCreateSet();
|
|
||||||
chunk.delegate = BOTH;
|
|
||||||
return chunk.setBiome(x, y, z, biome);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean setBlock(final ChunkHolder chunk, final int x, final int y, final int z, final BlockStateHolder block) {
|
|
||||||
chunk.getOrCreateSet();
|
|
||||||
chunk.delegate = BOTH;
|
|
||||||
return chunk.setBlock(x, y, z, block);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BiomeType getBiome(final ChunkHolder chunk, final int x, final int z) {
|
|
||||||
return chunk.get.getBiomeType(x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getBlock(final ChunkHolder chunk, final int x, final int y, final int z) {
|
|
||||||
return chunk.get.getBlock(x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BaseBlock getFullBlock(final ChunkHolder chunk, final int x, final int y, final int z) {
|
|
||||||
return chunk.get.getFullBlock(x, y, z);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public static final IBlockDelegate SET = new IBlockDelegate() {
|
|
||||||
@Override
|
|
||||||
public boolean setBiome(final ChunkHolder chunk, final int x, final int y, final int z, final BiomeType biome) {
|
|
||||||
return chunk.set.setBiome(x, y, z, biome);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean setBlock(final ChunkHolder chunk, final int x, final int y, final int z, final BlockStateHolder block) {
|
|
||||||
return chunk.set.setBlock(x, y, z, block);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BiomeType getBiome(final ChunkHolder chunk, final int x, final int z) {
|
|
||||||
chunk.getOrCreateGet();
|
|
||||||
chunk.delegate = BOTH;
|
|
||||||
return chunk.getBiomeType(x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getBlock(final ChunkHolder chunk, final int x, final int y, final int z) {
|
|
||||||
chunk.getOrCreateGet();
|
|
||||||
chunk.delegate = BOTH;
|
|
||||||
return chunk.getBlock(x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BaseBlock getFullBlock(final ChunkHolder chunk, final int x, final int y, final int z) {
|
|
||||||
chunk.getOrCreateGet();
|
|
||||||
chunk.delegate = BOTH;
|
|
||||||
return chunk.getFullBlock(x, y, z);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public static final IBlockDelegate BOTH = new IBlockDelegate() {
|
|
||||||
@Override
|
|
||||||
public boolean setBiome(final ChunkHolder chunk, final int x, final int y, final int z, final BiomeType biome) {
|
|
||||||
return chunk.set.setBiome(x, y, z, biome);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean setBlock(final ChunkHolder chunk, final int x, final int y, final int z, final BlockStateHolder block) {
|
|
||||||
return chunk.set.setBlock(x, y, z, block);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BiomeType getBiome(final ChunkHolder chunk, final int x, final int z) {
|
|
||||||
return chunk.get.getBiomeType(x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getBlock(final ChunkHolder chunk, final int x, final int y, final int z) {
|
|
||||||
return chunk.get.getBlock(x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BaseBlock getFullBlock(final ChunkHolder chunk, final int x, final int y, final int z) {
|
|
||||||
return chunk.get.getFullBlock(x, y, z);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
@ -1,33 +1,27 @@
|
|||||||
package com.boydti.fawe.beta.implementation.holder;
|
package com.boydti.fawe.beta.implementation.holder;
|
||||||
|
|
||||||
import com.boydti.fawe.beta.ChunkFilterBlock;
|
|
||||||
import com.boydti.fawe.beta.Filter;
|
|
||||||
import com.boydti.fawe.beta.FilterBlock;
|
|
||||||
import com.boydti.fawe.beta.FilterBlockMask;
|
|
||||||
import com.boydti.fawe.beta.Flood;
|
|
||||||
import com.boydti.fawe.beta.IChunk;
|
import com.boydti.fawe.beta.IChunk;
|
||||||
import com.boydti.fawe.beta.IDelegateChunk;
|
import com.boydti.fawe.beta.IDelegateChunk;
|
||||||
import com.sk89q.worldedit.math.MutableBlockVector3;
|
|
||||||
import com.sk89q.worldedit.regions.Region;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of IDelegateChunk
|
* Implementation of IDelegateChunk
|
||||||
|
*
|
||||||
* @param <T>
|
* @param <T>
|
||||||
*/
|
*/
|
||||||
public class DelegateChunk<T extends IChunk> implements IDelegateChunk {
|
public class DelegateChunk<T extends IChunk> implements IDelegateChunk {
|
||||||
|
|
||||||
private T parent;
|
private T parent;
|
||||||
|
|
||||||
public DelegateChunk(final T parent) {
|
public DelegateChunk(T parent) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public final T getParent() {
|
public final T getParent() {
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void setParent(final T parent) {
|
public final void setParent(T parent) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,22 +1,24 @@
|
|||||||
package com.boydti.fawe.beta.implementation.holder;
|
package com.boydti.fawe.beta.implementation.holder;
|
||||||
|
|
||||||
import com.boydti.fawe.beta.IQueueExtent;
|
|
||||||
import com.boydti.fawe.beta.IChunk;
|
import com.boydti.fawe.beta.IChunk;
|
||||||
|
import com.boydti.fawe.beta.IQueueExtent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by {@link ReferenceChunk} to allow the chunk to be garbage collected
|
* Used by {@link ReferenceChunk} to allow the chunk to be garbage collected. - When the object is
|
||||||
* - When the object is finalized, add it to the queue
|
* finalized, add it to the queue
|
||||||
*/
|
*/
|
||||||
public class FinalizedChunk extends DelegateChunk {
|
public class FinalizedChunk extends DelegateChunk {
|
||||||
|
|
||||||
private final IQueueExtent queueExtent;
|
private final IQueueExtent queueExtent;
|
||||||
|
|
||||||
public FinalizedChunk(final IChunk parent, final IQueueExtent queueExtent) {
|
public FinalizedChunk(IChunk parent, IQueueExtent queueExtent) {
|
||||||
super(parent);
|
super(parent);
|
||||||
this.queueExtent = queueExtent;
|
this.queueExtent = queueExtent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Submit the chunk to the queue
|
* Submit the chunk to the queue
|
||||||
|
*
|
||||||
* @throws Throwable
|
* @throws Throwable
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -3,26 +3,26 @@ package com.boydti.fawe.beta.implementation.holder;
|
|||||||
import com.boydti.fawe.beta.IChunk;
|
import com.boydti.fawe.beta.IChunk;
|
||||||
import com.boydti.fawe.beta.IDelegateChunk;
|
import com.boydti.fawe.beta.IDelegateChunk;
|
||||||
import com.boydti.fawe.beta.IQueueExtent;
|
import com.boydti.fawe.beta.IQueueExtent;
|
||||||
|
|
||||||
import java.lang.ref.Reference;
|
import java.lang.ref.Reference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An IChunk may be wrapped by a ReferenceChunk if there is low memory<br>
|
* An {@link IChunk} may be wrapped by a ReferenceChunk if there is low memory. This class stores a
|
||||||
* A reference chunk stores a reference (for garbage collection purposes)<br>
|
* reference for garbage collection purposes. If it cleaned by garbage collection, the {@link
|
||||||
* - If it is garbage collected, the {@link FinalizedChunk} logic is run
|
* FinalizedChunk} logic is run.
|
||||||
*/
|
*/
|
||||||
public abstract class ReferenceChunk implements IDelegateChunk {
|
public abstract class ReferenceChunk implements IDelegateChunk {
|
||||||
private final Reference<FinalizedChunk> ref;
|
|
||||||
|
|
||||||
public ReferenceChunk(final IChunk parent, final IQueueExtent queueExtent) {
|
private final Reference<FinalizedChunk> reference;
|
||||||
this.ref = toRef(new FinalizedChunk(parent, queueExtent));
|
|
||||||
|
public ReferenceChunk(IChunk parent, IQueueExtent queueExtent) {
|
||||||
|
this.reference = toReference(new FinalizedChunk(parent, queueExtent));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract Reference<FinalizedChunk> toRef(FinalizedChunk parent);
|
protected abstract Reference<FinalizedChunk> toReference(FinalizedChunk parent);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IChunk getParent() {
|
public IChunk getParent() {
|
||||||
final FinalizedChunk finalized = ref.get();
|
final FinalizedChunk finalized = reference.get();
|
||||||
return finalized != null ? finalized.getParent() : null;
|
return finalized != null ? finalized.getParent() : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package com.boydti.fawe.beta.implementation.holder;
|
|||||||
|
|
||||||
import com.boydti.fawe.beta.IChunk;
|
import com.boydti.fawe.beta.IChunk;
|
||||||
import com.boydti.fawe.beta.IQueueExtent;
|
import com.boydti.fawe.beta.IQueueExtent;
|
||||||
|
|
||||||
import java.lang.ref.Reference;
|
import java.lang.ref.Reference;
|
||||||
import java.lang.ref.SoftReference;
|
import java.lang.ref.SoftReference;
|
||||||
|
|
||||||
@ -11,12 +10,12 @@ import java.lang.ref.SoftReference;
|
|||||||
*/
|
*/
|
||||||
public class SoftChunk extends ReferenceChunk {
|
public class SoftChunk extends ReferenceChunk {
|
||||||
|
|
||||||
public SoftChunk(final IChunk parent, final IQueueExtent queueExtent) {
|
public SoftChunk(IChunk parent, IQueueExtent queueExtent) {
|
||||||
super(parent, queueExtent);
|
super(parent, queueExtent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Reference<FinalizedChunk> toRef(final FinalizedChunk parent) {
|
protected Reference<FinalizedChunk> toReference(FinalizedChunk parent) {
|
||||||
return new SoftReference<>(parent);
|
return new SoftReference<>(parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,21 +2,20 @@ package com.boydti.fawe.beta.implementation.holder;
|
|||||||
|
|
||||||
import com.boydti.fawe.beta.IChunk;
|
import com.boydti.fawe.beta.IChunk;
|
||||||
import com.boydti.fawe.beta.IQueueExtent;
|
import com.boydti.fawe.beta.IQueueExtent;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
|
||||||
|
|
||||||
import java.lang.ref.Reference;
|
import java.lang.ref.Reference;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Weak reference implementation of {@link ReferenceChunk}
|
* A {@link ReferenceChunk} using {@link WeakReference} to hold the chunk.
|
||||||
*/
|
*/
|
||||||
public class WeakChunk extends ReferenceChunk {
|
public class WeakChunk extends ReferenceChunk {
|
||||||
public WeakChunk(final IChunk parent, final IQueueExtent queueExtent) {
|
|
||||||
|
public WeakChunk(IChunk parent, IQueueExtent queueExtent) {
|
||||||
super(parent, queueExtent);
|
super(parent, queueExtent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Reference<FinalizedChunk> toRef(final FinalizedChunk parent) {
|
protected Reference<FinalizedChunk> toReference(FinalizedChunk parent) {
|
||||||
return new WeakReference<>(parent);
|
return new WeakReference<>(parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,21 +4,13 @@ import com.boydti.fawe.Fawe;
|
|||||||
import com.boydti.fawe.configuration.MemorySection;
|
import com.boydti.fawe.configuration.MemorySection;
|
||||||
import com.boydti.fawe.configuration.file.YamlConfiguration;
|
import com.boydti.fawe.configuration.file.YamlConfiguration;
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
import com.boydti.fawe.object.RunnableVal3;
|
|
||||||
import com.boydti.fawe.util.StringMan;
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
|
||||||
import com.sk89q.worldedit.extension.platform.Actor;
|
import com.sk89q.worldedit.extension.platform.Actor;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
@ -28,10 +20,9 @@ public enum BBC {
|
|||||||
* Things to note about this class:
|
* Things to note about this class:
|
||||||
* Can use multiple arguments %s, %s1, %s2, %s3 etc
|
* Can use multiple arguments %s, %s1, %s2, %s3 etc
|
||||||
*/
|
*/
|
||||||
PREFIX("(FAWE)", "Info"),
|
|
||||||
FILE_DELETED("%s0 has been deleted.", "Info"),
|
FILE_DELETED("%s0 has been deleted.", "Info"),
|
||||||
SCHEMATIC_PASTING("&7The schematic is pasting. This cannot be undone.", "Info"),
|
SCHEMATIC_PASTING("&7The schematic is pasting. This cannot be undone.", "Info"),
|
||||||
LIGHTING_PROPOGATE_SELECTION("Lighting has been propogated in %s0 chunks. (Note: To remove light use //removelight)", "Info"),
|
LIGHTING_PROPAGATE_SELECTION("Lighting has been propogated in %s0 chunks. (Note: To remove light use //removelight)", "Info"),
|
||||||
UPDATED_LIGHTING_SELECTION("Lighting has been updated in %s0 chunks. (It may take a second for the packets to send)", "Info"),
|
UPDATED_LIGHTING_SELECTION("Lighting has been updated in %s0 chunks. (It may take a second for the packets to send)", "Info"),
|
||||||
SET_REGION("Selection set to your current allowed region", "Info"),
|
SET_REGION("Selection set to your current allowed region", "Info"),
|
||||||
WORLDEDIT_COMMAND_LIMIT("Please wait until your current action completes", "Info"),
|
WORLDEDIT_COMMAND_LIMIT("Please wait until your current action completes", "Info"),
|
||||||
@ -304,7 +295,7 @@ public enum BBC {
|
|||||||
SEL_CUBOID("Cuboid: left click for point 1, right click for point 2", "Selection"),
|
SEL_CUBOID("Cuboid: left click for point 1, right click for point 2", "Selection"),
|
||||||
SEL_CUBOID_EXTEND("Cuboid: left click for a starting point, right click to extend", "Selection"),
|
SEL_CUBOID_EXTEND("Cuboid: left click for a starting point, right click to extend", "Selection"),
|
||||||
SEL_2D_POLYGON("2D polygon selector: Left/right click to add a point.", "Selection"),
|
SEL_2D_POLYGON("2D polygon selector: Left/right click to add a point.", "Selection"),
|
||||||
SEL_ELLIPSIOD("Ellipsoid selector: left click=center, right click to extend", "Selection"),
|
SAL_ELLIPSOID("Ellipsoid selector: left click=center, right click to extend", "Selection"),
|
||||||
SEL_SPHERE("Sphere selector: left click=center, right click to set radius", "Selection"),
|
SEL_SPHERE("Sphere selector: left click=center, right click to set radius", "Selection"),
|
||||||
SEL_CYLINDRICAL("Cylindrical selector: Left click=center, right click to extend.", "Selection"),
|
SEL_CYLINDRICAL("Cylindrical selector: Left click=center, right click to extend.", "Selection"),
|
||||||
SEL_MAX("%s0 points maximum.", "Selection"),
|
SEL_MAX("%s0 points maximum.", "Selection"),
|
||||||
@ -365,16 +356,6 @@ public enum BBC {
|
|||||||
TIP_BIOME_PATTERN("Tip: The #biome[forest] pattern can be used in any command", "Tips"),
|
TIP_BIOME_PATTERN("Tip: The #biome[forest] pattern can be used in any command", "Tips"),
|
||||||
TIP_BIOME_MASK("Tip: Restrict to a biome with the `$jungle` mask", "Tips"),;
|
TIP_BIOME_MASK("Tip: Restrict to a biome with the `$jungle` mask", "Tips"),;
|
||||||
|
|
||||||
|
|
||||||
private static final HashMap<String, String> replacements = new HashMap<>();
|
|
||||||
static {
|
|
||||||
for (char letter : "1234567890abcdefklmnor".toCharArray()) {
|
|
||||||
replacements.put("&" + letter, "\u00a7" + letter);
|
|
||||||
}
|
|
||||||
replacements.put("\\\\n", "\n");
|
|
||||||
replacements.put("\\n", "\n");
|
|
||||||
replacements.put("&-", "\n");
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Translated
|
* Translated
|
||||||
*/
|
*/
|
||||||
@ -460,7 +441,6 @@ public enum BBC {
|
|||||||
changed = true;
|
changed = true;
|
||||||
yml.set(caption.category + "." + caption.name().toLowerCase(Locale.ROOT), caption.defaultMessage);
|
yml.set(caption.category + "." + caption.name().toLowerCase(Locale.ROOT), caption.defaultMessage);
|
||||||
}
|
}
|
||||||
caption.translatedMessage = StringMan.replaceFromMap(caption.translatedMessage, replacements);
|
|
||||||
}
|
}
|
||||||
if (changed) {
|
if (changed) {
|
||||||
yml.save(file);
|
yml.save(file);
|
||||||
@ -483,15 +463,6 @@ public enum BBC {
|
|||||||
return toString().length();
|
return toString().length();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String color(String string) {
|
|
||||||
return StringMan.replaceFromMap(string, replacements);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String stripColor(String string) {
|
|
||||||
|
|
||||||
return StringMan.removeFromSet(string, replacements.values());
|
|
||||||
}
|
|
||||||
|
|
||||||
public String s() {
|
public String s() {
|
||||||
return this.translatedMessage;
|
return this.translatedMessage;
|
||||||
}
|
}
|
||||||
@ -519,17 +490,13 @@ public enum BBC {
|
|||||||
try {
|
try {
|
||||||
Method method = actor.getClass().getMethod("print", String.class);
|
Method method = actor.getClass().getMethod("print", String.class);
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
method.invoke(actor, (PREFIX.isEmpty() ? "" : PREFIX.s() + " ") + this.format(args));
|
method.invoke(actor, this.format(args));
|
||||||
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
|
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getPrefix() {
|
|
||||||
return PREFIX.isEmpty() ? "" : PREFIX.s() + " ";
|
|
||||||
}
|
|
||||||
|
|
||||||
public void send(FawePlayer<?> player, Object... args) {
|
public void send(FawePlayer<?> player, Object... args) {
|
||||||
if (isEmpty()) {
|
if (isEmpty()) {
|
||||||
return;
|
return;
|
||||||
@ -537,7 +504,7 @@ public enum BBC {
|
|||||||
if (player == null) {
|
if (player == null) {
|
||||||
Fawe.debug(this.format(args));
|
Fawe.debug(this.format(args));
|
||||||
} else {
|
} else {
|
||||||
player.sendMessage((PREFIX.isEmpty() ? "" : PREFIX.s() + " ") + this.format(args));
|
player.sendMessage(this.format(args));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void send(Actor player, Object... args) {
|
public void send(Actor player, Object... args) {
|
||||||
@ -551,189 +518,4 @@ public enum BBC {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static char getCode(String name) {
|
|
||||||
switch (name) {
|
|
||||||
case "BLACK":
|
|
||||||
return '0';
|
|
||||||
case "DARK_BLUE":
|
|
||||||
return '1';
|
|
||||||
case "DARK_GREEN":
|
|
||||||
return '2';
|
|
||||||
case "DARK_AQUA":
|
|
||||||
return '3';
|
|
||||||
case "DARK_RED":
|
|
||||||
return '4';
|
|
||||||
case "DARK_PURPLE":
|
|
||||||
return '5';
|
|
||||||
case "GOLD":
|
|
||||||
return '6';
|
|
||||||
case "GRAY":
|
|
||||||
return '7';
|
|
||||||
case "DARK_GRAY":
|
|
||||||
return '8';
|
|
||||||
case "BLUE":
|
|
||||||
return '9';
|
|
||||||
case "GREEN":
|
|
||||||
return 'a';
|
|
||||||
case "AQUA":
|
|
||||||
return 'b';
|
|
||||||
case "RED":
|
|
||||||
return 'c';
|
|
||||||
case "LIGHT_PURPLE":
|
|
||||||
return 'd';
|
|
||||||
case "YELLOW":
|
|
||||||
return 'e';
|
|
||||||
case "WHITE":
|
|
||||||
return 'f';
|
|
||||||
case "OBFUSCATED":
|
|
||||||
return 'k';
|
|
||||||
case "BOLD":
|
|
||||||
return 'l';
|
|
||||||
case "STRIKETHROUGH":
|
|
||||||
return 'm';
|
|
||||||
case "UNDERLINE":
|
|
||||||
return 'n';
|
|
||||||
case "ITALIC":
|
|
||||||
return 'o';
|
|
||||||
default:
|
|
||||||
case "RESET":
|
|
||||||
return 'r';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getColorName(char code) {
|
|
||||||
switch (code) {
|
|
||||||
case '0':
|
|
||||||
return "BLACK";
|
|
||||||
case '1':
|
|
||||||
return "DARK_BLUE";
|
|
||||||
case '2':
|
|
||||||
return "DARK_GREEN";
|
|
||||||
case '3':
|
|
||||||
return "DARK_AQUA";
|
|
||||||
case '4':
|
|
||||||
return "DARK_RED";
|
|
||||||
case '5':
|
|
||||||
return "DARK_PURPLE";
|
|
||||||
case '6':
|
|
||||||
return "GOLD";
|
|
||||||
case '7':
|
|
||||||
return "GRAY";
|
|
||||||
case '8':
|
|
||||||
return "DARK_GRAY";
|
|
||||||
case '9':
|
|
||||||
return "BLUE";
|
|
||||||
case 'a':
|
|
||||||
return "GREEN";
|
|
||||||
case 'b':
|
|
||||||
return "AQUA";
|
|
||||||
case 'c':
|
|
||||||
return "RED";
|
|
||||||
case 'd':
|
|
||||||
return "LIGHT_PURPLE";
|
|
||||||
case 'e':
|
|
||||||
return "YELLOW";
|
|
||||||
case 'f':
|
|
||||||
return "WHITE";
|
|
||||||
case 'k':
|
|
||||||
return "OBFUSCATED";
|
|
||||||
case 'l':
|
|
||||||
return "BOLD";
|
|
||||||
case 'm':
|
|
||||||
return "STRIKETHROUGH";
|
|
||||||
case 'n':
|
|
||||||
return "UNDERLINE";
|
|
||||||
case 'o':
|
|
||||||
return "ITALIC";
|
|
||||||
case 'r':
|
|
||||||
return "RESET";
|
|
||||||
default:
|
|
||||||
return "GRAY";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Object[] append(StringBuilder builder, Map<String, Object> obj, String color, Map<String, Boolean> properties) {
|
|
||||||
Object[] style = new Object[] { color, properties };
|
|
||||||
for (Map.Entry<String, Object> entry : obj.entrySet()) {
|
|
||||||
switch (entry.getKey()) {
|
|
||||||
case "text":
|
|
||||||
String text = (String) entry.getValue();
|
|
||||||
String newColor = (String) obj.get("color");
|
|
||||||
String newBold = (String) obj.get("bold");
|
|
||||||
int index = builder.length();
|
|
||||||
if (!Objects.equals(color, newColor)) {
|
|
||||||
style[0] = newColor;
|
|
||||||
char code = BBC.getCode(newColor.toUpperCase(Locale.ROOT));
|
|
||||||
builder.append('\u00A7').append(code);
|
|
||||||
}
|
|
||||||
for (Map.Entry<String, Object> entry2 : obj.entrySet()) {
|
|
||||||
if (StringMan.isEqualIgnoreCaseToAny(entry2.getKey(), "bold", "italic", "underlined", "strikethrough", "obfuscated")) {
|
|
||||||
boolean newValue = Boolean.parseBoolean((String) entry2.getValue());
|
|
||||||
if (properties.put(entry2.getKey(), newValue) != newValue) {
|
|
||||||
if (newValue) {
|
|
||||||
char code = BBC.getCode(entry2.getKey().toUpperCase(Locale.ROOT));
|
|
||||||
builder.append('\u00A7').append(code);
|
|
||||||
} else {
|
|
||||||
builder.insert(index, '\u00A7').append('r');
|
|
||||||
if (Objects.equals(color, newColor) && newColor != null) {
|
|
||||||
builder.append('\u00A7').append(BBC.getCode(newColor.toUpperCase(Locale.ROOT)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
builder.append(text);
|
|
||||||
break;
|
|
||||||
case "extra":
|
|
||||||
List<Map<String, Object>> list = (List<Map<String, Object>>) entry.getValue();
|
|
||||||
for (Map<String, Object> elem : list) {
|
|
||||||
elem.putIfAbsent("color", obj.get("color"));
|
|
||||||
for (Map.Entry<String, Object> entry2 : obj.entrySet()) {
|
|
||||||
if (StringMan.isEqualIgnoreCaseToAny(entry2.getKey(), "bold", "italic", "underlined", "strikethrough", "obfuscated")) {
|
|
||||||
elem.putIfAbsent(entry2.getKey(), entry2.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
style = append(builder, elem, (String) style[0], (Map) style[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return style;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String jsonToString(String text) {
|
|
||||||
Gson gson = new Gson();
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
Map<String, Object> obj = gson.fromJson(text, new TypeToken<Map<String, Object>>() {}.getType());
|
|
||||||
HashMap<String, Boolean> properties = new HashMap<>();
|
|
||||||
properties.put("bold", false);
|
|
||||||
properties.put("italic", false);
|
|
||||||
properties.put("underlined", false);
|
|
||||||
properties.put("strikethrough", false);
|
|
||||||
properties.put("obfuscated", false);
|
|
||||||
append(builder, obj, null, properties);
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param m
|
|
||||||
* @param runPart Part, Color, NewLine
|
|
||||||
*/
|
|
||||||
public static void splitMessage(String m, RunnableVal3<String, String, Boolean> runPart) {
|
|
||||||
m = color(m);
|
|
||||||
String color = "GRAY";
|
|
||||||
boolean newline = false;
|
|
||||||
for (String line : m.split("\n")) {
|
|
||||||
boolean hasColor = line.charAt(0) == '\u00A7';
|
|
||||||
String[] splitColor = line.split("\u00A7");
|
|
||||||
for (String part : splitColor) {
|
|
||||||
if (hasColor) {
|
|
||||||
color = getColorName(part.charAt(0));
|
|
||||||
part = part.substring(1);
|
|
||||||
}
|
|
||||||
runPart.run(part, color, newline);
|
|
||||||
hasColor = true;
|
|
||||||
}
|
|
||||||
newline = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -145,7 +145,7 @@ public abstract class FawePlayer<T> extends Metadatable {
|
|||||||
return cancelled;
|
return cancelled;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setConfirmTask(@NotNull Runnable task, InjectedValueAccess context, String command) {
|
private void setConfirmTask(@NotNull Runnable task, InjectedValueAccess context, @NotNull String command) {
|
||||||
CommandEvent event = new CommandEvent(getPlayer(), command);
|
CommandEvent event = new CommandEvent(getPlayer(), command);
|
||||||
Runnable newTask = () -> PlatformCommandManager.getInstance().handleCommandTask(() -> {
|
Runnable newTask = () -> PlatformCommandManager.getInstance().handleCommandTask(() -> {
|
||||||
task.run();
|
task.run();
|
||||||
@ -154,8 +154,8 @@ public abstract class FawePlayer<T> extends Metadatable {
|
|||||||
setMeta("cmdConfirm", newTask);
|
setMeta("cmdConfirm", newTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkConfirmation(@NotNull Runnable task, String command, int times, int limit, InjectedValueAccess context) throws RegionOperationException {
|
public void checkConfirmation(@NotNull Runnable task, @NotNull String command, int times, int limit, InjectedValueAccess context) throws RegionOperationException {
|
||||||
if (command != null && !getMeta("cmdConfirmRunning", false)) {
|
if (!getMeta("cmdConfirmRunning", false)) {
|
||||||
if (times > limit) {
|
if (times > limit) {
|
||||||
setConfirmTask(task, context, command);
|
setConfirmTask(task, context, command);
|
||||||
String volume = "<unspecified>";
|
String volume = "<unspecified>";
|
||||||
@ -181,8 +181,8 @@ public abstract class FawePlayer<T> extends Metadatable {
|
|||||||
task.run();
|
task.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkConfirmationStack(@NotNull Runnable task, String command, Region region, int times, InjectedValueAccess context) throws RegionOperationException {
|
public void checkConfirmationStack(@NotNull Runnable task, @NotNull String command, Region region, int times, InjectedValueAccess context) throws RegionOperationException {
|
||||||
if (command != null && !getMeta("cmdConfirmRunning", false)) {
|
if (!getMeta("cmdConfirmRunning", false)) {
|
||||||
if (region != null) {
|
if (region != null) {
|
||||||
BlockVector3 min = region.getMinimumPoint();
|
BlockVector3 min = region.getMinimumPoint();
|
||||||
BlockVector3 max = region.getMaximumPoint();
|
BlockVector3 max = region.getMaximumPoint();
|
||||||
@ -199,8 +199,8 @@ public abstract class FawePlayer<T> extends Metadatable {
|
|||||||
task.run();
|
task.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkConfirmationRegion(@NotNull Runnable task, String command, Region region, InjectedValueAccess context) throws RegionOperationException {
|
public void checkConfirmationRegion(@NotNull Runnable task, @NotNull String command, Region region, InjectedValueAccess context) throws RegionOperationException {
|
||||||
if (command != null && !getMeta("cmdConfirmRunning", false)) {
|
if (!getMeta("cmdConfirmRunning", false)) {
|
||||||
if (region != null) {
|
if (region != null) {
|
||||||
BlockVector3 min = region.getMinimumPoint();
|
BlockVector3 min = region.getMinimumPoint();
|
||||||
BlockVector3 max = region.getMaximumPoint();
|
BlockVector3 max = region.getMaximumPoint();
|
||||||
@ -265,18 +265,18 @@ public abstract class FawePlayer<T> extends Metadatable {
|
|||||||
|
|
||||||
// Queue for async tasks
|
// Queue for async tasks
|
||||||
private AtomicInteger runningCount = new AtomicInteger();
|
private AtomicInteger runningCount = new AtomicInteger();
|
||||||
private SimpleAsyncNotifyQueue asyncNotifyQueue = new SimpleAsyncNotifyQueue((t, e) -> {
|
private SimpleAsyncNotifyQueue asyncNotifyQueue = new SimpleAsyncNotifyQueue((thread, throwable) -> {
|
||||||
while (e.getCause() != null) {
|
while (throwable.getCause() != null) {
|
||||||
e = e.getCause();
|
throwable = throwable.getCause();
|
||||||
}
|
}
|
||||||
if (e instanceof WorldEditException) {
|
if (throwable instanceof WorldEditException) {
|
||||||
sendMessage(e.getLocalizedMessage());
|
sendMessage(throwable.getLocalizedMessage());
|
||||||
} else {
|
} else {
|
||||||
FaweException fe = FaweException.get(e);
|
FaweException fe = FaweException.get(throwable);
|
||||||
if (fe != null) {
|
if (fe != null) {
|
||||||
sendMessage(fe.getMessage());
|
sendMessage(fe.getMessage());
|
||||||
} else {
|
} else {
|
||||||
e.printStackTrace();
|
throwable.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -576,7 +576,7 @@ public abstract class FawePlayer<T> extends Metadatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unregister this player (delets all metadata etc)
|
* Unregister this player (deletes all metadata etc)
|
||||||
* - Usually called on logout
|
* - Usually called on logout
|
||||||
*/
|
*/
|
||||||
public void unregister() {
|
public void unregister() {
|
||||||
|
@ -9,7 +9,6 @@ import com.boydti.fawe.object.function.mask.AbstractDelegateMask;
|
|||||||
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.MaxChangedBlocksException;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
|
||||||
import com.sk89q.worldedit.command.tool.brush.Brush;
|
import com.sk89q.worldedit.command.tool.brush.Brush;
|
||||||
import com.sk89q.worldedit.entity.Player;
|
import com.sk89q.worldedit.entity.Player;
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
@ -21,11 +20,10 @@ import com.sk89q.worldedit.function.pattern.Pattern;
|
|||||||
import com.sk89q.worldedit.function.visitor.RecursiveVisitor;
|
import com.sk89q.worldedit.function.visitor.RecursiveVisitor;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
|
||||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||||
import com.sk89q.worldedit.util.Location;
|
import com.sk89q.worldedit.util.Location;
|
||||||
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
|
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
public class CopyPastaBrush implements Brush, ResettableTool {
|
public class CopyPastaBrush implements Brush, ResettableTool {
|
||||||
@ -62,7 +60,6 @@ public class CopyPastaBrush implements Brush, ResettableTool {
|
|||||||
mask = Masks.alwaysTrue();
|
mask = Masks.alwaysTrue();
|
||||||
}
|
}
|
||||||
final ResizableClipboardBuilder builder = new ResizableClipboardBuilder(editSession.getWorld());
|
final ResizableClipboardBuilder builder = new ResizableClipboardBuilder(editSession.getWorld());
|
||||||
final int size2 = (int) (size * size);
|
|
||||||
final int minY = position.getBlockY();
|
final int minY = position.getBlockY();
|
||||||
mask = new AbstractDelegateMask(mask) {
|
mask = new AbstractDelegateMask(mask) {
|
||||||
@Override
|
@Override
|
||||||
@ -93,13 +90,13 @@ public class CopyPastaBrush implements Brush, ResettableTool {
|
|||||||
} else {
|
} else {
|
||||||
AffineTransform transform = null;
|
AffineTransform transform = null;
|
||||||
if (randomRotate) {
|
if (randomRotate) {
|
||||||
if (transform == null) transform = new AffineTransform();
|
transform = new AffineTransform();
|
||||||
int rotate = 90 * ThreadLocalRandom.current().nextInt(4);
|
int rotate = 90 * ThreadLocalRandom.current().nextInt(4);
|
||||||
transform = transform.rotateY(rotate);
|
transform = transform.rotateY(rotate);
|
||||||
}
|
}
|
||||||
if (autoRotate) {
|
if (autoRotate) {
|
||||||
if (transform == null) transform = new AffineTransform();
|
if (transform == null) transform = new AffineTransform();
|
||||||
Location loc = editSession.getPlayer().getPlayer().getLocation();
|
Location loc = editSession.getPlayer().toWorldEditPlayer().getLocation();
|
||||||
float yaw = loc.getYaw();
|
float yaw = loc.getYaw();
|
||||||
float pitch = loc.getPitch();
|
float pitch = loc.getPitch();
|
||||||
transform = transform.rotateY((-yaw) % 360);
|
transform = transform.rotateY((-yaw) % 360);
|
||||||
@ -108,8 +105,6 @@ public class CopyPastaBrush implements Brush, ResettableTool {
|
|||||||
if (transform != null && !transform.isIdentity()) {
|
if (transform != null && !transform.isIdentity()) {
|
||||||
clipboard.setTransform(transform);
|
clipboard.setTransform(transform);
|
||||||
}
|
}
|
||||||
Clipboard faweClip = clipboard.getClipboard();
|
|
||||||
Region region = faweClip.getRegion();
|
|
||||||
|
|
||||||
Operation operation = clipboard
|
Operation operation = clipboard
|
||||||
.createPaste(editSession)
|
.createPaste(editSession)
|
||||||
|
@ -15,8 +15,6 @@ public class FallingSphere implements Brush {
|
|||||||
int pz = position.getBlockZ();
|
int pz = position.getBlockZ();
|
||||||
int maxY = editSession.getMaxY();
|
int maxY = editSession.getMaxY();
|
||||||
|
|
||||||
int lastY = py;
|
|
||||||
|
|
||||||
int radius = (int) Math.round(size);
|
int radius = (int) Math.round(size);
|
||||||
int radiusSqr = (int) Math.round(size * size);
|
int radiusSqr = (int) Math.round(size * size);
|
||||||
for (int z = -radius; z <= radius; z++) {
|
for (int z = -radius; z <= radius; z++) {
|
||||||
|
@ -60,12 +60,11 @@ public class InspectBrush extends BrushTool implements DoubleActionTraceTool {
|
|||||||
|
|
||||||
public boolean perform(final Player player, LocalSession session, boolean rightClick) {
|
public boolean perform(final Player player, LocalSession session, boolean rightClick) {
|
||||||
if (!session.isToolControlEnabled() || !player.hasPermission("worldedit.tool.inspect")) {
|
if (!session.isToolControlEnabled() || !player.hasPermission("worldedit.tool.inspect")) {
|
||||||
player.print(BBC.getPrefix() + BBC.NO_PERM.format("worldedit.tool.inspect"));
|
player.print(BBC.NO_PERM.format("worldedit.tool.inspect"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!Settings.IMP.HISTORY.USE_DATABASE) {
|
if (!Settings.IMP.HISTORY.USE_DATABASE) {
|
||||||
player.print(BBC.getPrefix() + BBC.SETTING_DISABLE
|
player.print(BBC.SETTING_DISABLE.format("history.use-database (Import with /frb #import )"));
|
||||||
.format("history.use-database (Import with /frb #import )"));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
BlockVector3 target = getTarget(player, rightClick).toBlockPoint();
|
BlockVector3 target = getTarget(player, rightClick).toBlockPoint();
|
||||||
|
@ -95,13 +95,13 @@ public class SplineBrush implements Brush, ResettableTool {
|
|||||||
points.add(position);
|
points.add(position);
|
||||||
}
|
}
|
||||||
this.positionSets.add(points);
|
this.positionSets.add(points);
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_SPLINE_PRIMARY_2.s());
|
player.print(BBC.BRUSH_SPLINE_PRIMARY_2.s());
|
||||||
if (!visualization) {
|
if (!visualization) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (positionSets.size() < 2) {
|
if (positionSets.size() < 2) {
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_SPLINE_SECONDARY_ERROR.s());
|
player.print(BBC.BRUSH_SPLINE_SECONDARY_ERROR.s());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<Vector3> centroids = new ArrayList<>();
|
List<Vector3> centroids = new ArrayList<>();
|
||||||
@ -133,7 +133,7 @@ public class SplineBrush implements Brush, ResettableTool {
|
|||||||
}
|
}
|
||||||
editSession.drawSpline(pattern, currentSpline, 0, 0, 0, 10, 0, true);
|
editSession.drawSpline(pattern, currentSpline, 0, 0, 0, 10, 0, true);
|
||||||
}
|
}
|
||||||
player.print(BBC.getPrefix() + BBC.BRUSH_SPLINE_SECONDARY.s());
|
player.print(BBC.BRUSH_SPLINE_SECONDARY.s());
|
||||||
if (visualization) {
|
if (visualization) {
|
||||||
numSplines = originalSize;
|
numSplines = originalSize;
|
||||||
positionSets.remove(positionSets.size() - 1);
|
positionSets.remove(positionSets.size() - 1);
|
||||||
|
@ -36,7 +36,7 @@ public class SurfaceSpline implements Brush {
|
|||||||
if (max == -1) return;
|
if (max == -1) return;
|
||||||
// pos.mutY(max);
|
// pos.mutY(max);
|
||||||
path.add(BlockVector3.at(pos.getBlockX(), max, pos.getBlockZ()));
|
path.add(BlockVector3.at(pos.getBlockX(), max, pos.getBlockZ()));
|
||||||
editSession.getPlayer().sendMessage(BBC.getPrefix() + BBC.BRUSH_SPLINE_PRIMARY_2.s());
|
editSession.getPlayer().sendMessage(BBC.BRUSH_SPLINE_PRIMARY_2.s());
|
||||||
if (!vis) return;
|
if (!vis) return;
|
||||||
}
|
}
|
||||||
LocalBlockVectorSet vset = new LocalBlockVectorSet();
|
LocalBlockVectorSet vset = new LocalBlockVectorSet();
|
||||||
@ -90,6 +90,6 @@ public class SurfaceSpline implements Brush {
|
|||||||
editSession.setBlocks(newSet, pattern);
|
editSession.setBlocks(newSet, pattern);
|
||||||
if (!vis) path.clear();
|
if (!vis) path.clear();
|
||||||
}
|
}
|
||||||
editSession.getPlayer().sendMessage(BBC.getPrefix() + BBC.BRUSH_SPLINE_SECONDARY.s());
|
editSession.getPlayer().sendMessage(BBC.BRUSH_SPLINE_SECONDARY.s());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,10 +78,10 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
protected final DifferentialArray<int[]> main;
|
protected final DifferentialArray<int[]> main;
|
||||||
protected DifferentialArray<int[]> overlay;
|
protected DifferentialArray<int[]> overlay;
|
||||||
|
|
||||||
protected final CFIPrimtives primtives = new CFIPrimtives();
|
protected final CFIPrimitives primitives = new CFIPrimitives();
|
||||||
private CFIPrimtives oldPrimitives = new CFIPrimtives();
|
private CFIPrimitives oldPrimitives = new CFIPrimitives();
|
||||||
|
|
||||||
public final class CFIPrimtives implements Cloneable {
|
public final class CFIPrimitives implements Cloneable {
|
||||||
protected int waterHeight = 0;
|
protected int waterHeight = 0;
|
||||||
protected int floorThickness = 0;
|
protected int floorThickness = 0;
|
||||||
protected int worldThickness = 0;
|
protected int worldThickness = 0;
|
||||||
@ -93,11 +93,11 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (obj == null || !(obj instanceof CFIPrimtives)) {
|
if (obj == null || !(obj instanceof CFIPrimitives)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
for (Field field : CFIPrimtives.class.getDeclaredFields()) {
|
for (Field field : CFIPrimitives.class.getDeclaredFields()) {
|
||||||
if (field.get(this) != field.get(obj)) return false;
|
if (field.get(this) != field.get(obj)) return false;
|
||||||
}
|
}
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
@ -125,8 +125,8 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
out.writeBoolean(overlay != null);
|
out.writeBoolean(overlay != null);
|
||||||
if (overlay != null) overlay.flushChanges(out);
|
if (overlay != null) overlay.flushChanges(out);
|
||||||
try {
|
try {
|
||||||
for (Field field : ReflectionUtils.sortFields(CFIPrimtives.class.getDeclaredFields())) {
|
for (Field field : ReflectionUtils.sortFields(CFIPrimitives.class.getDeclaredFields())) {
|
||||||
Object now = field.get(primtives);
|
Object now = field.get(primitives);
|
||||||
Object old = field.get(oldPrimitives);
|
Object old = field.get(oldPrimitives);
|
||||||
boolean diff = old != now;
|
boolean diff = old != now;
|
||||||
out.writeBoolean(diff);
|
out.writeBoolean(diff);
|
||||||
@ -135,7 +135,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
out.writePrimitive(now);
|
out.writePrimitive(now);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resetPrimtives();
|
resetPrimitives();
|
||||||
} catch (Throwable neverHappens) {
|
} catch (Throwable neverHappens) {
|
||||||
neverHappens.printStackTrace();
|
neverHappens.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -148,11 +148,11 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
heights.isModified() ||
|
heights.isModified() ||
|
||||||
biomes.isModified() ||
|
biomes.isModified() ||
|
||||||
(overlay != null && overlay.isModified()) ||
|
(overlay != null && overlay.isModified()) ||
|
||||||
!primtives.equals(oldPrimitives);
|
!primitives.equals(oldPrimitives);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resetPrimtives() throws CloneNotSupportedException {
|
private void resetPrimitives() throws CloneNotSupportedException {
|
||||||
oldPrimitives = (CFIPrimtives) primtives.clone();
|
oldPrimitives = (CFIPrimitives) primitives.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -163,13 +163,13 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
main.undoChanges(in);
|
main.undoChanges(in);
|
||||||
if (in.readBoolean()) overlay.undoChanges(in);
|
if (in.readBoolean()) overlay.undoChanges(in);
|
||||||
try {
|
try {
|
||||||
for (Field field : ReflectionUtils.sortFields(CFIPrimtives.class.getDeclaredFields())) {
|
for (Field field : ReflectionUtils.sortFields(CFIPrimitives.class.getDeclaredFields())) {
|
||||||
if (in.readBoolean()) {
|
if (in.readBoolean()) {
|
||||||
field.set(primtives, in.readPrimitive(field.getType())); // old
|
field.set(primitives, in.readPrimitive(field.getType())); // old
|
||||||
in.readPrimitive(field.getType()); // new
|
in.readPrimitive(field.getType()); // new
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resetPrimtives();
|
resetPrimitives();
|
||||||
} catch (Throwable neverHappens) {
|
} catch (Throwable neverHappens) {
|
||||||
neverHappens.printStackTrace();
|
neverHappens.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -185,13 +185,13 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
if (in.readBoolean()) overlay.redoChanges(in);
|
if (in.readBoolean()) overlay.redoChanges(in);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (Field field : ReflectionUtils.sortFields(CFIPrimtives.class.getDeclaredFields())) {
|
for (Field field : ReflectionUtils.sortFields(CFIPrimitives.class.getDeclaredFields())) {
|
||||||
if (in.readBoolean()) {
|
if (in.readBoolean()) {
|
||||||
in.readPrimitive(field.getType()); // old
|
in.readPrimitive(field.getType()); // old
|
||||||
field.set(primtives, in.readPrimitive(field.getType())); // new
|
field.set(primitives, in.readPrimitive(field.getType())); // new
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resetPrimtives();
|
resetPrimitives();
|
||||||
} catch (Throwable neverHappens) {
|
} catch (Throwable neverHappens) {
|
||||||
neverHappens.printStackTrace();
|
neverHappens.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -332,7 +332,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
textureUtil = Fawe.get().getTextureUtil();
|
textureUtil = Fawe.get().getTextureUtil();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (primtives.randomVariation) {
|
if (primitives.randomVariation) {
|
||||||
return new RandomTextureUtil(textureUtil);
|
return new RandomTextureUtil(textureUtil);
|
||||||
} else if (textureUtil instanceof CachedTextureUtil) {
|
} else if (textureUtil instanceof CachedTextureUtil) {
|
||||||
return textureUtil;
|
return textureUtil;
|
||||||
@ -346,31 +346,31 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setBedrockId(int bedrockId) {
|
public void setBedrockId(int bedrockId) {
|
||||||
this.primtives.bedrockId = bedrockId;
|
this.primitives.bedrockId = bedrockId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFloorThickness(int floorThickness) {
|
public void setFloorThickness(int floorThickness) {
|
||||||
this.primtives.floorThickness = floorThickness;
|
this.primitives.floorThickness = floorThickness;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setWorldThickness(int height) {
|
public void setWorldThickness(int height) {
|
||||||
this.primtives.worldThickness = height;
|
this.primitives.worldThickness = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setWaterHeight(int waterHeight) {
|
public void setWaterHeight(int waterHeight) {
|
||||||
this.primtives.waterHeight = waterHeight;
|
this.primitives.waterHeight = waterHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setWaterId(int waterId) {
|
public void setWaterId(int waterId) {
|
||||||
this.primtives.waterId = waterId;
|
this.primitives.waterId = waterId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTextureRandomVariation(boolean randomVariation) {
|
public void setTextureRandomVariation(boolean randomVariation) {
|
||||||
this.primtives.randomVariation = randomVariation;
|
this.primitives.randomVariation = randomVariation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getTextureRandomVariation() {
|
public boolean getTextureRandomVariation() {
|
||||||
return this.primtives.randomVariation;
|
return this.primitives.randomVariation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTextureUtil(TextureUtil textureUtil) {
|
public void setTextureUtil(TextureUtil textureUtil) {
|
||||||
@ -428,7 +428,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
}
|
}
|
||||||
// Process table
|
// Process table
|
||||||
table.processSummedAreaTable();
|
table.processSummedAreaTable();
|
||||||
{ // Copy from table
|
// Copy from table
|
||||||
int localIndex = 0;
|
int localIndex = 0;
|
||||||
int zIndex = (minZ * getWidth());
|
int zIndex = (minZ * getWidth());
|
||||||
for (int z = minZ, localZ = 0; z <= maxZ; z++, localZ++, zIndex += getWidth()) {
|
for (int z = minZ, localZ = 0; z <= maxZ; z++, localZ++, zIndex += getWidth()) {
|
||||||
@ -441,7 +441,6 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private final void setLayerHeight(int index, int height) {
|
private final void setLayerHeight(int index, int height) {
|
||||||
int blockHeight = (height) >> 3;
|
int blockHeight = (height) >> 3;
|
||||||
@ -909,8 +908,8 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (y <= primtives.waterHeight) {
|
if (y <= primitives.waterHeight) {
|
||||||
return primtives.waterId << 4;
|
return primitives.waterId << 4;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
} else if (y == height) {
|
} else if (y == height) {
|
||||||
@ -1020,11 +1019,11 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setBiomePriority(int value) {
|
public void setBiomePriority(int value) {
|
||||||
this.primtives.biomePriority = ((value * 65536) / 100) - 32768;
|
this.primitives.biomePriority = ((value * 65536) / 100) - 32768;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBiomePriority() {
|
public int getBiomePriority() {
|
||||||
return ((primtives.biomePriority + 32768) * 100) / 65536;
|
return ((primitives.biomePriority + 32768) * 100) / 65536;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBlockAndBiomeColor(BufferedImage img, Mask mask, BufferedImage imgMask, boolean whiteOnly) {
|
public void setBlockAndBiomeColor(BufferedImage img, Mask mask, BufferedImage imgMask, boolean whiteOnly) {
|
||||||
@ -1061,7 +1060,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
.current().nextInt(256) > height)) continue;
|
.current().nextInt(256) > height)) continue;
|
||||||
}
|
}
|
||||||
int color = img.getRGB(x, z);
|
int color = img.getRGB(x, z);
|
||||||
if (textureUtil.getIsBlockCloserThanBiome(buffer, color, primtives.biomePriority)) {
|
if (textureUtil.getIsBlockCloserThanBiome(buffer, color, primitives.biomePriority)) {
|
||||||
int combined = buffer[0];
|
int combined = buffer[0];
|
||||||
mainArr[index] = combined;
|
mainArr[index] = combined;
|
||||||
floorArr[index] = combined;
|
floorArr[index] = combined;
|
||||||
@ -1091,7 +1090,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
boolean yBiome = y > 0 && y < heightIndex;
|
boolean yBiome = y > 0 && y < heightIndex;
|
||||||
for (int x = 0; x < img.getWidth(); x++, index++) {
|
for (int x = 0; x < img.getWidth(); x++, index++) {
|
||||||
int color = img.getRGB(x, y);
|
int color = img.getRGB(x, y);
|
||||||
if (textureUtil.getIsBlockCloserThanBiome(buffer, color, primtives.biomePriority)) {
|
if (textureUtil.getIsBlockCloserThanBiome(buffer, color, primitives.biomePriority)) {
|
||||||
int combined = buffer[0];
|
int combined = buffer[0];
|
||||||
mainArr[index] = combined;
|
mainArr[index] = combined;
|
||||||
floorArr[index] = combined;
|
floorArr[index] = combined;
|
||||||
@ -1131,7 +1130,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||||
if (mask.getWidth() != getWidth() || mask.getHeight() != getLength())
|
if (mask.getWidth() != getWidth() || mask.getHeight() != getLength())
|
||||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||||
primtives.modifiedMain = true;
|
primitives.modifiedMain = true;
|
||||||
TextureUtil textureUtil = getTextureUtil();
|
TextureUtil textureUtil = getTextureUtil();
|
||||||
|
|
||||||
floor.record(() -> main.record(() -> {
|
floor.record(() -> main.record(() -> {
|
||||||
@ -1160,7 +1159,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
public void setColor(BufferedImage img, Mask mask) {
|
public void setColor(BufferedImage img, Mask mask) {
|
||||||
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
||||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||||
primtives.modifiedMain = true;
|
primitives.modifiedMain = true;
|
||||||
TextureUtil textureUtil = getTextureUtil();
|
TextureUtil textureUtil = getTextureUtil();
|
||||||
|
|
||||||
|
|
||||||
@ -1193,7 +1192,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
public void setColor(BufferedImage img) {
|
public void setColor(BufferedImage img) {
|
||||||
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
||||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||||
primtives.modifiedMain = true;
|
primitives.modifiedMain = true;
|
||||||
TextureUtil textureUtil = getTextureUtil();
|
TextureUtil textureUtil = getTextureUtil();
|
||||||
|
|
||||||
floor.record(() -> main.record(() -> {
|
floor.record(() -> main.record(() -> {
|
||||||
@ -1296,7 +1295,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
} else {
|
} else {
|
||||||
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
||||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||||
primtives.modifiedMain = true;
|
primitives.modifiedMain = true;
|
||||||
|
|
||||||
main.record(() -> {
|
main.record(() -> {
|
||||||
int[] mainArr = main.get();
|
int[] mainArr = main.get();
|
||||||
@ -1349,7 +1348,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
} else {
|
} else {
|
||||||
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
||||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||||
primtives.modifiedMain = true;
|
primitives.modifiedMain = true;
|
||||||
|
|
||||||
main.record(() -> floor.record(() -> {
|
main.record(() -> floor.record(() -> {
|
||||||
int[] floorArr = floor.get();
|
int[] floorArr = floor.get();
|
||||||
@ -1416,7 +1415,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
if (pattern instanceof BlockStateHolder) {
|
if (pattern instanceof BlockStateHolder) {
|
||||||
setMain(mask, ((BlockStateHolder) pattern).getInternalId());
|
setMain(mask, ((BlockStateHolder) pattern).getInternalId());
|
||||||
} else {
|
} else {
|
||||||
primtives.modifiedMain = true;
|
primitives.modifiedMain = true;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int z = 0; z < getLength(); z++) {
|
for (int z = 0; z < getLength(); z++) {
|
||||||
mutable.mutZ(z);
|
mutable.mutZ(z);
|
||||||
@ -1436,7 +1435,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
if (pattern instanceof BlockStateHolder) {
|
if (pattern instanceof BlockStateHolder) {
|
||||||
setColumn(mask, ((BlockStateHolder) pattern).getInternalId());
|
setColumn(mask, ((BlockStateHolder) pattern).getInternalId());
|
||||||
} else {
|
} else {
|
||||||
primtives.modifiedMain = true;
|
primitives.modifiedMain = true;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int z = 0; z < getLength(); z++) {
|
for (int z = 0; z < getLength(); z++) {
|
||||||
mutable.mutZ(z);
|
mutable.mutZ(z);
|
||||||
@ -1597,12 +1596,12 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
for (int layer = 0; layer <= maxLayer; layer++) {
|
for (int layer = 0; layer <= maxLayer; layer++) {
|
||||||
chunk.hasSections[layer] = true;
|
chunk.hasSections[layer] = true;
|
||||||
}
|
}
|
||||||
if (primtives.waterHeight != 0) {
|
if (primitives.waterHeight != 0) {
|
||||||
int maxIndex = (primtives.waterHeight) << 8;
|
int maxIndex = (primitives.waterHeight) << 8;
|
||||||
Arrays.fill(chunk.blocks, 0, maxIndex, primtives.waterId);
|
Arrays.fill(chunk.blocks, 0, maxIndex, primitives.waterId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (primtives.modifiedMain) { // If the main block is modified, we can't short circuit this
|
if (primitives.modifiedMain) { // If the main block is modified, we can't short circuit this
|
||||||
for (int z = csz; z <= cez; z++) {
|
for (int z = csz; z <= cez; z++) {
|
||||||
index = (z & 15) << 4;
|
index = (z & 15) << 4;
|
||||||
for (int x = csx; x <= cex; x++, index++) {
|
for (int x = csx; x <= cex; x++, index++) {
|
||||||
@ -1618,9 +1617,9 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
Arrays.fill(chunk.blocks, 0, maxIndex, BlockID.STONE);
|
Arrays.fill(chunk.blocks, 0, maxIndex, BlockID.STONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean hasFloorThickness = primtives.floorThickness != 0 || primtives.worldThickness != 0;
|
final boolean hasFloorThickness = primitives.floorThickness != 0 || primitives.worldThickness != 0;
|
||||||
if (primtives.worldThickness != 0) {
|
if (primitives.worldThickness != 0) {
|
||||||
int endLayer = ((minY - primtives.worldThickness + 1) >> 4);
|
int endLayer = ((minY - primitives.worldThickness + 1) >> 4);
|
||||||
for (int layer = 0; layer < endLayer; layer++) {
|
for (int layer = 0; layer < endLayer; layer++) {
|
||||||
chunk.hasSections[layer] = false;
|
chunk.hasSections[layer] = false;
|
||||||
}
|
}
|
||||||
@ -1645,8 +1644,8 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
|
|
||||||
int min = maxMainY;
|
int min = maxMainY;
|
||||||
|
|
||||||
if (primtives.floorThickness != 0) {
|
if (primitives.floorThickness != 0) {
|
||||||
maxMainY = Math.max(0, maxMainY - (primtives.floorThickness - 1));
|
maxMainY = Math.max(0, maxMainY - (primitives.floorThickness - 1));
|
||||||
for (int y = maxMainY; y <= height; y++) {
|
for (int y = maxMainY; y <= height; y++) {
|
||||||
chunk.blocks[index + (y << 8)] = floorCombined;
|
chunk.blocks[index + (y << 8)] = floorCombined;
|
||||||
}
|
}
|
||||||
@ -1655,8 +1654,8 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
chunk.blocks[index + ((height) << 8)] = floorCombined;
|
chunk.blocks[index + ((height) << 8)] = floorCombined;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (primtives.worldThickness != 0) {
|
if (primitives.worldThickness != 0) {
|
||||||
minMainY = Math.max(minY, min - primtives.worldThickness + 1);
|
minMainY = Math.max(minY, min - primitives.worldThickness + 1);
|
||||||
for (int y = minY; y < minMainY; y++) {
|
for (int y = minY; y < minMainY; y++) {
|
||||||
chunk.blocks[index + (y << 8)] = BlockID.AIR;
|
chunk.blocks[index + (y << 8)] = BlockID.AIR;
|
||||||
}
|
}
|
||||||
@ -1676,8 +1675,8 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
chunk.blocks[overlayIndex] = overlayCombined;
|
chunk.blocks[overlayIndex] = overlayCombined;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (primtives.bedrockId != 0) {
|
if (primitives.bedrockId != 0) {
|
||||||
chunk.blocks[index] = primtives.bedrockId;
|
chunk.blocks[index] = primitives.bedrockId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1775,7 +1774,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setMain(Mask mask, int combined) {
|
private void setMain(Mask mask, int combined) {
|
||||||
primtives.modifiedMain = true;
|
primitives.modifiedMain = true;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int z = 0; z < getLength(); z++) {
|
for (int z = 0; z < getLength(); z++) {
|
||||||
mutable.mutZ(z);
|
mutable.mutZ(z);
|
||||||
@ -1791,7 +1790,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setColumn(Mask mask, int combined) {
|
private void setColumn(Mask mask, int combined) {
|
||||||
primtives.modifiedMain = true;
|
primitives.modifiedMain = true;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int z = 0; z < getLength(); z++) {
|
for (int z = 0; z < getLength(); z++) {
|
||||||
mutable.mutZ(z);
|
mutable.mutZ(z);
|
||||||
@ -1817,7 +1816,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setMain(int value) {
|
private void setMain(int value) {
|
||||||
primtives.modifiedMain = true;
|
primitives.modifiedMain = true;
|
||||||
main.record(() -> Arrays.fill(main.get(), value));
|
main.record(() -> Arrays.fill(main.get(), value));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1848,7 +1847,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
private void setMain(BufferedImage img, int combined, boolean white) {
|
private void setMain(BufferedImage img, int combined, boolean white) {
|
||||||
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
||||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||||
primtives.modifiedMain = true;
|
primitives.modifiedMain = true;
|
||||||
|
|
||||||
main.record(() -> {
|
main.record(() -> {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
@ -1885,7 +1884,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
|||||||
private void setColumn(BufferedImage img, int combined, boolean white) {
|
private void setColumn(BufferedImage img, int combined, boolean white) {
|
||||||
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
||||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||||
primtives.modifiedMain = true;
|
primitives.modifiedMain = true;
|
||||||
|
|
||||||
main.record(() -> floor.record(() -> {
|
main.record(() -> floor.record(() -> {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
@ -2,7 +2,6 @@ package com.boydti.fawe.object.changeset;
|
|||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.jnbt.anvil.history.IAnvilHistory;
|
|
||||||
import com.boydti.fawe.util.MainUtil;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.collect.Iterators;
|
import com.google.common.collect.Iterators;
|
||||||
@ -20,7 +19,7 @@ import java.util.List;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class AnvilHistory extends FaweChangeSet implements IAnvilHistory {
|
public class AnvilHistory extends FaweChangeSet {
|
||||||
private final File folder;
|
private final File folder;
|
||||||
private int size;
|
private int size;
|
||||||
|
|
||||||
@ -41,7 +40,7 @@ public class AnvilHistory extends FaweChangeSet implements IAnvilHistory {
|
|||||||
this.size = 0;
|
this.size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
//@Override
|
||||||
public boolean addFileChange(File originalMCAFile) {
|
public boolean addFileChange(File originalMCAFile) {
|
||||||
try {
|
try {
|
||||||
Files.move(originalMCAFile.toPath(), Paths.get(folder.getPath(), originalMCAFile.getName()), StandardCopyOption.ATOMIC_MOVE);
|
Files.move(originalMCAFile.toPath(), Paths.get(folder.getPath(), originalMCAFile.getName()), StandardCopyOption.ATOMIC_MOVE);
|
||||||
|
@ -22,7 +22,7 @@ public class CFIChangeSet extends FaweChangeSet {
|
|||||||
super(hmmg);
|
super(hmmg);
|
||||||
File folder = MainUtil.getFile(Fawe.imp().getDirectory(), Settings.IMP.PATHS.HISTORY + File.separator + uuid + File.separator + "CFI" + File.separator + hmmg.getWorldName());
|
File folder = MainUtil.getFile(Fawe.imp().getDirectory(), Settings.IMP.PATHS.HISTORY + File.separator + uuid + File.separator + "CFI" + File.separator + hmmg.getWorldName());
|
||||||
int max = MainUtil.getMaxFileId(folder);
|
int max = MainUtil.getMaxFileId(folder);
|
||||||
this.file = new File(folder, Integer.toString(max) + ".cfi");
|
this.file = new File(folder, max + ".cfi");
|
||||||
File parent = this.file.getParentFile();
|
File parent = this.file.getParentFile();
|
||||||
if (!parent.exists()) this.file.getParentFile().mkdirs();
|
if (!parent.exists()) this.file.getParentFile().mkdirs();
|
||||||
if (!this.file.exists()) this.file.createNewFile();
|
if (!this.file.exists()) this.file.createNewFile();
|
||||||
|
@ -121,6 +121,7 @@ public class DiskStorageHistory extends FaweStreamChangeSet {
|
|||||||
initFiles(folder);
|
initFiles(folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void delete() {
|
public void delete() {
|
||||||
// Fawe.debug("Deleting history: " + getWorld().getName() + "/" + uuid + "/" + index);
|
// Fawe.debug("Deleting history: " + getWorld().getName() + "/" + uuid + "/" + index);
|
||||||
deleteFiles();
|
deleteFiles();
|
||||||
|
@ -20,17 +20,11 @@ import com.sk89q.worldedit.history.change.EntityRemove;
|
|||||||
import com.sk89q.worldedit.history.changeset.ChangeSet;
|
import com.sk89q.worldedit.history.changeset.ChangeSet;
|
||||||
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 com.sk89q.worldedit.util.task.LinkedFuture;
|
|
||||||
import com.sk89q.worldedit.world.World;
|
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.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
import com.sk89q.worldedit.world.block.BlockID;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
@ -57,7 +51,7 @@ public abstract class FaweChangeSet implements ChangeSet {
|
|||||||
|
|
||||||
public FaweChangeSet(String world) {
|
public FaweChangeSet(String world) {
|
||||||
this.worldName = world;
|
this.worldName = world;
|
||||||
this.mainThread = (Fawe.get() == null) || Fawe.isMainThread();
|
this.mainThread = Fawe.get() == null || Fawe.isMainThread();
|
||||||
this.layers = FaweCache.CHUNK_LAYERS;
|
this.layers = FaweCache.CHUNK_LAYERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +59,7 @@ public abstract class FaweChangeSet implements ChangeSet {
|
|||||||
this.world = world;
|
this.world = world;
|
||||||
this.worldName = world.getName();
|
this.worldName = world.getName();
|
||||||
this.mainThread = Fawe.isMainThread();
|
this.mainThread = Fawe.isMainThread();
|
||||||
this.layers = (this.world.getMaxY() + 1) >> 4;
|
this.layers = this.world.getMaxY() + 1 >> 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getWorldName() {
|
public String getWorldName() {
|
||||||
@ -177,6 +171,7 @@ public abstract class FaweChangeSet implements ChangeSet {
|
|||||||
addEntityRemove(tag);
|
addEntityRemove(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void add(Change change) {
|
public void add(Change change) {
|
||||||
if (change.getClass() == BlockChange.class) {
|
if (change.getClass() == BlockChange.class) {
|
||||||
add((BlockChange) change);
|
add((BlockChange) change);
|
||||||
@ -211,11 +206,13 @@ public abstract class FaweChangeSet implements ChangeSet {
|
|||||||
try {
|
try {
|
||||||
if (from.hasNbtData()) {
|
if (from.hasNbtData()) {
|
||||||
CompoundTag nbt = from.getNbtData();
|
CompoundTag nbt = from.getNbtData();
|
||||||
|
assert nbt != null;
|
||||||
MainUtil.setPosition(nbt, x, y, z);
|
MainUtil.setPosition(nbt, x, y, z);
|
||||||
addTileRemove(nbt);
|
addTileRemove(nbt);
|
||||||
}
|
}
|
||||||
if (to.hasNbtData()) {
|
if (to.hasNbtData()) {
|
||||||
CompoundTag nbt = to.getNbtData();
|
CompoundTag nbt = to.getNbtData();
|
||||||
|
assert nbt != null;
|
||||||
MainUtil.setPosition(nbt, x, y, z);
|
MainUtil.setPosition(nbt, x, y, z);
|
||||||
addTileCreate(nbt);
|
addTileCreate(nbt);
|
||||||
}
|
}
|
||||||
@ -236,6 +233,7 @@ public abstract class FaweChangeSet implements ChangeSet {
|
|||||||
try {
|
try {
|
||||||
if (to.hasNbtData()) {
|
if (to.hasNbtData()) {
|
||||||
CompoundTag nbt = to.getNbtData();
|
CompoundTag nbt = to.getNbtData();
|
||||||
|
assert nbt != null;
|
||||||
MainUtil.setPosition(nbt, x, y, z);
|
MainUtil.setPosition(nbt, x, y, z);
|
||||||
addTileCreate(nbt);
|
addTileCreate(nbt);
|
||||||
}
|
}
|
||||||
|
@ -312,6 +312,7 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
|
|||||||
return originZ;
|
return originZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void add(int x, int y, int z, int combinedFrom, int combinedTo) {
|
public void add(int x, int y, int z, int combinedFrom, int combinedTo) {
|
||||||
blockSize++;
|
blockSize++;
|
||||||
try {
|
try {
|
||||||
@ -344,6 +345,7 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void addTileCreate(CompoundTag tag) {
|
public void addTileCreate(CompoundTag tag) {
|
||||||
if (tag == null) {
|
if (tag == null) {
|
||||||
return;
|
return;
|
||||||
@ -357,6 +359,7 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void addTileRemove(CompoundTag tag) {
|
public void addTileRemove(CompoundTag tag) {
|
||||||
if (tag == null) {
|
if (tag == null) {
|
||||||
return;
|
return;
|
||||||
@ -370,6 +373,7 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void addEntityRemove(CompoundTag tag) {
|
public void addEntityRemove(CompoundTag tag) {
|
||||||
if (tag == null) {
|
if (tag == null) {
|
||||||
return;
|
return;
|
||||||
@ -383,6 +387,7 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void addEntityCreate(CompoundTag tag) {
|
public void addEntityCreate(CompoundTag tag) {
|
||||||
if (tag == null) {
|
if (tag == null) {
|
||||||
return;
|
return;
|
||||||
@ -660,6 +665,7 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Iterator<Change> getIterator(final boolean dir) {
|
public Iterator<Change> getIterator(final boolean dir) {
|
||||||
close();
|
close();
|
||||||
try {
|
try {
|
||||||
|
@ -155,8 +155,7 @@ public class MemoryOptimizedHistory extends FaweStreamChangeSet {
|
|||||||
if (biomes == null) {
|
if (biomes == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
FaweInputStream result = MainUtil.getCompressedIS(new FastByteArraysInputStream(biomes));
|
return MainUtil.getCompressedIS(new FastByteArraysInputStream(biomes));
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -11,7 +11,6 @@ import com.sk89q.worldedit.math.BlockVector3;
|
|||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
public class ResizableClipboardBuilder extends MemoryOptimizedHistory {
|
public class ResizableClipboardBuilder extends MemoryOptimizedHistory {
|
||||||
@ -63,13 +62,13 @@ public class ResizableClipboardBuilder extends MemoryOptimizedHistory {
|
|||||||
BlockVector3 pos2 = BlockVector3.at(maxX, maxY, maxZ);
|
BlockVector3 pos2 = BlockVector3.at(maxX, maxY, maxZ);
|
||||||
CuboidRegion region = new CuboidRegion(pos1, pos2);
|
CuboidRegion region = new CuboidRegion(pos1, pos2);
|
||||||
BlockArrayClipboard clipboard = new BlockArrayClipboard(region);
|
BlockArrayClipboard clipboard = new BlockArrayClipboard(region);
|
||||||
Iterator<Change> iter = getIterator(true);
|
Iterator<Change> iterator = getIterator(true);
|
||||||
try {
|
try {
|
||||||
while (iter.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
Change change = iter.next();
|
Change change = iterator.next();
|
||||||
if (change instanceof MutableBlockChange) {
|
if (change instanceof MutableBlockChange) {
|
||||||
MutableBlockChange blockChange = (MutableBlockChange) change;
|
MutableBlockChange blockChange = (MutableBlockChange) change;
|
||||||
BlockStateHolder block = BlockState.getFromInternalId(blockChange.combinedId);
|
BlockState block = BlockState.getFromInternalId(blockChange.combinedId);
|
||||||
clipboard.setBlock(blockChange.x, blockChange.y, blockChange.z, block);
|
clipboard.setBlock(blockChange.x, blockChange.y, blockChange.z, block);
|
||||||
} else if (change instanceof MutableTileChange) {
|
} else if (change instanceof MutableTileChange) {
|
||||||
MutableTileChange tileChange = (MutableTileChange) change;
|
MutableTileChange tileChange = (MutableTileChange) change;
|
||||||
|
@ -247,12 +247,11 @@ public class ClipboardRemapper {
|
|||||||
|
|
||||||
mapPEtoPC.put(new BaseBlock(198,-1), new BaseBlock(208,-1));
|
mapPEtoPC.put(new BaseBlock(198,-1), new BaseBlock(208,-1));
|
||||||
mapPEtoPC.put(new BaseBlock(207,-1), new BaseBlock(212,-1));
|
mapPEtoPC.put(new BaseBlock(207,-1), new BaseBlock(212,-1));
|
||||||
{ // beetroot
|
// beetroot
|
||||||
mapPEtoPC.put(new BaseBlock(244, 2), new BaseBlock(207, 1));
|
mapPEtoPC.put(new BaseBlock(244, 2), new BaseBlock(207, 1));
|
||||||
mapPEtoPC.put(new BaseBlock(244, 4), new BaseBlock(207, 2));
|
mapPEtoPC.put(new BaseBlock(244, 4), new BaseBlock(207, 2));
|
||||||
mapPEtoPC.put(new BaseBlock(244, 7), new BaseBlock(207, 3));
|
mapPEtoPC.put(new BaseBlock(244, 7), new BaseBlock(207, 3));
|
||||||
for (int data = 3; data < 16; data++) mapPEtoPC.putIfAbsent(new BaseBlock(244, data), new BaseBlock(207, data));
|
for (int data = 3; data < 16; data++) mapPEtoPC.putIfAbsent(new BaseBlock(244, data), new BaseBlock(207, data));
|
||||||
}
|
|
||||||
|
|
||||||
for (int data = 0; data < 16; data++) {
|
for (int data = 0; data < 16; data++) {
|
||||||
mapPEtoPC.put(new BaseBlock(218, data), new BaseBlock(219 + data, -1));
|
mapPEtoPC.put(new BaseBlock(218, data), new BaseBlock(219 + data, -1));
|
||||||
|
@ -35,7 +35,7 @@ public class LongHashSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static int lsw(long l) {
|
public static int lsw(long l) {
|
||||||
return (int) (l & 0xFFFFFFFF) + Integer.MIN_VALUE;
|
return (int) l + Integer.MIN_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean containsKey(int msw, int lsw) {
|
public boolean containsKey(int msw, int lsw) {
|
||||||
|
@ -5,13 +5,11 @@ import com.sk89q.worldedit.math.BlockVector2;
|
|||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.math.MutableBlockVector2;
|
import com.sk89q.worldedit.math.MutableBlockVector2;
|
||||||
import com.sk89q.worldedit.math.MutableBlockVector3;
|
import com.sk89q.worldedit.math.MutableBlockVector3;
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.AbstractSet;
|
import java.util.AbstractSet;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Memory optimized BlockVector3 Set using a sparsely populated bitset and grouped by chunk section
|
* Memory optimized BlockVector3 Set using a sparsely populated bitset and grouped by chunk section
|
||||||
@ -706,25 +704,26 @@ public final class MemBlockSet extends BlockSet {
|
|||||||
long total = 0;
|
long total = 0;
|
||||||
long lastBit = 0;
|
long lastBit = 0;
|
||||||
int lastCount = 0;
|
int lastCount = 0;
|
||||||
for (int X = 0; X < rows.length; X++) {
|
for (int x = 0; x < rows.length; x++) {
|
||||||
IRow nullRowX = rows[X];
|
IRow nullRowX = rows[x];
|
||||||
if (!(nullRowX instanceof RowX)) continue;
|
if (!(nullRowX instanceof RowX)) continue;
|
||||||
RowX rowx = (RowX) nullRowX;
|
RowX rowx = (RowX) nullRowX;
|
||||||
for (int Z = 0; Z < rowx.rows.length; Z++) {
|
for (int z = 0; z < rowx.rows.length; z++) {
|
||||||
IRow nullRowZ = rowx.rows[Z];
|
IRow nullRowZ = rowx.rows[z];
|
||||||
if (!(nullRowZ instanceof RowZ)) continue;
|
if (!(nullRowZ instanceof RowZ)) continue;
|
||||||
RowZ rowz = (RowZ) nullRowZ;
|
RowZ rowz = (RowZ) nullRowZ;
|
||||||
outer:
|
for (int y = 0; y < 16; y++) {
|
||||||
for (int Y = 0; Y < 16; Y++) {
|
IRow nullRowY = rowz.rows[y];
|
||||||
IRow nullRowY = rowz.rows[Y];
|
if (!(nullRowY instanceof RowY)) {
|
||||||
if (!(nullRowY instanceof RowY)) continue;
|
continue;
|
||||||
|
}
|
||||||
RowY rowY = (RowY) nullRowY;
|
RowY rowY = (RowY) nullRowY;
|
||||||
for (long bit : rowY.bits) {
|
for (long bit : rowY.bits) {
|
||||||
if (bit == 0) continue;
|
if (bit == 0) {
|
||||||
else if (bit == -1L) {
|
continue;
|
||||||
|
} else if (bit == -1L) {
|
||||||
total += 64;
|
total += 64;
|
||||||
}
|
} else if (bit == lastBit) {
|
||||||
else if (bit == lastBit) {
|
|
||||||
total += lastCount;
|
total += lastCount;
|
||||||
} else {
|
} else {
|
||||||
lastBit = bit;
|
lastBit = bit;
|
||||||
|
@ -3,6 +3,7 @@ package com.boydti.fawe.object.collection;
|
|||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
|
|
||||||
public class SummedAreaTable {
|
public class SummedAreaTable {
|
||||||
|
|
||||||
private final char[] source;
|
private final char[] source;
|
||||||
private final long[] summed;
|
private final long[] summed;
|
||||||
private final int length;
|
private final int length;
|
||||||
@ -28,10 +29,9 @@ 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 < colSize; j++, index++) {
|
for (int j = 0; j < width; j++, index++) {
|
||||||
long val = getVal(i, j, index, source[index]);
|
long val = getVal(i, j, index, source[index]);
|
||||||
summed[index] = val;
|
summed[index] = val;
|
||||||
}
|
}
|
||||||
@ -39,7 +39,9 @@ public class SummedAreaTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private long getSum(int index) {
|
private long getSum(int index) {
|
||||||
if (index < 0) return 0;
|
if (index < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return summed[index];
|
return summed[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,8 +344,7 @@ public class BufferedRandomAccessFile extends RandomAccessFile {
|
|||||||
if (this.curr_ == this.hi_)
|
if (this.curr_ == this.hi_)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
byte res = this.buff_[(int) (this.curr_ - this.lo_)];
|
return this.buff_[(int) (this.curr_ - this.lo_)];
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeCurrent(byte b) throws IOException {
|
public void writeCurrent(byte b) throws IOException {
|
||||||
|
@ -23,7 +23,7 @@ public class RandomFileOutputStream extends OutputStream {
|
|||||||
protected boolean closeParent;
|
protected boolean closeParent;
|
||||||
|
|
||||||
// *****************************************************************************
|
// *****************************************************************************
|
||||||
// INSTANCE CONSTRUCTION/INITIALIZATON/FINALIZATION, OPEN/CLOSE
|
// INSTANCE CONSTRUCTION/INITIALIZATION/FINALIZATION, OPEN/CLOSE
|
||||||
// *****************************************************************************
|
// *****************************************************************************
|
||||||
|
|
||||||
public RandomFileOutputStream(String fnm) throws IOException {
|
public RandomFileOutputStream(String fnm) throws IOException {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package com.boydti.fawe.object.progress;
|
package com.boydti.fawe.object.progress;
|
||||||
|
|
||||||
import com.boydti.fawe.config.BBC;
|
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
|
|
||||||
public class ChatProgressTracker extends DefaultProgressTracker {
|
public class ChatProgressTracker extends DefaultProgressTracker {
|
||||||
@ -11,6 +10,6 @@ public class ChatProgressTracker extends DefaultProgressTracker {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendTile(String title, String sub) {
|
public void sendTile(String title, String sub) {
|
||||||
getPlayer().sendMessage(BBC.getPrefix() + title + sub);
|
getPlayer().sendMessage(title + sub);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,8 @@ import com.sk89q.worldedit.regions.selector.limit.SelectorLimits;
|
|||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class FuzzyRegionSelector extends AbstractDelegateExtent implements RegionSelector {
|
public class FuzzyRegionSelector extends AbstractDelegateExtent implements RegionSelector {
|
||||||
@ -147,11 +149,8 @@ public class FuzzyRegionSelector extends AbstractDelegateExtent implements Regio
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getInformationLines() {
|
public List<String> getInformationLines() {
|
||||||
final List<String> lines = new ArrayList<>();
|
return IntStream.range(0, positions.size())
|
||||||
for (int i = 0; i < positions.size(); i++) {
|
.mapToObj(i -> "Position " + i + ": " + positions.get(i)).collect(Collectors.toList());
|
||||||
lines.add("Position " + i + ": " + positions.get(i));
|
|
||||||
}
|
|
||||||
return lines;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -38,7 +38,6 @@ public class PNGWriter implements ClipboardWriter {
|
|||||||
double d = Math.min((double) imageSize / length, (double) imageSize / width) / 3;
|
double d = Math.min((double) imageSize / length, (double) imageSize / width) / 3;
|
||||||
double d_2 = d / 2;
|
double d_2 = d / 2;
|
||||||
double cx = (double) imageSize / 2;
|
double cx = (double) imageSize / 2;
|
||||||
double cy = (double) imageSize / 2;
|
|
||||||
|
|
||||||
int[] poly1X = new int[4];
|
int[] poly1X = new int[4];
|
||||||
int[] poly1Y = new int[4];
|
int[] poly1Y = new int[4];
|
||||||
@ -106,50 +105,47 @@ public class PNGWriter implements ClipboardWriter {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
double cpy = cpy2 - dpxi[y - y0];
|
double cpy = cpy2 - dpxi[y - y0];
|
||||||
poly1X[0] = (int) (cpx);
|
poly1X[0] = (int) cpx;
|
||||||
poly1Y[0] = (int) (cpy);
|
poly1Y[0] = (int) cpy;
|
||||||
poly1X[1] = (int) (cpx - d);
|
poly1X[1] = (int) (cpx - d);
|
||||||
poly1Y[1] = (int) (cpy - d_2);
|
poly1Y[1] = (int) (cpy - d_2);
|
||||||
poly1X[2] = (int) (cpx);
|
poly1X[2] = (int) cpx;
|
||||||
poly1Y[2] = (int) (cpy - d);
|
poly1Y[2] = (int) (cpy - d);
|
||||||
poly1X[3] = (int) (cpx + d);
|
poly1X[3] = (int) (cpx + d);
|
||||||
poly1Y[3] = (int) (cpy - d_2);
|
poly1Y[3] = (int) (cpy - d_2);
|
||||||
|
|
||||||
poly2X[0] = (int) (cpx);
|
poly2X[0] = (int) cpx;
|
||||||
poly2Y[0] = (int) (cpy);
|
poly2Y[0] = (int) cpy;
|
||||||
poly2X[1] = (int) (cpx + d);
|
poly2X[1] = (int) (cpx + d);
|
||||||
poly2Y[1] = (int) (cpy - d_2);
|
poly2Y[1] = (int) (cpy - d_2);
|
||||||
poly2X[2] = (int) (cpx + d);
|
poly2X[2] = (int) (cpx + d);
|
||||||
poly2Y[2] = (int) (cpy + d_2 + dpxi[0]);
|
poly2Y[2] = (int) (cpy + d_2 + dpxi[0]);
|
||||||
poly2X[3] = (int) (cpx);
|
poly2X[3] = (int) cpx;
|
||||||
poly2Y[3] = (int) (cpy + dpxi[1]);
|
poly2Y[3] = (int) (cpy + dpxi[1]);
|
||||||
|
|
||||||
poly3X[0] = (int) (cpx);
|
poly3X[0] = (int) cpx;
|
||||||
poly3Y[0] = (int) (cpy);
|
poly3Y[0] = (int) cpy;
|
||||||
poly3X[1] = (int) (cpx - d);
|
poly3X[1] = (int) (cpx - d);
|
||||||
poly3Y[1] = (int) (cpy - d_2);
|
poly3Y[1] = (int) (cpy - d_2);
|
||||||
poly3X[2] = (int) (cpx - d);
|
poly3X[2] = (int) (cpx - d);
|
||||||
poly3Y[2] = (int) (cpy + d_2 + dpxi[0]);
|
poly3Y[2] = (int) (cpy + d_2 + dpxi[0]);
|
||||||
poly3X[3] = (int) (cpx);
|
poly3X[3] = (int) cpx;
|
||||||
poly3Y[3] = (int) (cpy + dpxi[1]);
|
poly3Y[3] = (int) (cpy + dpxi[1]);
|
||||||
|
|
||||||
Color colorTop = new Color(tu.getColor(block.getBlockType()));
|
Color colorTop = new Color(tu.getColor(block.getBlockType()));
|
||||||
Color colorRight = colorTop;
|
|
||||||
Color colorLeft = colorTop;
|
|
||||||
|
|
||||||
if (fill) {
|
|
||||||
g2.setColor(colorTop);
|
g2.setColor(colorTop);
|
||||||
|
if (fill) {
|
||||||
g2.fillPolygon(poly1X, poly1Y, 4);
|
g2.fillPolygon(poly1X, poly1Y, 4);
|
||||||
g2.setColor(colorRight);
|
g2.setColor(colorTop);
|
||||||
g2.fillPolygon(poly2X, poly2Y, 4);
|
g2.fillPolygon(poly2X, poly2Y, 4);
|
||||||
g2.setColor(colorLeft);
|
g2.setColor(colorTop);
|
||||||
g2.fillPolygon(poly3X, poly3Y, 4);
|
g2.fillPolygon(poly3X, poly3Y, 4);
|
||||||
} else {
|
} else {
|
||||||
g2.setColor(colorTop);
|
|
||||||
g2.drawPolygon(poly1X, poly1Y, 4);
|
g2.drawPolygon(poly1X, poly1Y, 4);
|
||||||
g2.setColor(colorRight);
|
g2.setColor(colorTop);
|
||||||
g2.drawPolygon(poly2X, poly2Y, 4);
|
g2.drawPolygon(poly2X, poly2Y, 4);
|
||||||
g2.setColor(colorLeft);
|
g2.setColor(colorTop);
|
||||||
g2.drawPolygon(poly3X, poly3Y, 4);
|
g2.drawPolygon(poly3X, poly3Y, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@ import com.boydti.fawe.object.FawePlayer;
|
|||||||
import com.boydti.fawe.object.RegionWrapper;
|
import com.boydti.fawe.object.RegionWrapper;
|
||||||
import com.boydti.fawe.object.RunnableVal;
|
import com.boydti.fawe.object.RunnableVal;
|
||||||
import com.boydti.fawe.object.RunnableVal2;
|
import com.boydti.fawe.object.RunnableVal2;
|
||||||
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;
|
||||||
@ -93,7 +92,6 @@ public class MainUtil {
|
|||||||
* e.g. sending messages
|
* e.g. sending messages
|
||||||
*/
|
*/
|
||||||
public static void sendMessage(final FawePlayer<?> player, String message) {
|
public static void sendMessage(final FawePlayer<?> player, String message) {
|
||||||
message = BBC.color(message);
|
|
||||||
if (player == null) {
|
if (player == null) {
|
||||||
Fawe.debug(message);
|
Fawe.debug(message);
|
||||||
} else {
|
} else {
|
||||||
@ -237,8 +235,8 @@ public class MainUtil {
|
|||||||
if (changeSet instanceof FaweStreamChangeSet) {
|
if (changeSet instanceof FaweStreamChangeSet) {
|
||||||
FaweStreamChangeSet fscs = (FaweStreamChangeSet) changeSet;
|
FaweStreamChangeSet fscs = (FaweStreamChangeSet) changeSet;
|
||||||
return fscs.getSizeOnDisk() + fscs.getSizeInMemory();
|
return fscs.getSizeOnDisk() + fscs.getSizeInMemory();
|
||||||
} else if (changeSet instanceof CPUOptimizedChangeSet) {
|
// } else if (changeSet instanceof CPUOptimizedChangeSet) {
|
||||||
return changeSet.size() + 32;
|
// return changeSet.size() + 32;
|
||||||
} else if (changeSet != null) {
|
} else if (changeSet != null) {
|
||||||
return changeSet.size() * 128;
|
return changeSet.size() * 128;
|
||||||
} else {
|
} else {
|
||||||
@ -631,7 +629,6 @@ public class MainUtil {
|
|||||||
boolean reading = false;
|
boolean reading = false;
|
||||||
int index = 1;
|
int index = 1;
|
||||||
int numIndex = 1;
|
int numIndex = 1;
|
||||||
outer:
|
|
||||||
for (int i = len; i >= 2; i--) {
|
for (int i = len; i >= 2; i--) {
|
||||||
char c = fileName.charAt(i);
|
char c = fileName.charAt(i);
|
||||||
if (!reading) {
|
if (!reading) {
|
||||||
@ -644,7 +641,9 @@ public class MainUtil {
|
|||||||
break;
|
break;
|
||||||
case '.':
|
case '.':
|
||||||
res[index--] = val;
|
res[index--] = val;
|
||||||
if (index == -1) return res;
|
if (index == -1) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
val = 0;
|
val = 0;
|
||||||
numIndex = 1;
|
numIndex = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -28,8 +28,7 @@ public class MemUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static long getUsedBytes() {
|
public static long getUsedBytes() {
|
||||||
long used = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
|
return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
|
||||||
return used;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long getFreeBytes() {
|
public static long getFreeBytes() {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.boydti.fawe.util;
|
package com.boydti.fawe.util;
|
||||||
|
|
||||||
import com.sk89q.worldedit.util.auth.Subject;
|
import com.sk89q.worldedit.util.auth.Subject;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public enum Permission {
|
public enum Permission {
|
||||||
/*
|
/*
|
||||||
@ -17,11 +18,8 @@ public enum Permission {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static boolean hasPermission(Subject player, String permission) {
|
public static boolean hasPermission(@NotNull Subject player, String permission) {
|
||||||
if (player == null || player.hasPermission(ADMIN.permission)) {
|
if (player.hasPermission(ADMIN.permission) || player.hasPermission(permission)) {
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (player.hasPermission(permission)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
final String[] nodes = permission.split("\\.");
|
final String[] nodes = permission.split("\\.");
|
||||||
|
@ -6,33 +6,12 @@ import java.util.Arrays;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
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.stream.Collectors;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
public class StringMan {
|
public class StringMan {
|
||||||
public static String replaceFromMap(String string, Map<String, String> replacements) {
|
|
||||||
final StringBuilder sb = new StringBuilder(string);
|
|
||||||
int size = string.length();
|
|
||||||
for (Entry<String, String> entry : replacements.entrySet()) {
|
|
||||||
if (size == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
final String key = entry.getKey();
|
|
||||||
final String value = entry.getValue();
|
|
||||||
int start = sb.indexOf(key, 0);
|
|
||||||
while (start > -1) {
|
|
||||||
final int end = start + key.length();
|
|
||||||
final int nextSearchStart = start + value.length();
|
|
||||||
sb.replace(start, end, value);
|
|
||||||
size -= end - start;
|
|
||||||
start = sb.indexOf(key, nextSearchStart);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean containsAny(CharSequence sequence, String any) {
|
public static boolean containsAny(CharSequence sequence, String any) {
|
||||||
return IntStream.range(0, sequence.length())
|
return IntStream.range(0, sequence.length())
|
||||||
@ -516,10 +495,6 @@ public class StringMan {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String repeat(String s, int n) {
|
public static String repeat(String s, int n) {
|
||||||
final StringBuilder sb = new StringBuilder();
|
return IntStream.range(0, n).mapToObj(i -> s).collect(Collectors.joining());
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
sb.append(s);
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,9 +99,9 @@ public class WEManager {
|
|||||||
synchronized (masks) {
|
synchronized (masks) {
|
||||||
boolean removed = false;
|
boolean removed = false;
|
||||||
if (!masks.isEmpty()) {
|
if (!masks.isEmpty()) {
|
||||||
Iterator<FaweMask> iter = masks.iterator();
|
Iterator<FaweMask> iterator = masks.iterator();
|
||||||
while (iter.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
FaweMask mask = iter.next();
|
FaweMask mask = iterator.next();
|
||||||
if (mask.isValid(player, type)) {
|
if (mask.isValid(player, type)) {
|
||||||
Region region = mask.getRegion();
|
Region region = mask.getRegion();
|
||||||
if (region.contains(loc.toBlockPoint())) {
|
if (region.contains(loc.toBlockPoint())) {
|
||||||
@ -112,7 +112,7 @@ public class WEManager {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
removed = true;
|
removed = true;
|
||||||
iter.remove();
|
iterator.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,7 @@ public class PlayerWrapper extends AbstractPlayerActor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void findFreePosition(final Location searchPos) {
|
public void findFreePosition(Location searchPos) {
|
||||||
TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
public void run(Boolean value) {
|
public void run(Boolean value) {
|
||||||
@ -180,7 +180,7 @@ public class PlayerWrapper extends AbstractPlayerActor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setOnGround(final Location searchPos) {
|
public void setOnGround(Location searchPos) {
|
||||||
TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
public void run(Boolean value) {
|
public void run(Boolean value) {
|
||||||
@ -284,7 +284,7 @@ public class PlayerWrapper extends AbstractPlayerActor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void floatAt(final int x, final int y, final int z, final boolean alwaysGlass) {
|
public void floatAt(int x, int y, int z, boolean alwaysGlass) {
|
||||||
RuntimeException caught = null;
|
RuntimeException caught = null;
|
||||||
try {
|
try {
|
||||||
EditSession edit = new EditSessionBuilder(parent.getWorld()).player(FawePlayer.wrap(this)).build();
|
EditSession edit = new EditSessionBuilder(parent.getWorld()).player(FawePlayer.wrap(this)).build();
|
||||||
@ -309,7 +309,7 @@ public class PlayerWrapper extends AbstractPlayerActor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Location getBlockTrace(final int range, final boolean useLastBlock) {
|
public Location getBlockTrace(int range, boolean useLastBlock) {
|
||||||
return TaskManager.IMP.sync(new RunnableVal<Location>() {
|
return TaskManager.IMP.sync(new RunnableVal<Location>() {
|
||||||
@Override
|
@Override
|
||||||
public void run(Location value) {
|
public void run(Location value) {
|
||||||
@ -320,7 +320,7 @@ public class PlayerWrapper extends AbstractPlayerActor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Location getBlockTraceFace(final int range, final boolean useLastBlock) {
|
public Location getBlockTraceFace(int range, boolean useLastBlock) {
|
||||||
return TaskManager.IMP.sync(new RunnableVal<Location>() {
|
return TaskManager.IMP.sync(new RunnableVal<Location>() {
|
||||||
@Override
|
@Override
|
||||||
public void run(Location value) {
|
public void run(Location value) {
|
||||||
@ -331,7 +331,7 @@ public class PlayerWrapper extends AbstractPlayerActor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Location getSolidBlockTrace(final int range) {
|
public Location getSolidBlockTrace(int range) {
|
||||||
return TaskManager.IMP.sync(new RunnableVal<Location>() {
|
return TaskManager.IMP.sync(new RunnableVal<Location>() {
|
||||||
@Override
|
@Override
|
||||||
public void run(Location value) {
|
public void run(Location value) {
|
||||||
@ -347,7 +347,7 @@ public class PlayerWrapper extends AbstractPlayerActor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean passThroughForwardWall(final int range) {
|
public boolean passThroughForwardWall(int range) {
|
||||||
return TaskManager.IMP.sync(() -> {
|
return TaskManager.IMP.sync(() -> {
|
||||||
int searchDist = 0;
|
int searchDist = 0;
|
||||||
TargetBlock hitBlox = new TargetBlock(PlayerWrapper.this, range, 0.2);
|
TargetBlock hitBlox = new TargetBlock(PlayerWrapper.this, range, 0.2);
|
||||||
|
@ -20,13 +20,14 @@
|
|||||||
package com.sk89q.jnbt;
|
package com.sk89q.jnbt;
|
||||||
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class which holds constant values.
|
* A class which holds constant values.
|
||||||
*/
|
*/
|
||||||
public final class NBTConstants {
|
public final class NBTConstants {
|
||||||
|
|
||||||
public static final Charset CHARSET = Charset.forName("UTF-8");
|
public static final Charset CHARSET = StandardCharsets.UTF_8;
|
||||||
|
|
||||||
public static final int TYPE_END = 0, TYPE_BYTE = 1, TYPE_SHORT = 2,
|
public static final int TYPE_END = 0, TYPE_BYTE = 1, TYPE_SHORT = 2,
|
||||||
TYPE_INT = 3, TYPE_LONG = 4, TYPE_FLOAT = 5, TYPE_DOUBLE = 6,
|
TYPE_INT = 3, TYPE_LONG = 4, TYPE_FLOAT = 5, TYPE_DOUBLE = 6,
|
||||||
|
@ -135,7 +135,7 @@ public final class StringUtil {
|
|||||||
}
|
}
|
||||||
StringBuilder buffer = new StringBuilder(Integer.toString(str[initialIndex]));
|
StringBuilder buffer = new StringBuilder(Integer.toString(str[initialIndex]));
|
||||||
for (int i = initialIndex + 1; i < str.length; ++i) {
|
for (int i = initialIndex + 1; i < str.length; ++i) {
|
||||||
buffer.append(delimiter).append(Integer.toString(str[i]));
|
buffer.append(delimiter).append(str[i]);
|
||||||
}
|
}
|
||||||
return buffer.toString();
|
return buffer.toString();
|
||||||
}
|
}
|
||||||
|
@ -103,6 +103,7 @@ import com.sk89q.worldedit.internal.expression.runtime.ExpressionTimeoutExceptio
|
|||||||
import com.sk89q.worldedit.internal.expression.runtime.RValue;
|
import com.sk89q.worldedit.internal.expression.runtime.RValue;
|
||||||
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.MathUtils;
|
||||||
import com.sk89q.worldedit.math.MutableBlockVector2;
|
import com.sk89q.worldedit.math.MutableBlockVector2;
|
||||||
import com.sk89q.worldedit.math.MutableBlockVector3;
|
import com.sk89q.worldedit.math.MutableBlockVector3;
|
||||||
import com.sk89q.worldedit.math.Vector2;
|
import com.sk89q.worldedit.math.Vector2;
|
||||||
@ -150,13 +151,9 @@ import java.util.UUID;
|
|||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An {@link Extent} that handles history, {@link BlockBag}s, change limits,
|
* An {@link Extent} that handles history, {@link BlockBag}s, change limits,
|
||||||
* block re-ordering, and much more. Most operations in WorldEdit use this class.
|
* block re-ordering, and much more. Most operations in WorldEdit use this class.
|
||||||
@ -206,7 +203,6 @@ public class EditSession extends AbstractDelegateExtent implements SimpleWorld,
|
|||||||
private final World world;
|
private final World world;
|
||||||
private final String worldName;
|
private final String worldName;
|
||||||
private boolean wrapped;
|
private boolean wrapped;
|
||||||
private boolean fastMode;
|
|
||||||
private final HistoryExtent history;
|
private final HistoryExtent history;
|
||||||
private AbstractDelegateExtent bypassHistory;
|
private AbstractDelegateExtent bypassHistory;
|
||||||
private AbstractDelegateExtent bypassAll;
|
private AbstractDelegateExtent bypassAll;
|
||||||
@ -1401,6 +1397,29 @@ public class EditSession extends AbstractDelegateExtent implements SimpleWorld,
|
|||||||
return replaceBlocks(region, mask, pattern);
|
return replaceBlocks(region, mask, pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the blocks at the center of the given region to the given pattern.
|
||||||
|
* If the center sits between two blocks on a certain axis, then two blocks
|
||||||
|
* will be placed to mark the center.
|
||||||
|
*
|
||||||
|
* @param region the region to find the center of
|
||||||
|
* @param pattern the replacement pattern
|
||||||
|
* @return the number of blocks placed
|
||||||
|
* @throws MaxChangedBlocksException thrown if too many blocks are changed
|
||||||
|
*/
|
||||||
|
public int center(Region region, Pattern pattern) throws MaxChangedBlocksException {
|
||||||
|
checkNotNull(region);
|
||||||
|
checkNotNull(pattern);
|
||||||
|
|
||||||
|
Vector3 center = region.getCenter();
|
||||||
|
Region centerRegion = new CuboidRegion(
|
||||||
|
getWorld(), // Causes clamping of Y range
|
||||||
|
BlockVector3.at(((int) center.getX()), ((int) center.getY()), ((int) center.getZ())),
|
||||||
|
BlockVector3.at(MathUtils.roundHalfUp(center.getX()),
|
||||||
|
center.getY(), MathUtils.roundHalfUp(center.getZ())));
|
||||||
|
return setBlocks(centerRegion, pattern);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make the faces of the given region as if it was a {@link CuboidRegion}.
|
* Make the faces of the given region as if it was a {@link CuboidRegion}.
|
||||||
*
|
*
|
||||||
@ -2971,7 +2990,7 @@ public class EditSession extends AbstractDelegateExtent implements SimpleWorld,
|
|||||||
double scaledZ = (z - zero2D.getZ()) / unit2D.getZ();
|
double scaledZ = (z - zero2D.getZ()) / unit2D.getZ();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (expression.evaluateTimeout(timeout, scaledX, scaledZ, timeout) <= 0) {
|
if (expression.evaluate(new double[]{scaledX, scaledZ}, timeout) <= 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ import com.sk89q.worldedit.command.tool.SinglePickaxe;
|
|||||||
import com.sk89q.worldedit.command.tool.Tool;
|
import com.sk89q.worldedit.command.tool.Tool;
|
||||||
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.Locatable;
|
||||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import com.sk89q.worldedit.function.operation.ChangeSetExecutor;
|
import com.sk89q.worldedit.function.operation.ChangeSetExecutor;
|
||||||
@ -70,7 +71,6 @@ import com.sk89q.worldedit.regions.RegionSelector;
|
|||||||
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
|
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
|
||||||
import com.sk89q.worldedit.regions.selector.RegionSelectorType;
|
import com.sk89q.worldedit.regions.selector.RegionSelectorType;
|
||||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||||
import com.sk89q.worldedit.session.request.Request;
|
|
||||||
import com.sk89q.worldedit.util.Countable;
|
import com.sk89q.worldedit.util.Countable;
|
||||||
import com.sk89q.worldedit.util.HandSide;
|
import com.sk89q.worldedit.util.HandSide;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
@ -313,10 +313,6 @@ public class LocalSession implements TextureHolder {
|
|||||||
return (historyNegativeIndex == null ? historyNegativeIndex = 0 : historyNegativeIndex);
|
return (historyNegativeIndex == null ? historyNegativeIndex = 0 : historyNegativeIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHistoryIndex(int value) {
|
|
||||||
historyNegativeIndex = history.size() - value - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean save() {
|
public boolean save() {
|
||||||
saveHistoryNegativeIndex(uuid, currentWorld);
|
saveHistoryNegativeIndex(uuid, currentWorld);
|
||||||
if (defaultSelector == RegionSelectorType.CUBOID) {
|
if (defaultSelector == RegionSelectorType.CUBOID) {
|
||||||
@ -505,13 +501,14 @@ public class LocalSession implements TextureHolder {
|
|||||||
* Performs an undo.
|
* Performs an undo.
|
||||||
*
|
*
|
||||||
* @param newBlockBag a new block bag
|
* @param newBlockBag a new block bag
|
||||||
* @param player the player
|
* @param actor the actor
|
||||||
* @return whether anything was undone
|
* @return whether anything was undone
|
||||||
*/
|
*/
|
||||||
public EditSession undo(@Nullable BlockBag newBlockBag, Player player) {
|
public EditSession undo(@Nullable BlockBag newBlockBag, Actor actor) {
|
||||||
checkNotNull(player);
|
checkNotNull(actor);
|
||||||
FawePlayer fp = FawePlayer.wrap(player);
|
//TODO This method needs to be modified to use actors instead of FAWEPlayer
|
||||||
loadSessionHistoryFromDisk(player.getUniqueId(), fp.getWorldForEditing());
|
FawePlayer fp = FawePlayer.wrap((Player)actor);
|
||||||
|
loadSessionHistoryFromDisk(actor.getUniqueId(), fp.getWorldForEditing());
|
||||||
if (getHistoryNegativeIndex() < history.size()) {
|
if (getHistoryNegativeIndex() < history.size()) {
|
||||||
FaweChangeSet changeSet = getChangeSet(history.get(getHistoryIndex()));
|
FaweChangeSet changeSet = getChangeSet(history.get(getHistoryIndex()));
|
||||||
try (EditSession newEditSession = new EditSessionBuilder(changeSet.getWorld())
|
try (EditSession newEditSession = new EditSessionBuilder(changeSet.getWorld())
|
||||||
@ -521,7 +518,7 @@ public class LocalSession implements TextureHolder {
|
|||||||
.fastmode(false)
|
.fastmode(false)
|
||||||
.limitUnprocessed(fp)
|
.limitUnprocessed(fp)
|
||||||
.player(fp)
|
.player(fp)
|
||||||
.blockBag(getBlockBag(player))
|
.blockBag(getBlockBag((Player)actor))
|
||||||
.build()) {
|
.build()) {
|
||||||
newEditSession.setBlocks(changeSet, ChangeSetExecutor.Type.UNDO);
|
newEditSession.setBlocks(changeSet, ChangeSetExecutor.Type.UNDO);
|
||||||
setDirty();
|
setDirty();
|
||||||
@ -542,13 +539,14 @@ public class LocalSession implements TextureHolder {
|
|||||||
* Performs a redo
|
* Performs a redo
|
||||||
*
|
*
|
||||||
* @param newBlockBag a new block bag
|
* @param newBlockBag a new block bag
|
||||||
* @param player the player
|
* @param actor the actor
|
||||||
* @return whether anything was redone
|
* @return whether anything was redone
|
||||||
*/
|
*/
|
||||||
public EditSession redo(@Nullable BlockBag newBlockBag, Player player) {
|
public EditSession redo(@Nullable BlockBag newBlockBag, Actor actor) {
|
||||||
checkNotNull(player);
|
checkNotNull(actor);
|
||||||
FawePlayer fp = FawePlayer.wrap(player);
|
//TODO This method needs to be modified to use actors instead of FAWEPlayer
|
||||||
loadSessionHistoryFromDisk(player.getUniqueId(), fp.getWorldForEditing());
|
FawePlayer fp = FawePlayer.wrap((Player)actor);
|
||||||
|
loadSessionHistoryFromDisk(actor.getUniqueId(), fp.getWorldForEditing());
|
||||||
if (getHistoryNegativeIndex() > 0) {
|
if (getHistoryNegativeIndex() > 0) {
|
||||||
setDirty();
|
setDirty();
|
||||||
historyNegativeIndex--;
|
historyNegativeIndex--;
|
||||||
@ -560,7 +558,7 @@ public class LocalSession implements TextureHolder {
|
|||||||
.fastmode(false)
|
.fastmode(false)
|
||||||
.limitUnprocessed(fp)
|
.limitUnprocessed(fp)
|
||||||
.player(fp)
|
.player(fp)
|
||||||
.blockBag(getBlockBag(player))
|
.blockBag(getBlockBag((Player)actor))
|
||||||
.build()) {
|
.build()) {
|
||||||
newEditSession.setBlocks(changeSet, ChangeSetExecutor.Type.REDO);
|
newEditSession.setBlocks(changeSet, ChangeSetExecutor.Type.REDO);
|
||||||
return newEditSession;
|
return newEditSession;
|
||||||
@ -849,14 +847,18 @@ public class LocalSession implements TextureHolder {
|
|||||||
* Get the position use for commands that take a center point
|
* Get the position use for commands that take a center point
|
||||||
* (i.e. //forestgen, etc.).
|
* (i.e. //forestgen, etc.).
|
||||||
*
|
*
|
||||||
* @param player the player
|
* @param actor the actor
|
||||||
* @return the position to use
|
* @return the position to use
|
||||||
* @throws IncompleteRegionException thrown if a region is not fully selected
|
* @throws IncompleteRegionException thrown if a region is not fully selected
|
||||||
*/
|
*/
|
||||||
public BlockVector3 getPlacementPosition(Player player) throws IncompleteRegionException {
|
public BlockVector3 getPlacementPosition(Actor actor) throws IncompleteRegionException {
|
||||||
checkNotNull(player);
|
checkNotNull(actor);
|
||||||
if (!placeAtPos1) {
|
if (!placeAtPos1) {
|
||||||
return player.getBlockIn().toVector().toBlockPoint();
|
if (actor instanceof Locatable) {
|
||||||
|
return ((Locatable) actor).getBlockLocation().toVector().toBlockPoint();
|
||||||
|
} else {
|
||||||
|
throw new IncompleteRegionException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return selector.getPrimaryPosition();
|
return selector.getPrimaryPosition();
|
||||||
@ -1093,9 +1095,9 @@ public class LocalSession implements TextureHolder {
|
|||||||
/**
|
/**
|
||||||
* Tell the player the WorldEdit version.
|
* Tell the player the WorldEdit version.
|
||||||
*
|
*
|
||||||
* @param player the player
|
* @param actor the actor
|
||||||
*/
|
*/
|
||||||
public void tellVersion(Actor player) {
|
public void tellVersion(Actor actor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean shouldUseServerCUI() {
|
public boolean shouldUseServerCUI() {
|
||||||
@ -1325,7 +1327,7 @@ public class LocalSession implements TextureHolder {
|
|||||||
/**
|
/**
|
||||||
* Construct a new edit session.
|
* Construct a new edit session.
|
||||||
*
|
*
|
||||||
* @param player the player
|
* @param player the actor
|
||||||
* @return an edit session
|
* @return an edit session
|
||||||
*/
|
*/
|
||||||
public EditSession createEditSession(Player player) {
|
public EditSession createEditSession(Player player) {
|
||||||
@ -1334,12 +1336,12 @@ public class LocalSession implements TextureHolder {
|
|||||||
BlockBag blockBag = getBlockBag(player);
|
BlockBag blockBag = getBlockBag(player);
|
||||||
|
|
||||||
World world = player.getWorld();
|
World world = player.getWorld();
|
||||||
boolean isPlayer = player.isPlayer();
|
|
||||||
EditSessionBuilder builder = new EditSessionBuilder(world);
|
EditSessionBuilder builder = new EditSessionBuilder(world);
|
||||||
if (player.isPlayer()) builder.player(FawePlayer.wrap(player));
|
if (player.isPlayer()) builder.player(FawePlayer.wrap(player));
|
||||||
builder.blockBag(blockBag);
|
builder.blockBag(blockBag);
|
||||||
builder.fastmode(fastMode);
|
builder.fastmode(fastMode);
|
||||||
|
|
||||||
|
// Create an edit session
|
||||||
EditSession editSession = builder.build();
|
EditSession editSession = builder.build();
|
||||||
|
|
||||||
if (mask != null) {
|
if (mask != null) {
|
||||||
|
@ -109,7 +109,7 @@ public final class WorldEdit {
|
|||||||
private final PlatformManager platformManager = new PlatformManager(this);
|
private final PlatformManager platformManager = new PlatformManager(this);
|
||||||
private final EditSessionFactory editSessionFactory = new EditSessionFactory.EditSessionFactoryImpl(eventBus);
|
private final EditSessionFactory editSessionFactory = new EditSessionFactory.EditSessionFactoryImpl(eventBus);
|
||||||
private final SessionManager sessions = new SessionManager(this);
|
private final SessionManager sessions = new SessionManager(this);
|
||||||
private final ListeningExecutorService executorService = MoreExecutors.listeningDecorator(EvenMoreExecutors.newBoundedCachedThreadPool(0, 1, 20));
|
private final ListeningExecutorService executorService = MoreExecutors.listeningDecorator(EvenMoreExecutors.newBoundedCachedThreadPool(0, 1, 20));;
|
||||||
private final Supervisor supervisor = new SimpleSupervisor();
|
private final Supervisor supervisor = new SimpleSupervisor();
|
||||||
|
|
||||||
private final BlockFactory blockFactory = new BlockFactory(this);
|
private final BlockFactory blockFactory = new BlockFactory(this);
|
||||||
@ -232,7 +232,7 @@ public final class WorldEdit {
|
|||||||
* traversal exploits by checking the root directory and the file directory.
|
* traversal exploits by checking the root directory and the file directory.
|
||||||
* On success, a {@code java.io.File} object will be returned.
|
* On success, a {@code java.io.File} object will be returned.
|
||||||
*
|
*
|
||||||
* @param player the player
|
* @param actor the actor
|
||||||
* @param dir sub-directory to look in
|
* @param dir sub-directory to look in
|
||||||
* @param filename filename (user-submitted)
|
* @param filename filename (user-submitted)
|
||||||
* @param defaultExt append an extension if missing one, null to not use
|
* @param defaultExt append an extension if missing one, null to not use
|
||||||
@ -240,8 +240,8 @@ public final class WorldEdit {
|
|||||||
* @return a file
|
* @return a file
|
||||||
* @throws FilenameException thrown if the filename is invalid
|
* @throws FilenameException thrown if the filename is invalid
|
||||||
*/
|
*/
|
||||||
public File getSafeSaveFile(Player player, File dir, String filename, String defaultExt, String... extensions) throws FilenameException {
|
public File getSafeSaveFile(Actor actor, File dir, String filename, String defaultExt, String... extensions) throws FilenameException {
|
||||||
return getSafeFile(player, dir, filename, defaultExt, extensions, true);
|
return getSafeFile(actor, dir, filename, defaultExt, extensions, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -250,7 +250,7 @@ public final class WorldEdit {
|
|||||||
* traversal exploits by checking the root directory and the file directory.
|
* traversal exploits by checking the root directory and the file directory.
|
||||||
* On success, a {@code java.io.File} object will be returned.
|
* On success, a {@code java.io.File} object will be returned.
|
||||||
*
|
*
|
||||||
* @param player the player
|
* @param actor the actor
|
||||||
* @param dir sub-directory to look in
|
* @param dir sub-directory to look in
|
||||||
* @param filename filename (user-submitted)
|
* @param filename filename (user-submitted)
|
||||||
* @param defaultExt append an extension if missing one, null to not use
|
* @param defaultExt append an extension if missing one, null to not use
|
||||||
@ -258,14 +258,14 @@ public final class WorldEdit {
|
|||||||
* @return a file
|
* @return a file
|
||||||
* @throws FilenameException thrown if the filename is invalid
|
* @throws FilenameException thrown if the filename is invalid
|
||||||
*/
|
*/
|
||||||
public File getSafeOpenFile(Player player, File dir, String filename, String defaultExt, String... extensions) throws FilenameException {
|
public File getSafeOpenFile(Actor actor, File dir, String filename, String defaultExt, String... extensions) throws FilenameException {
|
||||||
return getSafeFile(player, dir, filename, defaultExt, extensions, false);
|
return getSafeFile(actor, dir, filename, defaultExt, extensions, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a safe path to a file.
|
* Get a safe path to a file.
|
||||||
*
|
*
|
||||||
* @param player the player
|
* @param actor the actor
|
||||||
* @param dir sub-directory to look in
|
* @param dir sub-directory to look in
|
||||||
* @param filename filename (user-submitted)
|
* @param filename filename (user-submitted)
|
||||||
* @param defaultExt append an extension if missing one, null to not use
|
* @param defaultExt append an extension if missing one, null to not use
|
||||||
@ -274,16 +274,16 @@ public final class WorldEdit {
|
|||||||
* @return a file
|
* @return a file
|
||||||
* @throws FilenameException thrown if the filename is invalid
|
* @throws FilenameException thrown if the filename is invalid
|
||||||
*/
|
*/
|
||||||
private File getSafeFile(@Nullable Player player, File dir, String filename, String defaultExt, String[] extensions, boolean isSave) throws FilenameException {
|
private File getSafeFile(@Nullable Actor actor, File dir, String filename, String defaultExt, String[] extensions, boolean isSave) throws FilenameException {
|
||||||
if (extensions != null && (extensions.length == 1 && extensions[0] == null)) extensions = null;
|
if (extensions != null && (extensions.length == 1 && extensions[0] == null)) extensions = null;
|
||||||
|
|
||||||
File f;
|
File f;
|
||||||
|
|
||||||
if (filename.equals("#") && player != null) {
|
if (filename.equals("#") && actor != null) {
|
||||||
if (isSave) {
|
if (isSave) {
|
||||||
f = player.openFileSaveDialog(extensions);
|
f = actor.openFileSaveDialog(extensions);
|
||||||
} else {
|
} else {
|
||||||
f = player.openFileOpenDialog(extensions);
|
f = actor.openFileOpenDialog(extensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f == null) {
|
if (f == null) {
|
||||||
|
@ -22,7 +22,6 @@ package com.sk89q.worldedit.command;
|
|||||||
import static com.sk89q.worldedit.command.util.Logging.LogMode.REGION;
|
import static com.sk89q.worldedit.command.util.Logging.LogMode.REGION;
|
||||||
|
|
||||||
import com.boydti.fawe.config.BBC;
|
import com.boydti.fawe.config.BBC;
|
||||||
import com.boydti.fawe.object.visitor.Fast2DIterator;
|
|
||||||
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;
|
||||||
@ -141,14 +140,14 @@ public class BiomeCommands {
|
|||||||
Region region = session.getSelection(world);
|
Region region = session.getSelection(world);
|
||||||
|
|
||||||
if (region instanceof FlatRegion) {
|
if (region instanceof FlatRegion) {
|
||||||
for (BlockVector2 pt : new Fast2DIterator(((FlatRegion) region).asFlatRegion(), editSession)) {
|
for (BlockVector2 pt : ((FlatRegion) region).asFlatRegion()) {
|
||||||
biomes.add(world.getBiome(pt));
|
biomes.add(world.getBiome(pt));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
RegionVisitor visitor = new RegionVisitor(region, position -> {
|
RegionVisitor visitor = new RegionVisitor(region, position -> {
|
||||||
biomes.add(world.getBiome(position.toBlockVector2()));
|
biomes.add(world.getBiome(position.toBlockVector2()));
|
||||||
return true;
|
return true;
|
||||||
}, editSession);
|
});
|
||||||
Operations.completeBlindly(visitor);
|
Operations.completeBlindly(visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ import com.sk89q.worldedit.command.util.CommandPermissions;
|
|||||||
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
|
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
|
||||||
import com.sk89q.worldedit.command.util.Logging;
|
import com.sk89q.worldedit.command.util.Logging;
|
||||||
import com.sk89q.worldedit.entity.Player;
|
import com.sk89q.worldedit.entity.Player;
|
||||||
|
import com.sk89q.worldedit.extension.platform.Actor;
|
||||||
import com.sk89q.worldedit.internal.anvil.ChunkDeleter;
|
import com.sk89q.worldedit.internal.anvil.ChunkDeleter;
|
||||||
import com.sk89q.worldedit.internal.anvil.ChunkDeletionInfo;
|
import com.sk89q.worldedit.internal.anvil.ChunkDeletionInfo;
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
@ -41,6 +42,7 @@ import com.sk89q.worldedit.util.formatting.component.PaginationBox;
|
|||||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||||
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
|
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
|
||||||
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||||
|
import com.sk89q.worldedit.world.World;
|
||||||
import com.sk89q.worldedit.world.storage.LegacyChunkStore;
|
import com.sk89q.worldedit.world.storage.LegacyChunkStore;
|
||||||
import com.sk89q.worldedit.world.storage.McRegionChunkStore;
|
import com.sk89q.worldedit.world.storage.McRegionChunkStore;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -75,7 +77,7 @@ public class ChunkCommands {
|
|||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.chunkinfo")
|
@CommandPermissions("worldedit.chunkinfo")
|
||||||
public void chunkInfo(Player player) {
|
public void chunkInfo(Player player) {
|
||||||
Location pos = player.getBlockIn();
|
Location pos = player.getBlockLocation();
|
||||||
int chunkX = (int) Math.floor(pos.getBlockX() / 16.0);
|
int chunkX = (int) Math.floor(pos.getBlockX() / 16.0);
|
||||||
int chunkZ = (int) Math.floor(pos.getBlockZ() / 16.0);
|
int chunkZ = (int) Math.floor(pos.getBlockZ() / 16.0);
|
||||||
|
|
||||||
@ -90,12 +92,12 @@ public class ChunkCommands {
|
|||||||
desc = "List chunks that your selection includes"
|
desc = "List chunks that your selection includes"
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.listchunks")
|
@CommandPermissions("worldedit.listchunks")
|
||||||
public void listChunks(Player player, LocalSession session,
|
public void listChunks(Actor actor, World world, LocalSession session,
|
||||||
@ArgFlag(name = 'p', desc = "Page number.", def = "1") int page) throws WorldEditException {
|
@ArgFlag(name = 'p', desc = "Page number.", def = "1") int page) throws WorldEditException {
|
||||||
Set<BlockVector2> chunks = session.getSelection(player.getWorld()).getChunks();
|
Set<BlockVector2> chunks = session.getSelection(world).getChunks();
|
||||||
|
|
||||||
PaginationBox paginationBox = PaginationBox.fromStrings("Selected Chunks", "/listchunks -p %page%", chunks);
|
PaginationBox paginationBox = PaginationBox.fromStrings("Selected Chunks", "/listchunks -p %page%", chunks);
|
||||||
player.print(paginationBox.create(page));
|
actor.print(paginationBox.create(page));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -104,10 +106,10 @@ public class ChunkCommands {
|
|||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.delchunks")
|
@CommandPermissions("worldedit.delchunks")
|
||||||
@Logging(REGION)
|
@Logging(REGION)
|
||||||
public void deleteChunks(Player player, LocalSession session,
|
public void deleteChunks(Actor actor, World world, LocalSession session,
|
||||||
@ArgFlag(name = 'o', desc = "Only delete chunks older than the specified time.", def = "")
|
@ArgFlag(name = 'o', desc = "Only delete chunks older than the specified time.", def = "")
|
||||||
ZonedDateTime beforeTime) throws WorldEditException {
|
ZonedDateTime beforeTime) throws WorldEditException {
|
||||||
Path worldDir = player.getWorld().getStoragePath();
|
Path worldDir = world.getStoragePath();
|
||||||
if (worldDir == null) {
|
if (worldDir == null) {
|
||||||
throw new StopExecutionException(TextComponent.of("Couldn't find world folder for this world."));
|
throw new StopExecutionException(TextComponent.of("Couldn't find world folder for this world."));
|
||||||
}
|
}
|
||||||
@ -130,10 +132,10 @@ public class ChunkCommands {
|
|||||||
ChunkDeletionInfo.ChunkBatch newBatch = new ChunkDeletionInfo.ChunkBatch();
|
ChunkDeletionInfo.ChunkBatch newBatch = new ChunkDeletionInfo.ChunkBatch();
|
||||||
newBatch.worldPath = worldDir.toAbsolutePath().normalize().toString();
|
newBatch.worldPath = worldDir.toAbsolutePath().normalize().toString();
|
||||||
newBatch.backup = true;
|
newBatch.backup = true;
|
||||||
final Region selection = session.getSelection(player.getWorld());
|
final Region selection = session.getSelection(world);
|
||||||
if (selection instanceof CuboidRegion) {
|
if (selection instanceof CuboidRegion) {
|
||||||
newBatch.minChunk = BlockVector2.at(selection.getMinimumPoint().getBlockX() >> 4, selection.getMinimumPoint().getBlockZ() >> 4);
|
newBatch.minChunk = selection.getMinimumPoint().shr(4).toBlockVector2();
|
||||||
newBatch.maxChunk = BlockVector2.at(selection.getMaximumPoint().getBlockX() >> 4, selection.getMaximumPoint().getBlockZ() >> 4);
|
newBatch.maxChunk = selection.getMaximumPoint().shr(4).toBlockVector2();
|
||||||
} else {
|
} else {
|
||||||
// this has a possibility to OOM for very large selections still
|
// this has a possibility to OOM for very large selections still
|
||||||
Set<BlockVector2> chunks = selection.getChunks();
|
Set<BlockVector2> chunks = selection.getChunks();
|
||||||
@ -155,13 +157,13 @@ public class ChunkCommands {
|
|||||||
throw new StopExecutionException(TextComponent.of("Failed to write chunk list: " + e.getMessage()));
|
throw new StopExecutionException(TextComponent.of("Failed to write chunk list: " + e.getMessage()));
|
||||||
}
|
}
|
||||||
|
|
||||||
player.print(String.format("%d chunk(s) have been marked for deletion the next time the server starts.",
|
actor.print(String.format("%d chunk(s) have been marked for deletion the next time the server starts.",
|
||||||
newBatch.getChunkCount()));
|
newBatch.getChunkCount()));
|
||||||
if (currentInfo.batches.size() > 1) {
|
if (currentInfo.batches.size() > 1) {
|
||||||
player.printDebug(String.format("%d chunks total marked for deletion. (May have overlaps).",
|
actor.printDebug(String.format("%d chunks total marked for deletion. (May have overlaps).",
|
||||||
currentInfo.batches.stream().mapToInt(ChunkDeletionInfo.ChunkBatch::getChunkCount).sum()));
|
currentInfo.batches.stream().mapToInt(ChunkDeletionInfo.ChunkBatch::getChunkCount).sum()));
|
||||||
}
|
}
|
||||||
player.print(TextComponent.of("You can mark more chunks for deletion, or to stop now, run: ", TextColor.LIGHT_PURPLE)
|
actor.print(TextComponent.of("You can mark more chunks for deletion, or to stop now, run: ", TextColor.LIGHT_PURPLE)
|
||||||
.append(TextComponent.of("/stop", TextColor.AQUA)
|
.append(TextComponent.of("/stop", TextColor.AQUA)
|
||||||
.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, "/stop"))));
|
.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, "/stop"))));
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren