pub struct Region<S> { /* private fields */ }
Expand description
A Minecraft Region, allowing reading and writing of chunk data to a stream (eg a
File). This does not concern itself with manipulating chunk data, users are
expected to use fastnbt
or other deserialization method to manipulate the
chunk data itself.
If using a stream with Read
and Seek
you can only read chunk data. If
you want to be able to modify chunk data you also need a stream implementing
Write
. File
implements these, as does Cursor<Vec<u8>>
.
Implementations§
source§impl<S> Region<S>
impl<S> Region<S>
sourcepub fn from_stream(stream: S) -> Result<Self>
pub fn from_stream(stream: S) -> Result<Self>
Load a region from an existing stream, meaning something that implements
Read
and Seek
. This will assume a seek of zero is the start of
the region. This does not load all region data into memory immediately.
Chunks are read from the underlying stream when needed.
The most obvious ‘stream’ is a file:
let file = File::open("foo.mca")?;
let mut region = Region::from_stream(file)?;
// manipulate region
If you have raw data, this can also be used by wrapping it in a Cursor
:
let data: Vec<u8> = todo!("get data");
let data = Cursor::new(data);
let mut region = Region::from_stream(data)?;
// manipulate region
sourcepub fn read_chunk(&mut self, x: usize, z: usize) -> Result<Option<Vec<u8>>>
pub fn read_chunk(&mut self, x: usize, z: usize) -> Result<Option<Vec<u8>>>
Read the chunk located at the chunk coordindates x
, z
. The chunk
data returned is uncompressed NBT. Ok(None)
means that the chunk does
not exist, which will be the case if that chunk has not generated. If
x
or z
are outside 0..32
, Error::InvalidOffset
is returned.
use fastanvil::CurrentJavaChunk;
let file = File::open("foo.mca")?;
let mut region = Region::from_stream(file)?;
// Get a chunk. May error for IO reasons, and may not be present, hence Result<Option>.
let chunk = region.read_chunk(1,2).unwrap().unwrap();
// Parse chunk data into a CurrentJavaChunk.
let chunk: CurrentJavaChunk = fastnbt::from_bytes(&chunk).unwrap();
sourcepub fn into_inner(self) -> Result<S>
pub fn into_inner(self) -> Result<S>
Return the inner buffer used. The buffer is rewound to the logical end of the region data. If the region does not contain any chunk the position is at the end of the header. If saving to disk you should truncate the file to this position to ensure the file is saved with the correct padding bytes.
§Examples
This can be used to truncate a region file after manipulating it to save disk space.
let file = File::open("foo.mca")?;
let mut region = Region::from_stream(file)?;
// manipulate region
// recover the file object in order to make sure the file is the correct
// size on disk. The seek head is left at the exact end of the region data,
// including required padding.
let mut file = region.into_inner()?;
let len = file.stream_position()?;
file.set_len(len)?;
sourcepub fn iter(&mut self) -> RegionIter<'_, S> ⓘ
pub fn iter(&mut self) -> RegionIter<'_, S> ⓘ
Create an iterator for the chunks of the region. Chunks not present in the file are skipped.
source§impl<S> Region<S>
impl<S> Region<S>
sourcepub fn new(stream: S) -> Result<Self>
pub fn new(stream: S) -> Result<Self>
Create an new empty region. The provided stream will be overwritten, and will assume a seek to 0 is the start of the region. The stream needs read, write, and seek, like a file provides.
sourcepub fn write_chunk(
&mut self,
x: usize,
z: usize,
uncompressed_chunk: &[u8]
) -> Result<()>
pub fn write_chunk( &mut self, x: usize, z: usize, uncompressed_chunk: &[u8] ) -> Result<()>
Write the given uncompressed NBT chunk data to the chunk coordinates x, z.
The chunk data will be compressed with zlib by default. You can use
write_compressed_chunk if you want more control. If x
or z
are
outside 0..32
, Error::InvalidOffset
is returned.
sourcepub fn write_compressed_chunk(
&mut self,
x: usize,
z: usize,
scheme: CompressionScheme,
compressed_chunk: &[u8]
) -> Result<()>
pub fn write_compressed_chunk( &mut self, x: usize, z: usize, scheme: CompressionScheme, compressed_chunk: &[u8] ) -> Result<()>
Low level method to write the given compressed chunk data to the stream.
It is the callers responsibility to make sure the compression scheme
matches the compression used. If x
or z
are outside 0..32
,
Error::InvalidOffset
is returned.
sourcepub fn remove_chunk(&mut self, x: usize, z: usize) -> Result<()>
pub fn remove_chunk(&mut self, x: usize, z: usize) -> Result<()>
Remove the chunk at the chunk location with the coordinates x and z.
If you are stripping chunks from regions to save disk space, you should instead iterate through the chunks of the region, and write the desired chunks to a new region, and write that to disk. This will ensure chunks are compactly stored with no gaps.