mirror of
https://git.ahines.net/joeyahines/Albatross.git
synced 2025-10-29 03:15:39 +00:00
+ Bump to rust 2024 + Cleaned up old code + Added more fail safes in case certain files are missing
90 lines
2.7 KiB
Rust
90 lines
2.7 KiB
Rust
use crate::backup::uncompress_backup;
|
|
use crate::chunk_coordinate::ChunkCoordinate;
|
|
use crate::error::Result;
|
|
use anvil_region::position::{RegionChunkPosition, RegionPosition};
|
|
use anvil_region::provider::{FolderRegionProvider, RegionProvider};
|
|
use std::fs::remove_dir_all;
|
|
use std::path::{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: &Path, dest_path: &Path) -> 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 destination
|
|
pub fn copy_chunk(&self, x: i32, z: i32) {
|
|
let region_position = RegionPosition::from_chunk_position(x, z);
|
|
let region_chunk_position = RegionChunkPosition::from_chunk_position(x, z);
|
|
|
|
let src_provider = FolderRegionProvider::new(self.src_path.to_str().unwrap());
|
|
let dest_provider = FolderRegionProvider::new(self.dest_path.to_str().unwrap());
|
|
|
|
let mut src_region = src_provider.get_region(region_position).unwrap();
|
|
let src_chunk_compound_tag = src_region
|
|
.read_chunk(region_chunk_position)
|
|
.expect("Unable to load chunk");
|
|
|
|
let mut dst_region = dest_provider.get_region(region_position).unwrap();
|
|
|
|
dst_region
|
|
.write_chunk(region_chunk_position, src_chunk_compound_tag)
|
|
.expect("Unable to write 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: &Path,
|
|
minecraft_dir: &Path,
|
|
) -> 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: &Path,
|
|
minecraft_dir: &Path,
|
|
) -> Result<()> {
|
|
let chunk_access = RestoreAccess::new(world_name, backup_path, minecraft_dir)?;
|
|
chunk_access.copy_chunk(chunk.x, chunk.z);
|
|
|
|
chunk_access.cleanup()?;
|
|
Ok(())
|
|
}
|