mirror of
https://github.com/Chaoscaot/schemsearch.git
synced 2025-12-02 07:27:05 +01:00
Compare commits
4 Commits
add-invali
...
cosin-dist
| Author | SHA1 | Date | |
|---|---|---|---|
| d39e876885 | |||
| 1e8d5d6311 | |||
| 2a584e878f | |||
| 33f5fe03fe |
@@ -7,7 +7,9 @@ use schemsearch_files::SpongeSchematic;
|
|||||||
const NBT_BLOCKS: &str = include_str!("blocks.txt");
|
const NBT_BLOCKS: &str = include_str!("blocks.txt");
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref NBT_BLOCKS_SET: HashSet<String> = NBT_BLOCKS.lines().map(ToOwned::to_owned).collect();
|
static ref NBT_BLOCKS_SET: HashSet<String> = {
|
||||||
|
NBT_BLOCKS.lines().map(|x| format!("minecraft:{}", x)).collect()
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_invalid_nbt(schem: SpongeSchematic) -> bool {
|
pub fn has_invalid_nbt(schem: SpongeSchematic) -> bool {
|
||||||
@@ -15,13 +17,94 @@ pub fn has_invalid_nbt(schem: SpongeSchematic) -> bool {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let nbt_blocks = schem.palette.iter().filter(|(k, _)| NBT_BLOCKS_SET.contains(*k)).map(|(_, v)| *v).collect::<HashSet<i32>>();
|
let nbt_blocks = schem.palette.iter().filter(|(k, _)| NBT_BLOCKS_SET.contains(k.to_owned())).map(|(_, v)| *v).collect::<HashSet<i32>>();
|
||||||
|
|
||||||
for block_entity in schem.block_data.iter() {
|
for (i, block_entity) in schem.block_data.iter().enumerate() {
|
||||||
if nbt_blocks.contains(block_entity) {
|
if nbt_blocks.contains(&*block_entity) {
|
||||||
|
// i = x + z * Width + y * Width * Length
|
||||||
|
let x = i % schem.width as usize;
|
||||||
|
let z = (i / schem.width as usize) % schem.length as usize;
|
||||||
|
let y = i / (schem.width as usize * schem.length as usize);
|
||||||
|
if schem.block_entities.iter().any(|e| !e.pos.eq(&[x as i32, y as i32, z as i32])) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use nbt::CompoundTag;
|
||||||
|
use schemsearch_files::{BlockEntity, SpongeSchematic};
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_has_invalid_nbt() {
|
||||||
|
let schem = SpongeSchematic {
|
||||||
|
data_version: 1,
|
||||||
|
metadata: CompoundTag::new(),
|
||||||
|
width: 0,
|
||||||
|
height: 0,
|
||||||
|
length: 0,
|
||||||
|
offset: [0, 0, 0],
|
||||||
|
palette_max: 1,
|
||||||
|
palette: vec![("minecraft:chest".to_owned(), 1)].into_iter().collect(),
|
||||||
|
block_data: vec![1],
|
||||||
|
block_entities: vec![],
|
||||||
|
entities: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(has_invalid_nbt(schem), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_has_invalid_nbt_2() {
|
||||||
|
let schem = SpongeSchematic {
|
||||||
|
data_version: 1,
|
||||||
|
metadata: CompoundTag::new(),
|
||||||
|
width: 1,
|
||||||
|
height: 1,
|
||||||
|
length: 1,
|
||||||
|
offset: [0, 0, 0],
|
||||||
|
palette_max: 1,
|
||||||
|
palette: vec![("minecraft:chest".to_owned(), 1)].into_iter().collect(),
|
||||||
|
block_data: vec![1],
|
||||||
|
block_entities: vec![
|
||||||
|
BlockEntity {
|
||||||
|
id: "minecraft:chest".to_owned(),
|
||||||
|
pos: [0, 0, 0],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
entities: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(has_invalid_nbt(schem), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_has_invalid_nbt_3() {
|
||||||
|
let schem = SpongeSchematic {
|
||||||
|
data_version: 1,
|
||||||
|
metadata: CompoundTag::new(),
|
||||||
|
width: 2,
|
||||||
|
height: 1,
|
||||||
|
length: 1,
|
||||||
|
offset: [0, 0, 0],
|
||||||
|
palette_max: 1,
|
||||||
|
palette: vec![("minecraft:chest".to_owned(), 1), ("minecraft:stone".to_owned(), 2)].into_iter().collect(),
|
||||||
|
block_data: vec![1, 2],
|
||||||
|
block_entities: vec![
|
||||||
|
BlockEntity {
|
||||||
|
id: "minecraft:chest".to_owned(),
|
||||||
|
pos: [1, 0, 0],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
entities: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(has_invalid_nbt(schem), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,40 +43,34 @@ pub fn search(
|
|||||||
let schem_height = schem.height as usize;
|
let schem_height = schem.height as usize;
|
||||||
let schem_length = schem.length as usize;
|
let schem_length = schem.length as usize;
|
||||||
|
|
||||||
let skip_amount = ceil((pattern_blocks * (1.0 - search_behavior.threshold)) as f64, 0) as i32;
|
let pattern_vec_length = pattern_schem.block_data.iter().map(|x| x * x).sum::<i32>();
|
||||||
|
|
||||||
for y in 0..=schem_height - pattern_height {
|
for y in 0..=schem_height - pattern_height {
|
||||||
for z in 0..=schem_length - pattern_length {
|
for z in 0..=schem_length - pattern_length {
|
||||||
for x in 0..=schem_width - pattern_width {
|
for x in 0..=schem_width - pattern_width {
|
||||||
let mut not_matching = 0;
|
let mut dot_p: i32 = 0;
|
||||||
'outer:
|
let mut schem_vec_length = 0;
|
||||||
|
|
||||||
for j in 0..pattern_height {
|
for j in 0..pattern_height {
|
||||||
for k in 0..pattern_length {
|
for k in 0..pattern_length {
|
||||||
'inner:
|
|
||||||
for i in 0..pattern_width {
|
for i in 0..pattern_width {
|
||||||
let index = (x + i) + schem_width * ((z + k) + (y + j) * schem_length);
|
let index = (x + i) + schem_width * ((z + k) + (y + j) * schem_length);
|
||||||
let pattern_index = i + pattern_width * (k + j * pattern_length);
|
let pattern_index = i + pattern_width * (k + j * pattern_length);
|
||||||
let data = unsafe { *schem_data.add(index) };
|
|
||||||
let pattern_data = unsafe { *pattern_data.add(pattern_index) };
|
dot_p += unsafe { *pattern_data.add(pattern_index) * *schem_data.add(index) };
|
||||||
if (search_behavior.ignore_air && data != *air_id) || (search_behavior.air_as_any && pattern_data != *air_id) {
|
schem_vec_length += unsafe { *schem_data.add(index) * *schem_data.add(index) };
|
||||||
continue 'inner;
|
|
||||||
}
|
|
||||||
if data != pattern_data {
|
|
||||||
not_matching += 1;
|
|
||||||
if not_matching >= skip_amount {
|
|
||||||
break 'outer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if not_matching < skip_amount {
|
let sim = dot_p as f32 / ((pattern_vec_length as f32).sqrt() * (schem_vec_length as f32).sqrt());
|
||||||
|
|
||||||
|
if sim > search_behavior.threshold {
|
||||||
matches.push(Match {
|
matches.push(Match {
|
||||||
x: x as u16,
|
x: x as u16,
|
||||||
y: y as u16,
|
y: y as u16,
|
||||||
z: z as u16,
|
z: z as u16,
|
||||||
percent: (i_pattern_blocks - not_matching) as f32 / pattern_blocks,
|
percent: sim,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user