Esempio n. 1
0
        /// <summary>
        /// Retrieves the requested chunk from the region, or
        /// generates it if a world generator is provided.
        /// </summary>
        /// <param name="position">The position of the requested local chunk coordinates.</param>
        public IChunk GetChunk(Coordinates2D position)
        {
            // TODO: This could use some refactoring
            lock (Chunks)
            {
                if (!Chunks.ContainsKey(position))
                {
                    if (regionFile != null)
                    {
                        // Search the stream for that region
                        lock (regionFile)
                        {
                            var chunkData = GetChunkFromTable(position);
                            if (chunkData == null)
                            {
                                if (World.ChunkProvider == null)
                                {
                                    throw new ArgumentException("The requested chunk is not loaded.", "position");
                                }
                                GenerateChunk(position);
                                return(Chunks[position]);
                            }
                            regionFile.Seek(chunkData.Item1, SeekOrigin.Begin);
                            /*int length = */ new MinecraftStream(regionFile).ReadInt32(); // TODO: Avoid making new objects here, and in the WriteInt32
                            int compressionMode = regionFile.ReadByte();
                            switch (compressionMode)
                            {
                            case 1:     // gzip
                                throw new NotImplementedException("gzipped chunks are not implemented");

                            case 2:     // zlib
                                var nbt = new NbtFile();
                                nbt.LoadFromStream(regionFile, NbtCompression.ZLib, null);
                                var chunk = Chunk.FromNbt(nbt);
                                Chunks.Add(position, chunk);
                                break;

                            default:
                                throw new InvalidDataException("Invalid compression scheme provided by region file.");
                            }
                        }
                    }
                    else if (World.ChunkProvider == null)
                    {
                        throw new ArgumentException("The requested chunk is not loaded.", "position");
                    }
                    else
                    {
                        GenerateChunk(position);
                    }
                }
                return(Chunks[position]);
            }
        }