diff --git a/pom.xml b/pom.xml
index e0c8a00..f7bdbff 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
com.loohp
Limbo
- 0.3.3-ALPHA
+ 0.3.4-ALPHA
src
diff --git a/src/com/loohp/limbo/Server/Packets/PacketPlayOutMapChunk.java b/src/com/loohp/limbo/Server/Packets/PacketPlayOutMapChunk.java
index 4aadf0a..dbee890 100644
--- a/src/com/loohp/limbo/Server/Packets/PacketPlayOutMapChunk.java
+++ b/src/com/loohp/limbo/Server/Packets/PacketPlayOutMapChunk.java
@@ -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,25 +119,79 @@ 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 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));
}
+
+ 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);
+ }
+
+ 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 {
- dataOut.writeByte(14);
- }
-
- DataTypeIO.writeVarInt(dataOut, section.getBlockStates().length);
- for (int u = 0; u < section.getBlockStates().length; u++) {
- dataOut.writeLong(section.getBlockStates()[u]);
- //Limbo.getInstance().getConsole().sendMessage(Arrays.toString(section.getBlockStates()));
+ try {
+ dataOut.writeByte(15);
+ section.getBlockStates();
+ int longsNeeded = 1024;
+ List 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 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();
+ }
}
}
}
diff --git a/src/com/loohp/limbo/Utils/BitsUtils.java b/src/com/loohp/limbo/Utils/BitsUtils.java
new file mode 100644
index 0000000..b1291e5
--- /dev/null
+++ b/src/com/loohp/limbo/Utils/BitsUtils.java
@@ -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 list = new ArrayList<>();
+ for (long l : bitset.toLongArray()) {
+ list.add(Long.toBinaryString(l));
+ }
+ return Arrays.toString(list.toArray());
+ }
+
+}
diff --git a/src/com/loohp/limbo/World/Schematic.java b/src/com/loohp/limbo/World/Schematic.java
index f0c7908..17e1d1f 100644
--- a/src/com/loohp/limbo/World/Schematic.java
+++ b/src/com/loohp/limbo/World/Schematic.java
@@ -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 blockEntities = nbt.getListTag("BlockEntities").asTypedList(CompoundTag.class);
Map mapping = new HashMap<>();
@@ -26,29 +26,50 @@ 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]));
- Chunk chunk = world.getChunkAtWorldPos(x, z);
-
- Iterator itr = blockEntities.iterator();
- while (itr.hasNext()) {
- CompoundTag tag = itr.next();
- int[] pos = tag.getIntArray("Pos");
-
- if (pos[0] == x && pos[1] == y && pos[2] == z) {
- ListTag newTag = chunk.getTileEntities();
- newTag.add(SchematicConvertionUtils.toTileEntityTag(tag));
- chunk.setTileEntities(newTag);
- itr.remove();
- break;
- }
- }
+
+ 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 itr = blockEntities.iterator();
+ while (itr.hasNext()) {
+ CompoundTag tag = itr.next();
+ int[] pos = tag.getIntArray("Pos");
+
+ if (pos[0] == x && pos[1] == y && pos[2] == z) {
+ ListTag newTag = chunk.getTileEntities();
+ newTag.add(SchematicConvertionUtils.toTileEntityTag(tag));
+ chunk.setTileEntities(newTag);
+ itr.remove();
+ break;
}
}
- }
+
+ index++;
+ }
for (Chunk[] chunkarray : world.getChunks()) {
for (Chunk chunk : chunkarray) {