geforkt von Mirrors/FastAsyncWorldEdit
Looks like working block setting and removal
Dieser Commit ist enthalten in:
Ursprung
b59b95c282
Commit
3f3c49c0a8
@ -58,6 +58,7 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
private boolean listeningImages;
|
||||
private BukkitImageListener imageListener;
|
||||
private CFIPacketListener packetListener;
|
||||
private final boolean chunksStretched;
|
||||
|
||||
public VaultUtil getVault() {
|
||||
return this.vault;
|
||||
@ -99,6 +100,8 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
// The tick limiter
|
||||
new ChunkListener_9();
|
||||
});
|
||||
|
||||
chunksStretched = Integer.parseInt(Bukkit.getMinecraftVersion().split("\\.")[1]) >= 16;
|
||||
}
|
||||
|
||||
@Override // Please don't delete this again, it's WIP
|
||||
@ -302,6 +305,11 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChunksStretched() {
|
||||
return chunksStretched;
|
||||
}
|
||||
|
||||
private void setupPlotSquared() {
|
||||
Plugin plotSquared = this.plugin.getServer().getPluginManager().getPlugin("PlotSquared");
|
||||
if (plotSquared == null)
|
||||
|
@ -5,7 +5,7 @@ import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
||||
import com.boydti.fawe.bukkit.adapter.NMSAdapter;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.collection.BitArray;
|
||||
import com.boydti.fawe.object.collection.BitArrayUnstretched;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
@ -232,11 +232,13 @@ public final class BukkitAdapter_1_16_1 extends NMSAdapter {
|
||||
bitsPerEntry = Math.max(bitsPerEntry, 1); // For some reason minecraft needs 4096 bits to store 0 entries
|
||||
}
|
||||
|
||||
final int blockBitArrayEnd = (bitsPerEntry * 4096) >> 6;
|
||||
final int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntry);
|
||||
final int blockBitArrayEnd = MathMan.ceilZero((float) 4096 / blocksPerLong);
|
||||
|
||||
if (num_palette == 1) {
|
||||
for (int i = 0; i < blockBitArrayEnd; i++) blockStates[i] = 0;
|
||||
} else {
|
||||
final BitArray bitArray = new BitArray(bitsPerEntry, 4096, blockStates);
|
||||
final BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntry, blockStates);
|
||||
bitArray.fromRaw(blocksCopy);
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
||||
import com.boydti.fawe.bukkit.adapter.mc1_16_1.nbt.LazyCompoundTag_1_16_1;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.collection.AdaptedMap;
|
||||
import com.boydti.fawe.object.collection.BitArray;
|
||||
import com.boydti.fawe.object.collection.BitArrayUnstretched;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
@ -553,7 +553,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
||||
final int bitsPerEntry = (int) BukkitAdapter_1_16_1.fieldBitsPerEntry.get(bits);
|
||||
final long[] blockStates = bits.a();
|
||||
|
||||
new BitArray(bitsPerEntry, 4096, blockStates).toRaw(data);
|
||||
new BitArrayUnstretched(bitsPerEntry, blockStates).toRaw(data);
|
||||
|
||||
int num_palette;
|
||||
if (palette instanceof DataPaletteLinear) {
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.boydti.fawe;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.slf4j.LoggerFactory.getLogger;
|
||||
|
||||
import com.boydti.fawe.beta.IChunkSet;
|
||||
import com.boydti.fawe.beta.Trimable;
|
||||
@ -9,6 +8,7 @@ import com.boydti.fawe.beta.implementation.queue.Pool;
|
||||
import com.boydti.fawe.beta.implementation.queue.QueuePool;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.collection.BitArray;
|
||||
import com.boydti.fawe.object.collection.BitArrayUnstretched;
|
||||
import com.boydti.fawe.object.collection.CleanableThreadLocal;
|
||||
import com.boydti.fawe.object.collection.VariableThreadLocal;
|
||||
import com.boydti.fawe.object.exception.FaweBlockBagException;
|
||||
@ -299,6 +299,102 @@ public enum FaweCache implements Trimable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert raw int array to unstretched palette (1.16)
|
||||
* @param layerOffset
|
||||
* @param blocks
|
||||
* @return palette
|
||||
*/
|
||||
public Palette toPaletteUnstretched(int layerOffset, char[] blocks) {
|
||||
return toPaletteUnstretched(layerOffset, null, blocks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert raw int array to unstretched palette (1.16)
|
||||
* @param layerOffset
|
||||
* @param blocks
|
||||
* @return palette
|
||||
*/
|
||||
public Palette toPaletteUnstretched(int layerOffset, int[] blocks) {
|
||||
return toPaletteUnstretched(layerOffset, blocks, null);
|
||||
}
|
||||
|
||||
private Palette toPaletteUnstretched(int layerOffset, int[] blocksInts, char[] blocksChars) {
|
||||
int[] blockToPalette = BLOCK_TO_PALETTE.get();
|
||||
int[] paletteToBlock = PALETTE_TO_BLOCK.get();
|
||||
long[] blockStates = BLOCK_STATES.get();
|
||||
int[] blocksCopy = SECTION_BLOCKS.get();
|
||||
|
||||
try {
|
||||
int num_palette = 0;
|
||||
int blockIndexStart = layerOffset << 12;
|
||||
int blockIndexEnd = blockIndexStart + 4096;
|
||||
if (blocksChars != null) {
|
||||
for (int i = blockIndexStart, j = 0; i < blockIndexEnd; i++, j++) {
|
||||
int ordinal = blocksChars[i];
|
||||
int palette = blockToPalette[ordinal];
|
||||
if (palette == Integer.MAX_VALUE) {
|
||||
blockToPalette[ordinal] = palette = num_palette;
|
||||
paletteToBlock[num_palette] = ordinal;
|
||||
num_palette++;
|
||||
}
|
||||
blocksCopy[j] = palette;
|
||||
}
|
||||
} else if (blocksInts != null) {
|
||||
for (int i = blockIndexStart, j = 0; i < blockIndexEnd; i++, j++) {
|
||||
int ordinal = blocksInts[i];
|
||||
int palette = blockToPalette[ordinal];
|
||||
if (palette == Integer.MAX_VALUE) {
|
||||
// BlockState state = BlockTypesCache.states[ordinal];
|
||||
blockToPalette[ordinal] = palette = num_palette;
|
||||
paletteToBlock[num_palette] = ordinal;
|
||||
num_palette++;
|
||||
}
|
||||
blocksCopy[j] = palette;
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_palette; i++) {
|
||||
blockToPalette[paletteToBlock[i]] = Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
// BlockStates
|
||||
int bitsPerEntry = MathMan.log2nlz(num_palette - 1);
|
||||
if (Settings.IMP.PROTOCOL_SUPPORT_FIX || num_palette != 1) {
|
||||
bitsPerEntry = Math.max(bitsPerEntry, 4); // Protocol support breaks <4 bits per entry
|
||||
} else {
|
||||
bitsPerEntry = Math.max(bitsPerEntry, 1); // For some reason minecraft needs 4096 bits to store 0 entries
|
||||
}
|
||||
int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntry);
|
||||
int blockBitArrayEnd = MathMan.ceilZero((float) 4096 / blocksPerLong);
|
||||
if (num_palette == 1) {
|
||||
// Set a value, because minecraft needs it for some reason
|
||||
blockStates[0] = 0;
|
||||
blockBitArrayEnd = 1;
|
||||
} else {
|
||||
BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntry, blockStates);
|
||||
bitArray.fromRaw(blocksCopy);
|
||||
}
|
||||
|
||||
// Construct palette
|
||||
Palette palette = PALETTE_CACHE.get();
|
||||
palette.bitsPerEntry = bitsPerEntry;
|
||||
palette.paletteToBlockLength = num_palette;
|
||||
palette.paletteToBlock = paletteToBlock;
|
||||
|
||||
palette.blockStatesLength = blockBitArrayEnd;
|
||||
palette.blockStates = blockStates;
|
||||
|
||||
return palette;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
Arrays.fill(blockToPalette, Integer.MAX_VALUE);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Vector cache
|
||||
*/
|
||||
|
@ -41,4 +41,8 @@ public interface IFawe {
|
||||
|
||||
Preloader getPreloader();
|
||||
|
||||
default boolean isChunksStretched() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -45,11 +45,11 @@ public interface IBlocks extends Trimable {
|
||||
|
||||
IBlocks reset();
|
||||
|
||||
default byte[] toByteArray(boolean full) {
|
||||
return toByteArray(null, getBitMask(), full);
|
||||
default byte[] toByteArray(boolean full, boolean stretched) {
|
||||
return toByteArray(null, getBitMask(), full, stretched);
|
||||
}
|
||||
|
||||
default byte[] toByteArray(byte[] buffer, int bitMask, boolean full) {
|
||||
default byte[] toByteArray(byte[] buffer, int bitMask, boolean full, boolean stretched) {
|
||||
if (buffer == null) {
|
||||
buffer = new byte[1024];
|
||||
}
|
||||
@ -81,7 +81,12 @@ public interface IBlocks extends Trimable {
|
||||
}
|
||||
|
||||
sectionWriter.writeShort(nonEmpty); // non empty
|
||||
FaweCache.Palette palette = FaweCache.IMP.toPalette(0, ids);
|
||||
FaweCache.Palette palette;
|
||||
if (stretched) {
|
||||
palette = FaweCache.IMP.toPalette(0, ids);
|
||||
} else {
|
||||
palette = FaweCache.IMP.toPaletteUnstretched(0, ids);
|
||||
}
|
||||
|
||||
sectionWriter.writeByte(palette.bitsPerEntry); // bits per block
|
||||
sectionWriter.writeVarInt(palette.paletteToBlockLength);
|
||||
|
@ -1,10 +1,12 @@
|
||||
package com.boydti.fawe.beta.implementation.packet;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.beta.IBlocks;
|
||||
import com.boydti.fawe.object.FaweOutputStream;
|
||||
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.function.Function;
|
||||
@ -64,7 +66,7 @@ public class ChunkPacket implements Function<byte[], byte[]>, Supplier<byte[]> {
|
||||
if (sectionBytes == null) {
|
||||
IBlocks tmpChunk = getChunk();
|
||||
byte[] buf = FaweCache.IMP.BYTE_BUFFER_8192.get();
|
||||
sectionBytes = tmpChunk.toByteArray(buf, tmpChunk.getBitMask(), this.full);
|
||||
sectionBytes = tmpChunk.toByteArray(buf, tmpChunk.getBitMask(), this.full, Fawe.imp().isChunksStretched());
|
||||
}
|
||||
tmp = sectionBytes;
|
||||
}
|
||||
@ -72,6 +74,7 @@ public class ChunkPacket implements Function<byte[], byte[]>, Supplier<byte[]> {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
public Object getNativePacket() {
|
||||
return nativePacket;
|
||||
}
|
||||
|
@ -0,0 +1,115 @@
|
||||
package com.boydti.fawe.object.collection;
|
||||
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
|
||||
public final class BitArrayUnstretched {
|
||||
|
||||
private final long[] data;
|
||||
private final int bitsPerEntry;
|
||||
private final int maxSeqLocIndex;
|
||||
private final int emptyBitCount;
|
||||
private final long mask;
|
||||
private final int longLen;
|
||||
|
||||
public BitArrayUnstretched(int bitsPerEntry, long[] buffer) {
|
||||
this.bitsPerEntry = bitsPerEntry;
|
||||
this.mask = (1L << bitsPerEntry) - 1L;
|
||||
this.emptyBitCount = 64 % bitsPerEntry;
|
||||
this.maxSeqLocIndex = 64 - (bitsPerEntry + emptyBitCount);
|
||||
final int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntry);
|
||||
this.longLen = MathMan.ceilZero((float) 4096 / blocksPerLong);
|
||||
if (buffer.length < longLen) {
|
||||
this.data = new long[longLen];
|
||||
} else {
|
||||
this.data = buffer;
|
||||
}
|
||||
}
|
||||
|
||||
public long[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public final void set(int index, int value) {
|
||||
if (longLen == 0) return;
|
||||
int bitIndexStart = index * bitsPerEntry + MathMan.floorZero((double) index / longLen) * emptyBitCount;
|
||||
int longIndexStart = bitIndexStart >> 6;
|
||||
int localBitIndexStart = bitIndexStart & 63;
|
||||
this.data[longIndexStart] = this.data[longIndexStart] & ~(mask << localBitIndexStart) | (long) value << localBitIndexStart;
|
||||
}
|
||||
|
||||
public final int get(int index) {
|
||||
if (longLen == 0) return 0;
|
||||
int bitIndexStart = index * bitsPerEntry + MathMan.floorZero((double) index / longLen) * emptyBitCount;
|
||||
|
||||
int longIndexStart = bitIndexStart >> 6;
|
||||
|
||||
int localBitIndexStart = bitIndexStart & 63;
|
||||
return (int)(this.data[longIndexStart] >>> localBitIndexStart & mask);
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return longLen;
|
||||
}
|
||||
|
||||
public final void fromRaw(int[] arr) {
|
||||
final long[] data = this.data;
|
||||
final int bitsPerEntry = this.bitsPerEntry;
|
||||
final int maxSeqLocIndex = this.maxSeqLocIndex;
|
||||
|
||||
int localStart = 0;
|
||||
int arrI = 0;
|
||||
long l = 0;
|
||||
for (int i = 0; i < longLen; i++) {
|
||||
int lastVal;
|
||||
for (; localStart <= maxSeqLocIndex && arrI < 4096; localStart += bitsPerEntry) {
|
||||
lastVal = arr[arrI++];
|
||||
l |= ((long) lastVal << localStart);
|
||||
}
|
||||
localStart = 0;
|
||||
data[i] = l;
|
||||
l = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public final int[] toRaw() {
|
||||
return toRaw(new int[4096]);
|
||||
}
|
||||
|
||||
public final int[] toRaw(int[] buffer) {
|
||||
final long[] data = this.data;
|
||||
final int bitsPerEntry = this.bitsPerEntry;
|
||||
final int maxSeqLocIndex = this.maxSeqLocIndex;
|
||||
|
||||
int localStart = 0;
|
||||
int arrI = 0;
|
||||
for (int i = 0; i < longLen; i++) {
|
||||
long l = data[i];
|
||||
char lastVal;
|
||||
for (; localStart <= maxSeqLocIndex && arrI < 4096; localStart += bitsPerEntry) {
|
||||
lastVal = (char) (l >>> localStart & this.mask);
|
||||
buffer[arrI++] = lastVal;
|
||||
}
|
||||
localStart = 0;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public final char[] toRaw(char[] buffer) {
|
||||
final long[] data = this.data;
|
||||
final int bitsPerEntry = this.bitsPerEntry;
|
||||
final int maxSeqLocIndex = this.maxSeqLocIndex;
|
||||
|
||||
int localStart = 0;
|
||||
int arrI = 0;
|
||||
for (int i = 0; i < longLen; i++) {
|
||||
long l = data[i];
|
||||
char lastVal;
|
||||
for (; localStart <= maxSeqLocIndex && arrI < 4096; localStart += bitsPerEntry) {
|
||||
lastVal = (char) (l >>> localStart & this.mask);
|
||||
buffer[arrI++] = lastVal;
|
||||
}
|
||||
localStart = 0;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren