1
0
Mirror von https://github.com/Chaoscaot/schemsearch synchronisiert 2024-09-29 03:01:10 +02:00

A very rude implementation for Tile-Entity Search

Dieser Commit ist enthalten in:
Chaoscaot 2023-03-21 14:21:30 +01:00
Ursprung b8d912881d
Commit d48910ecb4
5 geänderte Dateien mit 59 neuen und 39 gelöschten Zeilen

Datei anzeigen

@ -65,10 +65,17 @@ fn main() {
.action(ArgAction::SetTrue), .action(ArgAction::SetTrue),
) )
.arg( .arg(
Arg::new("ignore-block-entities") Arg::new("ignore-tile-entities")
.help("Ignores block entities when searching [Not Implemented]") .help("Ignores tile entities when searching [Not Implemented]")
.short('b') .short('b')
.long("ignore-block-entities") .long("ignore-tile-entities")
.action(ArgAction::SetTrue),
)
.arg(
Arg::new("ignore-tile-entity-data")
.help("Ignores tile entity data when searching [Not Implemented]")
.short('B')
.long("ignore-tile-entity-data")
.action(ArgAction::SetTrue), .action(ArgAction::SetTrue),
) )
.arg( .arg(
@ -179,7 +186,8 @@ fn main() {
let search_behavior = SearchBehavior { let search_behavior = SearchBehavior {
ignore_block_data: matches.get_flag("ignore-data"), ignore_block_data: matches.get_flag("ignore-data"),
ignore_block_entities: matches.get_flag("ignore-block-entities"), ignore_tile_entities: matches.get_flag("ignore-tile-entities"),
ignore_tile_entity_data: matches.get_flag("ignore-tile-entity-data"),
ignore_air: matches.get_flag("ignore-air"), ignore_air: matches.get_flag("ignore-air"),
air_as_any: matches.get_flag("air-as-any"), air_as_any: matches.get_flag("air-as-any"),
ignore_entities: matches.get_flag("ignore-entities"), ignore_entities: matches.get_flag("ignore-entities"),

Datei anzeigen

@ -18,7 +18,6 @@
use std::path::PathBuf; use std::path::PathBuf;
#[cfg(feature = "sql")] #[cfg(feature = "sql")]
use futures::executor::block_on; use futures::executor::block_on;
use schemsearch_files::Schematic;
#[cfg(feature = "sql")] #[cfg(feature = "sql")]
use schemsearch_sql::{load_schemdata, SchematicNode}; use schemsearch_sql::{load_schemdata, SchematicNode};

Datei anzeigen

@ -62,6 +62,9 @@ pub struct BlockEntity {
pub id: String, pub id: String,
#[serde(rename = "Pos")] #[serde(rename = "Pos")]
pub pos: [i32; 3], pub pos: [i32; 3],
#[serde(flatten)]
pub data: Map<String, Value>,
} }
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
@ -70,6 +73,9 @@ pub struct Entity {
pub id: String, pub id: String,
#[serde(rename = "Pos")] #[serde(rename = "Pos")]
pub pos: [i32; 3], pub pos: [i32; 3],
#[serde(flatten)]
pub data: Map<String, Value>,
} }
impl Schematic { impl Schematic {

Datei anzeigen

@ -35,14 +35,7 @@ pub extern "system" fn Java_SchemSearch_search<'local>(mut env: JNIEnv<'local>,
let schematic = Schematic::load(&PathBuf::from(&schematic_path)).unwrap(); let schematic = Schematic::load(&PathBuf::from(&schematic_path)).unwrap();
let pattern = Schematic::load(&PathBuf::from(&pattern_path)).unwrap(); let pattern = Schematic::load(&PathBuf::from(&pattern_path)).unwrap();
let matches = search(schematic, &pattern, SearchBehavior { let matches = search(schematic, &pattern, SearchBehavior::default());
ignore_block_data: true,
ignore_block_entities: true,
ignore_entities: true,
ignore_air: false,
air_as_any: false,
threshold: 0.0,
});
let mut result = String::new(); let mut result = String::new();
for (x, y, z, p) in matches { for (x, y, z, p) in matches {

Datei anzeigen

@ -25,13 +25,28 @@ use crate::pattern_mapper::match_palette_adapt;
#[derive(Debug, Clone, Copy, Deserialize, Serialize)] #[derive(Debug, Clone, Copy, Deserialize, Serialize)]
pub struct SearchBehavior { pub struct SearchBehavior {
pub ignore_block_data: bool, pub ignore_block_data: bool,
pub ignore_block_entities: bool, pub ignore_tile_entities: bool,
pub ignore_tile_entity_data: bool,
pub ignore_air: bool, pub ignore_air: bool,
pub air_as_any: bool, pub air_as_any: bool,
pub ignore_entities: bool, pub ignore_entities: bool,
pub threshold: f32, pub threshold: f32,
} }
impl Default for SearchBehavior {
fn default() -> Self {
SearchBehavior {
ignore_block_data: true,
ignore_tile_entities: true,
ignore_tile_entity_data: false,
ignore_entities: true,
ignore_air: false,
air_as_any: false,
threshold: 90.0,
}
}
}
pub fn search( pub fn search(
schem: Schematic, schem: Schematic,
pattern_schem: &Schematic, pattern_schem: &Schematic,
@ -61,7 +76,7 @@ pub fn search(
let air_id = if search_behavior.ignore_air || search_behavior.air_as_any { pattern_schem.palette.get("minecraft:air").unwrap_or(&-1) } else { &-1}; let air_id = if search_behavior.ignore_air || search_behavior.air_as_any { pattern_schem.palette.get("minecraft:air").unwrap_or(&-1) } else { &-1};
let pattern_blocks = (pattern_schem.width * pattern_schem.height * pattern_schem.length) as f32; let pattern_blocks = (pattern_schem.width * pattern_schem.height * pattern_schem.length) as f32 + if search_behavior.ignore_tile_entities { 0.0 } else { pattern_schem.block_entities.len() as f32 };
let pattern_width = pattern_schem.width as usize; let pattern_width = pattern_schem.width as usize;
let pattern_height = pattern_schem.height as usize; let pattern_height = pattern_schem.height as usize;
@ -88,6 +103,26 @@ pub fn search(
} }
} }
} }
if !search_behavior.ignore_tile_entities {
for tile_entity in &pattern_schem.block_entities {
for entry in &schem.block_entities {
if tile_entity.id.as_str() == entry.id.as_str() {
let pos = tile_entity.pos;
let schem_pos = [pos[0] + x as i32, pos[1] + y as i32, pos[2] + z as i32];
if schem_pos == entry.pos {
if search_behavior.ignore_tile_entity_data {
matching += 1;
} else {
if tile_entity.data == entry.data {
matching += 1;
}
}
}
}
}
}
}
let matching_percent = matching as f32 / pattern_blocks; let matching_percent = matching as f32 / pattern_blocks;
if matching_percent >= search_behavior.threshold { if matching_percent >= search_behavior.threshold {
matches.push((x as u16, y as u16, z as u16, matching_percent)); matches.push((x as u16, y as u16, z as u16, matching_percent));
@ -170,14 +205,7 @@ mod tests {
let schematic = Schematic::load(&PathBuf::from("../tests/simple.schem")).unwrap(); let schematic = Schematic::load(&PathBuf::from("../tests/simple.schem")).unwrap();
let endstone = Schematic::load(&PathBuf::from("../tests/endstone.schem")).unwrap(); let endstone = Schematic::load(&PathBuf::from("../tests/endstone.schem")).unwrap();
let _ = search(schematic, &endstone, SearchBehavior { let _ = search(schematic, &endstone, SearchBehavior::default());
ignore_block_data: true,
ignore_block_entities: true,
ignore_entities: true,
ignore_air: false,
air_as_any: false,
threshold: 0.9
});
} }
#[test] #[test]
@ -185,14 +213,7 @@ mod tests {
let schematic = Schematic::load(&PathBuf::from("../tests/Random.schem")).unwrap(); let schematic = Schematic::load(&PathBuf::from("../tests/Random.schem")).unwrap();
let pattern = Schematic::load(&PathBuf::from("../tests/Pattern.schem")).unwrap(); let pattern = Schematic::load(&PathBuf::from("../tests/Pattern.schem")).unwrap();
let matches = search(schematic, &pattern, SearchBehavior { let matches = search(schematic, &pattern, SearchBehavior::default());
ignore_block_data: true,
ignore_block_entities: true,
ignore_entities: true,
ignore_air: false,
air_as_any: false,
threshold: 0.9
});
println!("{:?}", matches); println!("{:?}", matches);
assert_eq!(matches.len(), 1); assert_eq!(matches.len(), 1);
@ -204,14 +225,7 @@ mod tests {
let schematic = Schematic::load(&PathBuf::from("../tests/warships/GreyFly-by-Bosslar.schem")).unwrap(); let schematic = Schematic::load(&PathBuf::from("../tests/warships/GreyFly-by-Bosslar.schem")).unwrap();
let pattern = Schematic::load(&PathBuf::from("../tests/gray_castle_complex.schem")).unwrap(); let pattern = Schematic::load(&PathBuf::from("../tests/gray_castle_complex.schem")).unwrap();
let matches = search(schematic, &pattern, SearchBehavior { let matches = search(schematic, &pattern, SearchBehavior::default());
ignore_block_data: false,
ignore_block_entities: false,
ignore_entities: false,
ignore_air: false,
air_as_any: false,
threshold: 0.9
});
println!("{:?}", matches); println!("{:?}", matches);
assert_eq!(matches.len(), 1); assert_eq!(matches.len(), 1);