public static void HandleChunkData(IPacket _packet, MultiplayerClient client) { var packet = (ChunkDataPacket)_packet; var data = ZlibStream.UncompressBuffer(packet.CompressedData); IChunk chunk; var adjustedCoords = client.World.World.FindBlockPosition( new Coordinates3D(packet.X, packet.Y, packet.Z), out chunk); if (packet.Width == Chunk.Width && packet.Height == Chunk.Height && packet.Depth == Chunk.Depth) // Fast path { // Block IDs Buffer.BlockCopy(data, 0, chunk.Blocks, 0, chunk.Blocks.Length); // Block metadata Buffer.BlockCopy(data, chunk.Blocks.Length, chunk.Metadata.Data, 0, chunk.Metadata.Data.Length); // Block light Buffer.BlockCopy(data, chunk.Blocks.Length + chunk.Metadata.Data.Length, chunk.BlockLight.Data, 0, chunk.BlockLight.Data.Length); // Sky light Buffer.BlockCopy(data, chunk.Blocks.Length + chunk.Metadata.Data.Length + chunk.BlockLight.Data.Length, chunk.SkyLight.Data, 0, chunk.SkyLight.Data.Length); } else // Slow path { int x = adjustedCoords.X, y = adjustedCoords.Y, z = adjustedCoords.Z; int fullLength = packet.Width * packet.Height * packet.Depth; // Length of full sized byte section int nibbleLength = fullLength / 2; // Length of nibble sections for (int i = 0; i < fullLength; i++) // Iterate through block IDs { chunk.SetBlockID(new Coordinates3D(x, y, z), data[i]); y++; if (y >= packet.Height) { y = 0; z++; if (z >= packet.Depth) { z = 0; x++; if (x >= packet.Width) { x = 0; } } } } x = adjustedCoords.X; y = adjustedCoords.Y; z = adjustedCoords.Z; for (int i = fullLength; i < nibbleLength; i++) // Iterate through metadata { byte m = data[i]; chunk.SetMetadata(new Coordinates3D(x, y, z), (byte)(m & 0xF)); chunk.SetMetadata(new Coordinates3D(x, y + 1, z), (byte)(m & 0xF0 << 8)); y += 2; if (y >= packet.Height) { y = 0; z++; if (z >= packet.Depth) { z = 0; x++; if (x >= packet.Width) { x = 0; } } } } // TODO: Lighting } chunk.UpdateHeightMap(); client.OnChunkLoaded(new ChunkEventArgs(new ReadOnlyChunk(chunk))); }
public static void HandleChunkData(IPacket _packet, MultiplayerClient client) { var packet = (ChunkDataPacket)_packet; var coords = new Coordinates3D(packet.X, packet.Y, packet.Z); var data = ZlibStream.UncompressBuffer(packet.CompressedData); IChunk chunk; var adjustedCoords = client.World.World.FindBlockPosition(coords, out chunk); if (packet.Width == Chunk.Width && packet.Height == Chunk.Height && packet.Depth == Chunk.Depth) // Fast path { // Block IDs Buffer.BlockCopy(data, 0, chunk.Data, 0, chunk.Data.Length); // Block metadata Buffer.BlockCopy(data, chunk.Data.Length, chunk.Metadata.Data, 0, chunk.Metadata.Data.Length); // Block light Buffer.BlockCopy(data, chunk.Data.Length + chunk.Metadata.Data.Length, chunk.BlockLight.Data, 0, chunk.BlockLight.Data.Length); // Sky light Buffer.BlockCopy(data, chunk.Data.Length + chunk.Metadata.Data.Length + chunk.BlockLight.Data.Length, chunk.SkyLight.Data, 0, chunk.SkyLight.Data.Length); } else // Slow path { int x = adjustedCoords.X, y = adjustedCoords.Y, z = adjustedCoords.Z; int fullLength = packet.Width * packet.Height * packet.Depth; // Length of full sized byte section int nibbleLength = fullLength / 2; // Length of nibble sections for (int i = 0; i < fullLength; i++) // Iterate through block IDs { chunk.SetBlockID(new Coordinates3D(x, y, z), data[i]); y++; if (y >= packet.Height) { y = 0; z++; if (z >= packet.Depth) { z = 0; x++; if (x >= packet.Width) { x = 0; } } } } x = adjustedCoords.X; y = adjustedCoords.Y; z = adjustedCoords.Z; for (int i = fullLength; i < nibbleLength; i++) // Iterate through metadata { byte m = data[i]; chunk.SetMetadata(new Coordinates3D(x, y, z), (byte)(m & 0xF)); chunk.SetMetadata(new Coordinates3D(x, y + 1, z), (byte)(m & 0xF0 << 8)); y += 2; if (y >= packet.Height) { y = 0; z++; if (z >= packet.Depth) { z = 0; x++; if (x >= packet.Width) { x = 0; } } } } // TODO: Lighting } chunk.UpdateHeightMap(); chunk.TerrainPopulated = true; client.OnChunkLoaded(new ChunkEventArgs(new ReadOnlyChunk(chunk))); }