Beispiel #1
0
        public void Load()
        {
            lock (_chunkCache)
            {
                string filePath = FilePath;
                if (!File.Exists(filePath))
                {
                    // Welp, nothing to load.
                    IsLoaded = true;
                    return;
                }

                using (FileStream regionFile = File.OpenRead(filePath))
                {
                    AnvilRegionHeader header = LoadRegionHeader(regionFile);
                    RegionHeader = header;

                    //File.WriteAllLines(FilePath + ".header", header.GetAllChunkData().Select(h => string.Format("{0,-10}\t=>\t{1,-10}\t{2,-10}\t{3,-10}", h.ChunkCoordinates, h.LocationOffset, h.SectorCount, h.UpdatedTimestamp)).ToArray());

                    foreach (AnvilRegionHeaderChunkData data in header.GetAllChunkData())
                    {
                        // Attempt to load NbtFile for each chunk.
                        if (!data.ChunkExists)
                        {
                            continue;
                        }

                        regionFile.Seek(data.LocationOffset, SeekOrigin.Begin);
                        var lengthBuffer = new byte[4];
                        regionFile.Read(lengthBuffer, 0, 4);
                        Array.Reverse(lengthBuffer);

                        int nbtDataLength = BitConverter.ToInt32(lengthBuffer, 0) - 1;


                        int            compressionMode = regionFile.ReadByte();
                        NbtCompression compression     = compressionMode == 2
                                                                                                                ? NbtCompression.ZLib
                                                                                                                : (compressionMode == 1 ? NbtCompression.GZip : NbtCompression.None);

                        var nbtDataBuffer = new byte[nbtDataLength];
                        regionFile.Read(nbtDataBuffer, 0, nbtDataLength);

                        //Debug.WriteLine($"({data.ChunkCoordinates.X}, {data.ChunkCoordinates.Z}) Offset: {data.LocationOffset}, Header Length: {data.SectorCount}, NbtDataLength: {nbtDataLength}");

                        var nbtFile = new NbtFile();
                        nbtFile.LoadFromBuffer(nbtDataBuffer, 0, nbtDataLength, compression);

                        //File.WriteAllText(Path.Combine(Provider.BasePath, "region", FileName + $"_{data.ChunkCoordinates.X}-{data.ChunkCoordinates.Z}.txt"), nbtFile.ToString());

                        //Debug.WriteLine(
                        //	$"Region: ({X},{Z}), Chunk({data.ChunkCoordinates.X}, {data.ChunkCoordinates.Z}): NbtDataLength: {nbtDataLength}");

                        _containingChunks.TryAdd(data.ChunkCoordinates, nbtFile);
                    }
                }

                IsLoaded = true;
            }
        }
Beispiel #2
0
        private AnvilRegionHeader LoadRegionHeader(FileStream regionFile)
        {
            var header = new AnvilRegionHeader();

            var completeUpdatedTimeBuffer = new byte[4096];

            regionFile.Seek(4096, SeekOrigin.Begin);
            regionFile.Read(completeUpdatedTimeBuffer, 0, 4096);

            regionFile.Seek(0, SeekOrigin.Begin);

            //int read = 0;
            int baseX = X * Width;
            int baseZ = Z * Width;

            // Load Chunk Locations
            for (var zi = 0; zi < Width; zi++)
            {
                for (var xi = 0; xi < Width; xi++)
                {
                    int x = baseX + xi;
                    int z = baseZ + zi;

                    int index = (xi + zi * Width) * 4;

                    var coords = new ChunkCoordinates(x, z);

                    var chunkLocationBuffer = new byte[4];
                    regionFile.Read(chunkLocationBuffer, 0, 3);
                    Array.Reverse(chunkLocationBuffer);
                    int offset = BitConverter.ToInt32(chunkLocationBuffer, 0) << 4;
                    int length = regionFile.ReadByte() << 12;

                    var updatedTimeBuffer = new byte[4];
                    Array.Copy(completeUpdatedTimeBuffer, index, updatedTimeBuffer, 0, 4);

                    Array.Reverse(updatedTimeBuffer);
                    int updatedTime = BitConverter.ToInt32(updatedTimeBuffer, 0);

                    //Debug.WriteLine($"Header ({x},{z}) Offset: {offset}	Length: {length} UpdatedTime: {updatedTime}");
                    var chunkHeader = new AnvilRegionHeaderChunkData(coords, offset, length, updatedTime);
                    header.SetChunkData(coords, chunkHeader);
                }
            }
            return(header);
        }