mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-02 19:36:41 +00:00
merge 1.16
This commit is contained in:
@ -305,7 +305,7 @@ public class Fawe {
|
||||
br.close();
|
||||
this.version = FaweVersion.tryParse(versionString, commitString, dateString);
|
||||
Settings.IMP.DATE = new Date(100 + version.year, version.month, version.day).toGMTString();
|
||||
Settings.IMP.BUILD = "https://ci.athion.net/job/FastAsyncWorldEdit-1.15/" + version.build;
|
||||
Settings.IMP.BUILD = "https://ci.athion.net/job/FastAsyncWorldEdit-1.16/" + version.build;
|
||||
Settings.IMP.COMMIT = "https://github.com/IntellectualSites/FastAsyncWorldEdit/commit/" + Integer.toHexString(version.hash);
|
||||
} catch (Throwable ignore) {}
|
||||
try {
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -32,9 +32,9 @@ public class FaweVersion {
|
||||
|
||||
@Override public String toString() {
|
||||
if (hash == 0 && build == 0) {
|
||||
return "FastAsyncWorldEdit-1.15-NoVer-SNAPSHOT";
|
||||
return "FastAsyncWorldEdit-1.16-NoVer-SNAPSHOT";
|
||||
} else {
|
||||
return "FastAsyncWorldEdit-1.15" + build;
|
||||
return "FastAsyncWorldEdit-1.16" + build;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -181,6 +181,18 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
|
||||
}
|
||||
|
||||
@Override public void setFullBright(int layer) {
|
||||
if (light == null) {
|
||||
light = new char[16][];
|
||||
}
|
||||
if (light[layer] == null) {
|
||||
light[layer] = new char[4096];
|
||||
}
|
||||
if (skyLight == null) {
|
||||
skyLight = new char[16][];
|
||||
}
|
||||
if (skyLight[layer] == null) {
|
||||
skyLight[layer] = new char[4096];
|
||||
}
|
||||
Arrays.fill(light[layer], (char) 15);
|
||||
Arrays.fill(skyLight[layer], (char) 15);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -13,12 +13,16 @@ import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.util.SideEffectSet;
|
||||
import com.sk89q.worldedit.util.TreeGenerator;
|
||||
import com.sk89q.worldedit.world.AbstractWorld;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.File;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
@ -35,6 +39,11 @@ public class MCAWorld extends AbstractWorld {
|
||||
return path.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean setTile(int x, int y, int z, CompoundTag tile) throws WorldEditException {
|
||||
@ -46,6 +55,11 @@ public class MCAWorld extends AbstractWorld {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SideEffect> applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet) throws WorldEditException {
|
||||
return SideEffectSet.none().getSideEffectsToApply();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearContainerBlockContents(BlockVector3 position) {
|
||||
return false;
|
||||
|
@ -31,7 +31,8 @@ public class CopyPastaBrush implements Brush, ResettableTool {
|
||||
|
||||
private final LocalSession session;
|
||||
private final Player player;
|
||||
public boolean autoRotate, randomRotate;
|
||||
public boolean autoRotate;
|
||||
public boolean randomRotate;
|
||||
|
||||
public CopyPastaBrush(Player player, LocalSession session, boolean randomRotate, boolean autoRotate) {
|
||||
session.setClipboard(null);
|
||||
|
@ -29,10 +29,7 @@ import com.boydti.fawe.util.TextureUtil;
|
||||
import com.boydti.fawe.util.image.Drawable;
|
||||
import com.boydti.fawe.util.image.ImageViewer;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
@ -48,9 +45,7 @@ import com.sk89q.worldedit.math.transform.Transform;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.util.Identifiable;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.util.TreeGenerator;
|
||||
import com.sk89q.worldedit.util.*;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||
@ -68,6 +63,7 @@ import java.lang.reflect.Field;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.function.Supplier;
|
||||
@ -750,12 +746,24 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
||||
return BlockVector3.at(getWidth() - 1, 255, getLength() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SideEffect> applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet)
|
||||
throws WorldEditException{
|
||||
return SideEffectSet.none().getSideEffectsToApply();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block)
|
||||
throws WorldEditException {
|
||||
return setBlock(position.getBlockX(), position.getBlockY(), position.getBlockZ(), block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects)
|
||||
throws WorldEditException {
|
||||
return setBlock(position.getBlockX(), position.getBlockY(), position.getBlockZ(), block);
|
||||
}
|
||||
|
||||
private boolean setBlock(int x, int y, int z, char combined) {
|
||||
int index = z * getWidth() + x;
|
||||
if (index < 0 || index >= getArea()) {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -24,9 +24,7 @@ import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Direction;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.util.TreeGenerator;
|
||||
import com.sk89q.worldedit.util.*;
|
||||
import com.sk89q.worldedit.world.AbstractWorld;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
@ -38,6 +36,7 @@ import com.sk89q.worldedit.world.weather.WeatherType;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class WorldWrapper extends AbstractWorld {
|
||||
|
||||
@ -88,6 +87,12 @@ public class WorldWrapper extends AbstractWorld {
|
||||
return parent.useItem(position, item, face);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SideEffect> applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet)
|
||||
throws WorldEditException{
|
||||
return parent.applySideEffects(position, previousType, sideEffectSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, boolean notifyAndLight) throws WorldEditException {
|
||||
return parent.setBlock(position, block, notifyAndLight);
|
||||
@ -99,6 +104,11 @@ public class WorldWrapper extends AbstractWorld {
|
||||
return parent.setBlock(x, y, z, block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException {
|
||||
return parent.setBlock(position, block, sideEffects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setTile(int x, int y, int z, CompoundTag tile) throws WorldEditException {
|
||||
return parent.setTile(x, y, z, tile);
|
||||
|
Reference in New Issue
Block a user