Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-09-06 08:02:50 +02:00
Fix palette / region iteration
Dieser Commit ist enthalten in:
Ursprung
930dfb7f7c
Commit
1e16095cba
@ -249,6 +249,13 @@ public final class BukkitAdapter_1_14 {
|
||||
case 0:
|
||||
ordinal = getArr[i];
|
||||
set[i] = ordinal;
|
||||
switch (ordinal) {
|
||||
case BlockID.AIR:
|
||||
case BlockID.CAVE_AIR:
|
||||
case BlockID.VOID_AIR:
|
||||
air++;
|
||||
}
|
||||
break;
|
||||
case BlockID.AIR:
|
||||
case BlockID.CAVE_AIR:
|
||||
case BlockID.VOID_AIR:
|
||||
@ -270,12 +277,11 @@ public final class BukkitAdapter_1_14 {
|
||||
private static int createPalette(int[] blockToPalette, int[] paletteToBlock, int[] blocksCopy, int[] num_palette_buffer, char[] set) {
|
||||
int air = 0;
|
||||
int num_palette = 0;
|
||||
char airOrdinal = BlockTypes.AIR.getDefaultState().getOrdinalChar();
|
||||
for (int i = 0; i < 4096; i++) {
|
||||
char ordinal = set[i];
|
||||
switch (ordinal) {
|
||||
case 0:
|
||||
ordinal = airOrdinal;
|
||||
ordinal = BlockID.AIR;
|
||||
case BlockID.AIR:
|
||||
case BlockID.CAVE_AIR:
|
||||
case BlockID.VOID_AIR:
|
||||
|
@ -26,6 +26,7 @@ import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import net.minecraft.server.v1_14_R1.BiomeBase;
|
||||
import net.minecraft.server.v1_14_R1.BlockPosition;
|
||||
import net.minecraft.server.v1_14_R1.Chunk;
|
||||
import net.minecraft.server.v1_14_R1.ChunkCoordIntPair;
|
||||
import net.minecraft.server.v1_14_R1.ChunkSection;
|
||||
import net.minecraft.server.v1_14_R1.DataBits;
|
||||
import net.minecraft.server.v1_14_R1.DataPalette;
|
||||
@ -35,8 +36,11 @@ import net.minecraft.server.v1_14_R1.DataPaletteLinear;
|
||||
import net.minecraft.server.v1_14_R1.Entity;
|
||||
import net.minecraft.server.v1_14_R1.EntityTypes;
|
||||
import net.minecraft.server.v1_14_R1.IBlockData;
|
||||
import net.minecraft.server.v1_14_R1.LightEngineThreaded;
|
||||
import net.minecraft.server.v1_14_R1.NBTTagCompound;
|
||||
import net.minecraft.server.v1_14_R1.NBTTagInt;
|
||||
import net.minecraft.server.v1_14_R1.SectionPosition;
|
||||
import net.minecraft.server.v1_14_R1.SystemUtils;
|
||||
import net.minecraft.server.v1_14_R1.TileEntity;
|
||||
import net.minecraft.server.v1_14_R1.WorldServer;
|
||||
import org.bukkit.World;
|
||||
@ -47,6 +51,7 @@ import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Future;
|
||||
@ -439,6 +444,13 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks {
|
||||
};
|
||||
}
|
||||
|
||||
// {//Lighting
|
||||
// for (int layer = 0; layer < 16; layer++) {
|
||||
// if (!set.hasSection(layer)) continue;
|
||||
// //TODO lighting
|
||||
// }
|
||||
// }
|
||||
|
||||
Runnable callback;
|
||||
if (bitMask == 0) {
|
||||
callback = null;
|
||||
|
@ -1,16 +1,28 @@
|
||||
package com.boydti.fawe.bukkit.adapter.mc1_14;
|
||||
|
||||
import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
|
||||
import com.boydti.fawe.object.FaweInputStream;
|
||||
import com.boydti.fawe.object.FaweOutputStream;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import net.minecraft.server.v1_14_R1.Chunk;
|
||||
import net.minecraft.server.v1_14_R1.ChunkSection;
|
||||
import net.minecraft.server.v1_14_R1.NBTBase;
|
||||
import net.minecraft.server.v1_14_R1.NBTTagCompound;
|
||||
import net.minecraft.server.v1_14_R1.PacketPlayOutMapChunk;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class MapChunkUtil_1_14 {
|
||||
private static final Field fieldX;
|
||||
@ -42,6 +54,7 @@ public class MapChunkUtil_1_14 {
|
||||
fieldZ.setAccessible(true);
|
||||
fieldBitMask.setAccessible(true);
|
||||
fieldHeightMap.setAccessible(true);
|
||||
fieldChunkData.setAccessible(true);
|
||||
fieldBlockEntities.setAccessible(true);
|
||||
fieldFull.setAccessible(true);
|
||||
} catch (Throwable e) {
|
||||
@ -60,7 +73,8 @@ public class MapChunkUtil_1_14 {
|
||||
fieldBitMask.set(nmsPacket, packet.getChunk().getBitMask());
|
||||
NBTBase heightMap = adapter.fromNative(packet.getHeightMap());
|
||||
fieldHeightMap.set(nmsPacket, heightMap);
|
||||
fieldChunkData.set(nmsPacket, packet.get());
|
||||
|
||||
fieldChunkData.set(nmsPacket, packet.getSectionBytes());
|
||||
|
||||
Map<BlockVector3, CompoundTag> tiles = packet.getChunk().getTiles();
|
||||
ArrayList<NBTTagCompound> nmsTiles = new ArrayList<>(tiles.size());
|
||||
@ -72,6 +86,7 @@ public class MapChunkUtil_1_14 {
|
||||
fieldFull.set(nmsPacket, packet.isFull());
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
return nmsPacket;
|
||||
|
@ -297,7 +297,6 @@ public enum FaweCache implements Trimable {
|
||||
int ordinal = blocksChars[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++;
|
||||
@ -309,7 +308,7 @@ public enum FaweCache implements Trimable {
|
||||
int ordinal = blocksInts[i];
|
||||
int palette = blockToPalette[ordinal];
|
||||
if (palette == Integer.MAX_VALUE) {
|
||||
BlockState state = BlockTypesCache.states[ordinal];
|
||||
// BlockState state = BlockTypesCache.states[ordinal];
|
||||
blockToPalette[ordinal] = palette = num_palette;
|
||||
paletteToBlock[num_palette] = ordinal;
|
||||
num_palette++;
|
||||
@ -326,6 +325,11 @@ public enum FaweCache implements Trimable {
|
||||
|
||||
// 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 blockBitArrayEnd = (bitsPerEntry * 4096) >> 6;
|
||||
if (num_palette == 1) {
|
||||
// Set a value, because minecraft needs it for some reason
|
||||
@ -347,8 +351,8 @@ public enum FaweCache implements Trimable {
|
||||
|
||||
return palette;
|
||||
} catch (Throwable e) {
|
||||
Arrays.fill(blockToPalette, Integer.MAX_VALUE);
|
||||
e.printStackTrace();
|
||||
Arrays.fill(blockToPalette, Integer.MAX_VALUE);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import com.sk89q.worldedit.world.block.BlockID;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.registry.BlockRegistry;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -66,28 +67,36 @@ public interface IBlocks extends Trimable {
|
||||
char[] ids = this.getArray(layer);
|
||||
|
||||
int nonEmpty = 0; // TODO optimize into same loop as toPalette
|
||||
for (char id : ids) {
|
||||
if (id != 0) nonEmpty++;
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
char ordinal = ids[i];
|
||||
switch (ordinal) {
|
||||
case BlockID.__RESERVED__:
|
||||
case BlockID.CAVE_AIR:
|
||||
case BlockID.VOID_AIR:
|
||||
ids[i] = BlockID.AIR;
|
||||
case BlockID.AIR:
|
||||
continue;
|
||||
default:
|
||||
nonEmpty++;
|
||||
}
|
||||
}
|
||||
|
||||
sectionWriter.writeShort(nonEmpty); // non empty
|
||||
|
||||
sectionWriter.writeByte(14); // globalPaletteBitsPerBlock
|
||||
|
||||
if (true) {
|
||||
BitArray4096 bits = new BitArray4096(14); // globalPaletteBitsPerBlock
|
||||
bits.setAt(0, 0);
|
||||
for (int i = 0; i < 4096; i++) {
|
||||
int ordinal = ids[i];
|
||||
BlockState state = BlockState.getFromOrdinal(ordinal);
|
||||
if (!state.getMaterial().isAir()) {
|
||||
int mcId = registry.getInternalBlockStateId(state).getAsInt();
|
||||
bits.setAt(i, mcId);
|
||||
}
|
||||
}
|
||||
sectionWriter.write(bits.getData());
|
||||
} else {
|
||||
|
||||
// if (false) {
|
||||
// sectionWriter.writeByte(14); // globalPaletteBitsPerBlock
|
||||
// BitArray4096 bits = new BitArray4096(14); // globalPaletteBitsPerBlock
|
||||
// bits.setAt(0, 0);
|
||||
// for (int i = 0; i < 4096; i++) {
|
||||
// int ordinal = ids[i];
|
||||
// BlockState state = BlockState.getFromOrdinal(ordinal);
|
||||
// if (!state.getMaterial().isAir()) {
|
||||
// int mcId = registry.getInternalBlockStateId(state).getAsInt();
|
||||
// bits.setAt(i, mcId);
|
||||
// }
|
||||
// }
|
||||
// sectionWriter.write(bits.getData());
|
||||
// } else {
|
||||
FaweCache.Palette palette = FaweCache.IMP.toPalette(0, ids);
|
||||
|
||||
sectionWriter.writeByte(palette.bitsPerEntry); // bits per block
|
||||
@ -95,11 +104,11 @@ public interface IBlocks extends Trimable {
|
||||
for (int i = 0; i < palette.paletteToBlockLength; i++) {
|
||||
int ordinal = palette.paletteToBlock[i];
|
||||
switch (ordinal) {
|
||||
case BlockID.__RESERVED__:
|
||||
case BlockID.CAVE_AIR:
|
||||
case BlockID.VOID_AIR:
|
||||
case BlockID.AIR:
|
||||
case BlockID.__RESERVED__:
|
||||
sectionWriter.writeVarInt(0);
|
||||
sectionWriter.write(0);
|
||||
break;
|
||||
default:
|
||||
BlockState state = BlockState.getFromOrdinal(ordinal);
|
||||
@ -112,7 +121,7 @@ public interface IBlocks extends Trimable {
|
||||
for (int i = 0; i < palette.blockStatesLength; i++) {
|
||||
sectionWriter.writeLong(palette.blockStates[i]);
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
// if (writeBiomes) {
|
||||
|
@ -115,7 +115,7 @@ public class CharFilterBlock extends ChunkFilterBlock {
|
||||
|
||||
@Override
|
||||
public void filter(Filter filter, int yStart, int yEnd) {
|
||||
for (y = yStart, index = yStart << 8; y < yEnd; y++) {
|
||||
for (y = yStart, index = yStart << 8; y <= yEnd; y++) {
|
||||
for (z = 0; z < 16; z++) {
|
||||
for (x = 0; x < 16; x++, index++) {
|
||||
filter.applyBlock(this);
|
||||
|
@ -57,7 +57,7 @@ public class ChunkPacket implements Function<byte[], byte[]>, Supplier<byte[]> {
|
||||
return chunk;
|
||||
}
|
||||
|
||||
private byte[] getSectionBytes() {
|
||||
public byte[] getSectionBytes() {
|
||||
byte[] tmp = this.sectionBytes;
|
||||
if (tmp == null) {
|
||||
synchronized (this) {
|
||||
@ -107,7 +107,6 @@ public class ChunkPacket implements Function<byte[], byte[]>, Supplier<byte[]> {
|
||||
|
||||
fos.writeVarInt(getChunk().getBitMask());
|
||||
|
||||
|
||||
fos.writeNBT("", getHeightMap());
|
||||
|
||||
fos.writeVarInt(sectionBytes.length);
|
||||
|
@ -8,6 +8,7 @@ import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
@ -25,7 +26,7 @@ public class ChunkSendProcessor implements IBatchProcessor {
|
||||
public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) {
|
||||
int chunkX = chunk.getX();
|
||||
int chunkZ = chunk.getZ();
|
||||
boolean replaceAll = true;
|
||||
boolean replaceAll = set.getBiomeType(0, 0) != null;
|
||||
ChunkPacket packet = new ChunkPacket(chunkX, chunkZ, () -> set, replaceAll);
|
||||
Stream<Player> stream = this.players.get();
|
||||
if (stream == null) {
|
||||
@ -41,4 +42,4 @@ public class ChunkSendProcessor implements IBatchProcessor {
|
||||
public Extent construct(Extent child) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -328,31 +328,67 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
||||
@NotNull @Override
|
||||
public Iterator<BlockVector2> iterator() {
|
||||
return new Iterator<BlockVector2>() {
|
||||
private MutableBlockVector2 pos = new MutableBlockVector2().setComponents(maxX + 1, maxZ);
|
||||
final MutableBlockVector2 mutable = new MutableBlockVector2(0, 0);
|
||||
|
||||
int bx = minX;
|
||||
int bz = minZ;
|
||||
|
||||
int tx = maxX;
|
||||
int tz = maxZ;
|
||||
|
||||
private int x = minX;
|
||||
private int z = minZ;
|
||||
|
||||
int regionX = x >> 5;
|
||||
int regionZ = z >> 5;
|
||||
int rbx = Math.max(bx, regionX << 5);
|
||||
int rbz = Math.max(bz, regionZ << 5);
|
||||
int rtx = Math.min(tx, 31 + (regionX << 5));
|
||||
int rtz = Math.min(tz, 31 + (regionZ << 5));
|
||||
|
||||
boolean hasNext = true;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return pos != null;
|
||||
return hasNext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockVector2 next() {
|
||||
MutableBlockVector2 result = pos;
|
||||
// calc next
|
||||
pos.setComponents(pos.getX() - 1, pos.getZ());
|
||||
if (pos.getX() <= minX) {
|
||||
if (pos.getZ() == minZ) {
|
||||
pos = null;
|
||||
} else if (pos.getX() < minX) {
|
||||
pos.setComponents(maxX, pos.getZ() - 1);
|
||||
mutable.mutX(x);
|
||||
mutable.mutZ(z);
|
||||
if (++x > rtx) {
|
||||
if (++z > rtz) {
|
||||
if (x > tx) {
|
||||
x = bx;
|
||||
if (z > tz) {
|
||||
if (!hasNext) {
|
||||
throw new NoSuchElementException("End of iterator") {
|
||||
@Override
|
||||
public Throwable fillInStackTrace() {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
}
|
||||
x = tx;
|
||||
hasNext = false;
|
||||
return mutable;
|
||||
}
|
||||
} else {
|
||||
z = rbz;
|
||||
}
|
||||
regionX = x >> 5;
|
||||
regionZ = z >> 5;
|
||||
rbx = Math.max(bx, regionX << 5);
|
||||
rbz = Math.max(bz, regionZ << 5);
|
||||
rtx = Math.min(tx, 31 + (regionX << 5));
|
||||
rtz = Math.min(tz, 31 + (regionZ << 5));
|
||||
} else {
|
||||
x = rbx;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("This set is immutable.");
|
||||
return mutable;
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -628,19 +664,19 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
||||
|
||||
@Override
|
||||
public void filter(final IChunk chunk, final Filter filter, ChunkFilterBlock block, final IChunkGet get, final IChunkSet set) {
|
||||
int x = chunk.getX();
|
||||
int z = chunk.getZ();
|
||||
block = block.init(x, z, get);
|
||||
int chunkX = chunk.getX();
|
||||
int chunkZ = chunk.getZ();
|
||||
block = block.init(chunkX, chunkZ, get);
|
||||
|
||||
|
||||
if ((minX + 15) >> 4 <= x && (maxX - 15) >> 4 >= x && (minZ + 15) >> 4 <= z && (maxZ - 15) >> 4 >= z) {
|
||||
if ((minX + 15) >> 4 <= chunkX && (maxX - 15) >> 4 >= chunkX && (minZ + 15) >> 4 <= chunkZ && (maxZ - 15) >> 4 >= chunkZ) {
|
||||
filter(chunk, filter, block, get, set, minY, maxY);
|
||||
return;
|
||||
}
|
||||
int localMinX = Math.max(minX, x << 4) & 15;
|
||||
int localMaxX = Math.min(maxX, 15 + (x << 4)) & 15;
|
||||
int localMinZ = Math.max(minZ, z << 4) & 15;
|
||||
int localMaxZ = Math.min(maxZ, 15 + (z << 4)) & 15;
|
||||
int localMinX = Math.max(minX, chunkX << 4) & 15;
|
||||
int localMaxX = Math.min(maxX, 15 + (chunkX << 4)) & 15;
|
||||
int localMinZ = Math.max(minZ, chunkZ << 4) & 15;
|
||||
int localMaxZ = Math.min(maxZ, 15 + (chunkZ << 4)) & 15;
|
||||
|
||||
int yStart = (minY & 15);
|
||||
int yEnd = (maxY & 15);
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren