示例#1
0
        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)));
        }
示例#2
0
        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)));
        }