Albatross/src/restore.rs

80 lines
2.2 KiB
Rust

use crate::backup::uncompress_backup;
use crate::chunk_coordinate::ChunkCoordinate;
use crate::error::Result;
use anvil_region::AnvilChunkProvider;
use std::fs::remove_dir_all;
use std::path::PathBuf;
/// Struct for manipulating a world from a backup
struct RestoreAccess {
/// Chunk source
src_path: PathBuf,
/// Chunk destination
dest_path: PathBuf,
}
impl RestoreAccess {
/// Create new RestoreAccess
pub fn new(world_name: &str, src_path: &PathBuf, dest_path: &PathBuf) -> Result<Self> {
let src_path = uncompress_backup(src_path)?.join(world_name).join("region");
let dest_path = dest_path.join(world_name).join("region");
Ok(RestoreAccess {
src_path,
dest_path,
})
}
/// Copy chunk from source to desination
pub fn copy_chunk(&self, x: i32, z: i32) {
let src_provider = AnvilChunkProvider::new(self.src_path.to_str().unwrap());
let dest_provider = AnvilChunkProvider::new(self.dest_path.to_str().unwrap());
let chunk = src_provider.load_chunk(x, z).expect("Unable to load chunk");
dest_provider
.save_chunk(x, z, chunk)
.expect("Unable to save chunk");
}
/// Cleanup process
pub fn cleanup(self) -> Result<()> {
Ok(remove_dir_all("tmp")?)
}
}
/// Restore a range of chunks from a backup
pub fn restore_range_from_backup(
world_name: &str,
lower: ChunkCoordinate,
upper: ChunkCoordinate,
backup_path: &PathBuf,
minecraft_dir: &PathBuf,
) -> Result<u64> {
let chunk_access = RestoreAccess::new(world_name, backup_path, minecraft_dir)?;
let mut count = 0;
for x in lower.x..=upper.x {
for z in lower.z..=upper.z {
chunk_access.copy_chunk(x, z);
count += 1;
}
}
chunk_access.cleanup()?;
Ok(count)
}
/// Restore a single chunk from a backup
pub fn restore_chunk_from_backup(
world_name: &str,
chunk: ChunkCoordinate,
backup_path: &PathBuf,
minecraft_dir: &PathBuf,
) -> Result<()> {
let chunk_access = RestoreAccess::new(world_name, backup_path, minecraft_dir)?;
chunk_access.copy_chunk(chunk.x, chunk.z);
chunk_access.cleanup()?;
Ok(())
}