Search in sources :

Example 1 with ChunkDataStream

use of org.spongepowered.api.world.storage.ChunkDataStream in project LanternServer by LanternPowered.

the class AnvilChunkIOService method getGeneratedChunks.

@Override
public ChunkDataStream getGeneratedChunks() {
    return new ChunkDataStream() {

        // All the region files
        private Path[] paths;

        // The current region file that we opened
        @Nullable
        private RegionFile region;

        // The coordinates of the chunk inside the region
        private int chunkX;

        private int chunkZ;

        // The next index of the chunk in the region file
        private int regionChunkIndex;

        // The next index that we are in the file array
        private int regionFileIndex;

        // Whether the current fields are cached
        private boolean cached;

        // Done, no new chunks can be found
        private boolean done;

        {
            // Use the reset to initialize
            this.reset();
        }

        @Override
        public DataContainer next() {
            if (!this.hasNext()) {
                throw new NoSuchElementException();
            }
            try {
                final DataInputStream is = this.region.getChunkDataInputStream(this.chunkX, this.chunkZ);
                final DataContainer data;
                try (NbtDataContainerInputStream nbt = new NbtDataContainerInputStream(is)) {
                    data = nbt.read();
                }
                this.cached = false;
                return data;
            } catch (IOException e) {
                // This shouldn't happen
                throw new IllegalStateException(e);
            }
        }

        @Override
        public boolean hasNext() {
            // Fast fail
            if (this.done) {
                return false;
            }
            // Use the cached index if set
            if (this.cached) {
                return true;
            }
            // Try first to search for more chunks in the current region
            while (true) {
                if (this.region != null) {
                    while (++this.regionChunkIndex < REGION_AREA) {
                        this.chunkX = this.regionChunkIndex / REGION_SIZE;
                        this.chunkZ = this.regionChunkIndex % REGION_SIZE;
                        if (this.region.hasChunk(this.chunkX, this.chunkZ)) {
                            this.cached = true;
                            return true;
                        }
                    }
                }
                // There no chunk available in the current region,
                // reset the chunk index for the next one
                this.regionChunkIndex = -1;
                // try the next region
                if (++this.regionFileIndex >= this.paths.length) {
                    this.region = null;
                    this.done = true;
                    return false;
                }
                final Path nextRegionFile = this.paths[this.regionFileIndex];
                if (Files.exists(nextRegionFile)) {
                    Matcher matcher = cache.getFilePattern().matcher(nextRegionFile.getFileName().toString());
                    int regionX = Integer.parseInt(matcher.group(0));
                    int regionZ = Integer.parseInt(matcher.group(1));
                    try {
                        this.region = cache.getRegionFile(regionX, regionZ);
                    } catch (IOException e) {
                        logger.error("Failed to read the region file ({};{}) in the world folder {}", regionX, regionZ, baseDir.getFileName().toString(), e);
                        this.region = null;
                    }
                } else {
                    this.region = null;
                }
            }
        }

        @Override
        public int available() {
            // the region files
            throw new UnsupportedOperationException();
        }

        @Override
        public void reset() {
            this.paths = cache.getRegionFiles();
            this.regionFileIndex = -1;
            this.regionChunkIndex = -1;
            this.region = null;
            this.cached = false;
            this.done = false;
        }
    };
}
Also used : Path(java.nio.file.Path) DataContainer(org.spongepowered.api.data.DataContainer) ChunkDataStream(org.spongepowered.api.world.storage.ChunkDataStream) NbtDataContainerInputStream(org.lanternpowered.server.data.persistence.nbt.NbtDataContainerInputStream) Matcher(java.util.regex.Matcher) IOException(java.io.IOException) DataInputStream(java.io.DataInputStream) NoSuchElementException(java.util.NoSuchElementException)

Aggregations

DataInputStream (java.io.DataInputStream)1 IOException (java.io.IOException)1 Path (java.nio.file.Path)1 NoSuchElementException (java.util.NoSuchElementException)1 Matcher (java.util.regex.Matcher)1 NbtDataContainerInputStream (org.lanternpowered.server.data.persistence.nbt.NbtDataContainerInputStream)1 DataContainer (org.spongepowered.api.data.DataContainer)1 ChunkDataStream (org.spongepowered.api.world.storage.ChunkDataStream)1