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;
}
};
}
Aggregations