1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
use chashmap::{CHashMap, ReadGuard, WriteGuard};
use fastanvil::{Block, Chunk, CurrentJavaChunk, Region, RegionFileLoader, RegionLoader};
use log::{debug, info};
use std::{fs::File, path::PathBuf};
pub struct Dimension {
loader: RegionFileLoader,
regions: CHashMap<(isize, isize), Option<Region<File>>>,
chunks: CHashMap<(isize, isize), Option<CurrentJavaChunk>>,
}
impl Dimension {
pub fn new(path: PathBuf) -> Self {
let loader = fastanvil::RegionFileLoader::new(path);
Self {
loader,
regions: Default::default(),
chunks: Default::default(),
}
}
pub fn region(
&self,
rx: isize,
rz: isize,
) -> WriteGuard<'_, (isize, isize), Option<Region<File>>> {
if self.regions.contains_key(&(rx, rz)) {
self.regions.get_mut(&(rx, rz)).unwrap()
} else {
info!("loading region {:?}", (rx, rz));
self.regions.insert(
(rx, rz),
self.loader
.region(fastanvil::RCoord(rx), fastanvil::RCoord(rz)),
);
self.region(rx, rz)
}
}
pub fn chunk(
&self,
cx: isize,
cz: isize,
) -> ReadGuard<'_, (isize, isize), Option<CurrentJavaChunk>> {
if self.chunks.contains_key(&(cx, cz)) {
self.chunks.get(&(cx, cz)).unwrap()
} else {
let mut guard = self.region(cx / 32, cz / 32);
debug!("loading chunk {:?}", (cx, cz));
let chunk: Option<CurrentJavaChunk> = guard
.as_mut()
.map(|c| {
c.read_chunk(cx.rem_euclid(32) as usize, cz.rem_euclid(32) as usize)
.ok()
})
.flatten()
.flatten()
.map(|chunk| fastnbt::from_bytes(&chunk).ok())
.flatten();
self.chunks.insert((cx, cz), chunk);
self.chunk(cx, cz)
}
}
pub fn block(&self, x: isize, y: isize, z: isize) -> Option<Block> {
self.chunk(x / 16, z / 16)
.as_ref()?
.block((x % 16).abs() as usize, y, (z % 16).abs() as usize)
.map(|e| e.to_owned())
}
}
|