Fixed importing schem incorrectly after certain x/y/z value

This commit is contained in:
LOOHP 2020-10-30 18:45:23 +08:00
parent ae11665312
commit 5c69de1637
4 changed files with 145 additions and 34 deletions

View File

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.loohp</groupId>
<artifactId>Limbo</artifactId>
<version>0.3.3-ALPHA</version>
<version>0.3.4-ALPHA</version>
<build>
<sourceDirectory>src</sourceDirectory>
<resources>

View File

@ -3,9 +3,13 @@ package com.loohp.limbo.Server.Packets;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import com.loohp.limbo.Utils.ChunkDataUtils;
import com.loohp.limbo.Utils.BitsUtils;
import com.loohp.limbo.Utils.DataTypeIO;
import com.loohp.limbo.World.Environment;
import com.loohp.limbo.World.GeneratedBlockDataMappings;
@ -105,8 +109,9 @@ public class PacketPlayOutMapChunk extends PacketOut {
int newBits = 32 - Integer.numberOfLeadingZeros(section.getPalette().size() - 1);
newBits = Math.max(newBits, 4);
//Limbo.getInstance().getConsole().sendMessage(i + " " + newBits);
if (newBits <= 8) {
/*
if (newBits == 4) {
dataOut.writeByte(4);
} else {
@ -114,26 +119,80 @@ public class PacketPlayOutMapChunk extends PacketOut {
ChunkDataUtils.adjustBlockStateBits(newBits, section, chunk.getDataVersion());
dataOut.writeByte(8);
}
*/
dataOut.writeByte(newBits);
DataTypeIO.writeVarInt(dataOut, section.getPalette().size());
//Limbo.getInstance().getConsole().sendMessage(section.getPalette().size());
Iterator<CompoundTag> itr1 = section.getPalette().iterator();
//Limbo.getInstance().getConsole().sendMessage("Nonnull -> " + i + " " + newBits);
counter = 0;
while (itr1.hasNext()) {
CompoundTag tag = itr1.next();
DataTypeIO.writeVarInt(dataOut, GeneratedBlockDataMappings.getGlobalPaletteIDFromState(tag));
//Limbo.getInstance().getConsole().sendMessage(tag + " -> " + GeneratedDataUtils.getGlobalPaletteIDFromState(tag));
}
} else {
dataOut.writeByte(14);
BitSet bits = BitSet.valueOf(section.getBlockStates());
int shift = 64 % newBits;
int longsNeeded = (int) Math.ceil(4096 / (double) (64 / newBits));
for (int u = 64; u <= bits.length(); u += 64) {
bits = BitsUtils.shiftAfter(bits, u - shift, shift);
}
DataTypeIO.writeVarInt(dataOut, section.getBlockStates().length);
for (int u = 0; u < section.getBlockStates().length; u++) {
dataOut.writeLong(section.getBlockStates()[u]);
long[] formattedLongs = bits.toLongArray();
//Limbo.getInstance().getConsole().sendMessage(longsNeeded + "");
DataTypeIO.writeVarInt(dataOut, longsNeeded);
for (int u = 0; u < longsNeeded; u++) {
if (u < formattedLongs.length) {
dataOut.writeLong(formattedLongs[u]);
} else {
dataOut.writeLong(0);
}
//Limbo.getInstance().getConsole().sendMessage(Arrays.toString(section.getBlockStates()));
}
} else {
try {
dataOut.writeByte(15);
section.getBlockStates();
int longsNeeded = 1024;
List<Integer> list = new LinkedList<>();
for (int y = 0; y < 16; y++) {
for (int z = 0; z < 16; z++) {
for (int x = 0; x < 16; x++) {
list.add(GeneratedBlockDataMappings.getGlobalPaletteIDFromState(section.getBlockStateAt(x, y, z)));
}
}
}
List<Long> globalLongs = new ArrayList<>();
long currentLong = 0;
int pos = 0;
int u = 0;
while (pos < longsNeeded) {
if (u == 3) {
globalLongs.add(currentLong);
currentLong = 0;
u = 0;
pos++;
} else {
u++;
}
int id = list.isEmpty() ? 0 : list.remove(0);
currentLong = currentLong << 15;
currentLong |= (long) id;
}
DataTypeIO.writeVarInt(dataOut, longsNeeded);
for (int j = 0; j < longsNeeded; j++) {
if (j < globalLongs.size()) {
dataOut.writeLong(globalLongs.get(j));
} else {
dataOut.writeLong(0);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
byte[] data = dataBuffer.toByteArray();

View File

@ -0,0 +1,31 @@
package com.loohp.limbo.Utils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.List;
public class BitsUtils {
public static BitSet shiftAfter(BitSet bitset, int from, int shift) {
BitSet subset = bitset.get(from, bitset.length());
for (int i = 0; i < subset.length(); i++) {
bitset.set(from + shift + i, subset.get(i));
}
if (shift > 0) {
for (int i = 0; i < shift; i++) {
bitset.set(from + i, false);
}
}
return bitset;
}
public static String toLongString(BitSet bitset) {
List<String> list = new ArrayList<>();
for (long l : bitset.toLongArray()) {
list.add(Long.toBinaryString(l));
}
return Arrays.toString(list.toArray());
}
}

View File

@ -16,8 +16,8 @@ public class Schematic {
public static World toWorld(String name, Environment environment, CompoundTag nbt) {
short width = nbt.getShort("Width");
short length = nbt.getShort("Length");
short height = nbt.getShort("Height");
byte[] blocks = nbt.getByteArray("BlockData");
//short height = nbt.getShort("Height");
byte[] blockdata = nbt.getByteArray("BlockData");
CompoundTag palette = nbt.getCompoundTag("Palette");
ListTag<CompoundTag> blockEntities = nbt.getListTag("BlockEntities").asTypedList(CompoundTag.class);
Map<Integer, String> mapping = new HashMap<>();
@ -26,11 +26,32 @@ public class Schematic {
}
World world = new World(name, width, length, environment);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
for (int z = 0; z < length; z++) {
int blockIndex = x + z * width + y * width * length;
world.setBlock(x, y, z, mapping.get(blocks[blockIndex] < 0 ? blocks[blockIndex] + 256 : blocks[blockIndex]));
int index = 0;
int i = 0;
int value = 0;
int varint_length = 0;
while (i < blockdata.length) {
value = 0;
varint_length = 0;
while (true) {
value |= (blockdata[i] & 127) << (varint_length++ * 7);
if (varint_length > 5) {
throw new RuntimeException("VarInt too big (probably corrupted data)");
}
if ((blockdata[i] & 128) != 128) {
i++;
break;
}
i++;
}
// index = (y * length + z) * width + x
int y = index / (width * length);
int z = (index % (width * length)) / width;
int x = (index % (width * length)) % width;
world.setBlock(x, y, z, mapping.get(value));
Chunk chunk = world.getChunkAtWorldPos(x, z);
Iterator<CompoundTag> itr = blockEntities.iterator();
@ -46,8 +67,8 @@ public class Schematic {
break;
}
}
}
}
index++;
}
for (Chunk[] chunkarray : world.getChunks()) {