public static ParsedChunkData dataToChunks(NetworkChunkData data, boolean checkForSky) { Chunk chunks[] = new Chunk[16]; int pos = 0; int expected = 0; boolean sky = false; ShortBuffer buf = ByteBuffer.wrap(data.getData()).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer(); // 0 = Calculate expected length and determine if the packet has skylight. // 1 = Create chunks from mask and get blocks. // 2 = Get block light. // 3 = Get sky light. for (int pass = 0; pass < 4; pass++) { for (int ind = 0; ind < 16; ind++) { if ((data.getMask() & 1 << ind) != 0) { if (pass == 0) { // Block length + Blocklight + Skylight length expected += (4096 * 2) + 2048 + 2048; } if (pass == 1) { chunks[ind] = new Chunk(sky || data.hasSkyLight()); ShortArray3d blocks = chunks[ind].getBlocks(); buf.position(pos / 2); buf.get(blocks.getData(), 0, blocks.getData().length); pos += blocks.getData().length * 2; } if (pass == 2) { NibbleArray3d blocklight = chunks[ind].getBlockLight(); System.arraycopy( data.getData(), pos, blocklight.getData(), 0, blocklight.getData().length); pos += blocklight.getData().length; } if (pass == 3 && (sky || data.hasSkyLight())) { NibbleArray3d skylight = chunks[ind].getSkyLight(); System.arraycopy(data.getData(), pos, skylight.getData(), 0, skylight.getData().length); pos += skylight.getData().length; } } } if (pass == 0) { // If we have more data than blocks and blocklight combined, there must be skylight data as // well. if (data.getData().length >= expected) { sky = checkForSky; } } } byte biomeData[] = null; if (data.isFullChunk()) { biomeData = new byte[256]; System.arraycopy(data.getData(), pos, biomeData, 0, biomeData.length); pos += biomeData.length; } return new ParsedChunkData(chunks, biomeData); }
public static NetworkChunkData chunksToData(ParsedChunkData chunks) { int chunkMask = 0; boolean fullChunk = chunks.getBiomes() != null; boolean sky = false; int length = fullChunk ? chunks.getBiomes().length : 0; byte[] data = null; int pos = 0; ShortBuffer buf = null; // 0 = Determine length and masks. // 1 = Add blocks. // 2 = Add block light. // 3 = Add sky light. for (int pass = 0; pass < 4; pass++) { for (int ind = 0; ind < chunks.getChunks().length; ++ind) { Chunk chunk = chunks.getChunks()[ind]; if (chunk != null && (!fullChunk || !chunk.isEmpty())) { if (pass == 0) { chunkMask |= 1 << ind; length += chunk.getBlocks().getData().length * 2; length += chunk.getBlockLight().getData().length; if (chunk.getSkyLight() != null) { length += chunk.getSkyLight().getData().length; } } if (pass == 1) { short blocks[] = chunk.getBlocks().getData(); buf.position(pos / 2); buf.put(blocks, 0, blocks.length); pos += blocks.length * 2; } if (pass == 2) { byte blocklight[] = chunk.getBlockLight().getData(); System.arraycopy(blocklight, 0, data, pos, blocklight.length); pos += blocklight.length; } if (pass == 3 && chunk.getSkyLight() != null) { byte skylight[] = chunk.getSkyLight().getData(); System.arraycopy(skylight, 0, data, pos, skylight.length); pos += skylight.length; sky = true; } } } if (pass == 0) { data = new byte[length]; buf = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer(); } } // Add biomes. if (fullChunk) { System.arraycopy(chunks.getBiomes(), 0, data, pos, chunks.getBiomes().length); pos += chunks.getBiomes().length; } return new NetworkChunkData(chunkMask, fullChunk, sky, data); }