1
0
Mirror von https://github.com/Chaoscaot/schemsearch synchronisiert 2024-11-19 10:20:08 +01:00

Fix Performance

Dieser Commit ist enthalten in:
Chaoscaot 2023-04-22 21:29:18 +02:00
Ursprung 9a0b0535c6
Commit 5cff84538d
5 geänderte Dateien mit 79 neuen und 196 gelöschten Zeilen

Datei anzeigen

@ -7,5 +7,5 @@ edition = "2021"
[dependencies] [dependencies]
flate2 = "1.0.25" flate2 = "1.0.25"
hematite-nbt = "0.5.2" named-binary-tag = "0.6"

Datei anzeigen

@ -18,7 +18,7 @@
use std::collections::hash_map::HashMap; use std::collections::hash_map::HashMap;
use std::io::Read; use std::io::Read;
use std::path::PathBuf; use std::path::PathBuf;
use nbt::Value; use nbt::{CompoundTag, Tag};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum SchematicVersioned { pub enum SchematicVersioned {
@ -94,7 +94,7 @@ impl SchematicVersioned {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct SpongeV1Schematic { pub struct SpongeV1Schematic {
pub metadata: HashMap<String, Value>, pub metadata: CompoundTag,
pub width: u16, pub width: u16,
pub height: u16, pub height: u16,
pub length: u16, pub length: u16,
@ -108,7 +108,7 @@ pub struct SpongeV1Schematic {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct SpongeV2Schematic { pub struct SpongeV2Schematic {
pub data_version: i32, pub data_version: i32,
pub metadata: HashMap<String, Value>, pub metadata: CompoundTag,
pub width: u16, pub width: u16,
pub height: u16, pub height: u16,
pub length: u16, pub length: u16,
@ -123,7 +123,7 @@ pub struct SpongeV2Schematic {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct SpongeV3Schematic { pub struct SpongeV3Schematic {
pub data_version: i32, pub data_version: i32,
pub metadata: HashMap<String, Value>, pub metadata: CompoundTag,
pub width: u16, pub width: u16,
pub height: u16, pub height: u16,
pub length: u16, pub length: u16,
@ -149,7 +149,7 @@ pub struct BlockEntity {
pub struct BlockEntityV3 { pub struct BlockEntityV3 {
pub id: String, pub id: String,
pub pos: [i32; 3], pub pos: [i32; 3],
pub data: HashMap<String, Value>, pub data: HashMap<String, Tag>,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -159,17 +159,9 @@ pub struct Entity {
} }
impl SchematicVersioned { impl SchematicVersioned {
pub fn load_data<R>(data: R) -> Result<SchematicVersioned, String> where R: Read { pub fn load_data<R>(data: &mut R) -> Result<SchematicVersioned, String> where R: Read {
let nbt: HashMap<String, Value> = nbt::de::from_gzip_reader(data).map_err(|e| e.to_string())?; let nbt: CompoundTag = nbt::decode::read_gzip_compound_tag(data).map_err(|e| e.to_string())?;
let version = match nbt.get("Version") { let version = nbt.get_i32("Version").map_err(|e| e.to_string())?;
Some(version) => match version {
Value::Short(n) => *n as i32,
Value::Byte(n) => *n as i32,
Value::Int(n) => *n,
_ => return Err("Invalid schematic: Wrong Version Type".to_string()),
},
None => return Err("Invalid schematic: Version not Found".to_string()),
};
match version { match version {
1 => Ok(SchematicVersioned::V1(SpongeV1Schematic::from_nbt(nbt)?)), 1 => Ok(SchematicVersioned::V1(SpongeV1Schematic::from_nbt(nbt)?)),
@ -180,212 +172,99 @@ impl SchematicVersioned {
} }
pub fn load(path: &PathBuf) -> Result<SchematicVersioned, String> { pub fn load(path: &PathBuf) -> Result<SchematicVersioned, String> {
let file = std::fs::File::open(path).map_err(|e| e.to_string())?; let mut file = std::fs::File::open(path).map_err(|e| e.to_string())?;
Self::load_data(file) Self::load_data(&mut file)
} }
} }
impl SpongeV1Schematic { impl SpongeV1Schematic {
pub fn from_nbt(nbt: HashMap<String, Value>) -> Result<Self, String> { pub fn from_nbt(nbt: CompoundTag) -> Result<Self, String> {
Ok(Self { Ok(Self {
metadata: match nbt.get("Metadata").ok_or("Invalid schematic: Metadata not found".to_string())? { metadata: nbt.get_compound_tag("Metadata").map_err(|e| e.to_string())?.clone(),
Value::Compound(metadata) => metadata.clone(), width: nbt.get_i16("Width").map_err(|e| e.to_string())? as u16,
_ => return Err("Invalid schematic: Metadata Wrong Type".to_string()), height: nbt.get_i16("Height").map_err(|e| e.to_string())? as u16,
}, length: nbt.get_i16("Length").map_err(|e| e.to_string())? as u16,
width: match nbt.get("Width").ok_or("Invalid schematic: Width not found".to_string())? { offset: read_offset(nbt.get_i32_vec("Offset").map_err(|e| e.to_string())?)?,
Value::Short(n) => *n as u16, palette_max: nbt.get_i32("PaletteMax").map_err(|e| e.to_string())?,
Value::Byte(n) => *n as u16, palette: read_palette(nbt.get_compound_tag("Palette").map_err(|e| e.to_string())?),
_ => return Err("Invalid schematic: Width Wrong Type".to_string()), block_data: read_blocks(nbt.get_i8_vec("BlockData").map_err(|e| e.to_string())?),
}, tile_entities: read_tile_entities(nbt.get_compound_tag_vec("TileEntities").map_err(|e| e.to_string())?)?,
height: match nbt.get("Height").ok_or("Invalid schematic: Height not found".to_string())? {
Value::Short(n) => *n as u16,
Value::Byte(n) => *n as u16,
_ => return Err("Invalid schematic: Height Wrong Type".to_string()),
},
length: match nbt.get("Length").ok_or("Invalid schematic: Length not found".to_string())? {
Value::Short(n) => *n as u16,
Value::Byte(n) => *n as u16,
_ => return Err("Invalid schematic: Length Wrong Type".to_string()),
},
offset: read_offset(nbt.get("Offset"))?,
palette_max: match nbt.get("PaletteMax").ok_or("Invalid schematic: PaletteMax not found".to_string())? {
Value::Int(p) => *p,
_ => return Err("Invalid schematic: PaletteMax Wrong Type".to_string()),
},
palette: read_palette(nbt.get("Palette"))?,
block_data: read_blocks(nbt.get("BlockData"))?,
tile_entities: read_tile_entities(nbt.get("TileEntities"))?,
}) })
} }
} }
impl SpongeV2Schematic { impl SpongeV2Schematic {
pub fn from_nbt(nbt: HashMap<String, Value>) -> Result<Self, String> { pub fn from_nbt(nbt: CompoundTag) -> Result<Self, String> {
Ok(Self{ Ok(Self{
data_version: match nbt.get("DataVersion").ok_or("Invalid schematic: DataVersion Missing".to_string())? { data_version: nbt.get_i32("DataVersion").map_err(|e| e.to_string())?,
Value::Short(n) => *n as i32, metadata: nbt.get_compound_tag("Metadata").map_err(|e| e.to_string())?.clone(),
Value::Byte(n) => *n as i32, width: nbt.get_i16("Width").map_err(|e| e.to_string())? as u16,
Value::Int(n) => *n, height: nbt.get_i16("Height").map_err(|e| e.to_string())? as u16,
_ => return Err("Invalid schematic: DataVersion Wrong Type".to_string()), length: nbt.get_i16("Length").map_err(|e| e.to_string())? as u16,
}, offset: read_offset(nbt.get_i32_vec("Offset").map_err(|e| e.to_string())?)?,
metadata: match nbt.get("Metadata").ok_or("Invalid schematic".to_string())? { palette_max: nbt.get_i32("PaletteMax").map_err(|e| e.to_string())?,
Value::Compound(m) => m.clone(), palette: read_palette(nbt.get_compound_tag("Palette").map_err(|e| e.to_string())?),
_ => return Err("Invalid schematic: Metadata Wrong Type".to_string()), block_data: read_blocks(nbt.get_i8_vec("BlockData").map_err(|e| e.to_string())?),
}, block_entities: read_tile_entities(nbt.get_compound_tag_vec("BlockEntities").map_err(|e| e.to_string())?)?,
width: match nbt.get("Width").ok_or("Invalid schematic".to_string())? {
Value::Short(n) => *n as u16,
Value::Byte(n) => *n as u16,
_ => return Err("Invalid schematic: Width Wrong Type".to_string()),
},
height: match nbt.get("Height").ok_or("Invalid schematic".to_string())? {
Value::Short(n) => *n as u16,
Value::Byte(n) => *n as u16,
_ => return Err("Invalid schematic: Height Wrong Type".to_string()),
},
length: match nbt.get("Length").ok_or("Invalid schematic".to_string())? {
Value::Short(n) => *n as u16,
Value::Byte(n) => *n as u16,
_ => return Err("Invalid schematic: Length Wrong Type".to_string()),
},
offset: read_offset(nbt.get("Offset"))?,
palette_max: match nbt.get("PaletteMax").ok_or("Invalid schematic: PaletteMax Missing".to_string())? {
Value::Short(n) => *n as i32,
Value::Byte(n) => *n as i32,
Value::Int(n) => *n,
_ => return Err("Invalid schematic: PaletteMax Invalid Type".to_string()),
},
palette: read_palette(nbt.get("Palette"))?,
block_data: read_blocks(nbt.get("BlockData"))?,
block_entities: read_tile_entities(nbt.get("BlockEntities"))?,
entities: None, entities: None,
}) })
} }
} }
impl SpongeV3Schematic { impl SpongeV3Schematic {
pub fn from_nbt(nbt: HashMap<String, Value>) -> Result<Self, String> { pub fn from_nbt(nbt: CompoundTag) -> Result<Self, String> {
let blocks = nbt.get_compound_tag("Blocks").map_err(|e| e.to_string())?;
Ok(Self{ Ok(Self{
data_version: match nbt.get("DataVersion").ok_or("Invalid schematic".to_string())? { data_version: nbt.get_i32("DataVersion").map_err(|e| e.to_string())?,
Value::Int(d) => *d, metadata: nbt.get_compound_tag("Metadata").map_err(|e| e.to_string())?.clone(),
_ => return Err("Invalid schematic".to_string()), width: nbt.get_i16("Width").map_err(|e| e.to_string())? as u16,
}, height: nbt.get_i16("Height").map_err(|e| e.to_string())? as u16,
metadata: match nbt.get("Metadata").ok_or("Invalid schematic".to_string())? { length: nbt.get_i16("Length").map_err(|e| e.to_string())? as u16,
Value::Compound(m) => m.clone(), offset: read_offset(nbt.get_i32_vec("Offset").map_err(|e| e.to_string())?)?,
_ => return Err("Invalid schematic".to_string()), blocks: BlockContainer {
}, palette: read_palette(blocks.get_compound_tag("Palette").map_err(|e| e.to_string())?),
width: match nbt.get("Width").ok_or("Invalid schematic".to_string())? { block_data: read_blocks(blocks.get_i8_vec("BlockData").map_err(|e| e.to_string())?),
Value::Short(n) => *n as u16, block_entities: read_tile_entities(blocks.get_compound_tag_vec("BlockEntities").map_err(|e| e.to_string())?)?,
Value::Byte(n) => *n as u16,
_ => return Err("Invalid schematic".to_string()),
},
height: match nbt.get("Height").ok_or("Invalid schematic".to_string())? {
Value::Short(n) => *n as u16,
Value::Byte(n) => *n as u16,
_ => return Err("Invalid schematic".to_string()),
},
length: match nbt.get("Length").ok_or("Invalid schematic".to_string())? {
Value::Short(n) => *n as u16,
Value::Byte(n) => *n as u16,
_ => return Err("Invalid schematic".to_string()),
},
offset: read_offset(nbt.get("Offset"))?,
blocks: match nbt.get("Blocks").ok_or("Invalid schematic".to_string())? {
Value::Compound(b) => {
BlockContainer {
palette: read_palette(b.get("Palette"))?,
block_data: read_blocks(b.get("BlockData"))?,
block_entities: read_tile_entities(b.get("BlockEntities"))?,
}
}
_ => return Err("Invalid schematic".to_string()),
}, },
entities: None, entities: None,
}) })
} }
} }
fn read_tile_entities(tag: Option<&Value>) -> Result<Vec<BlockEntity>, String> { fn read_tile_entities(tag: Vec<&CompoundTag>) -> Result<Vec<BlockEntity>, String> {
match tag.ok_or("Invalid schematic: read_tile_entities not found".to_string())? {
Value::List(t) => {
let mut tile_entities = Vec::new(); let mut tile_entities = Vec::new();
for te in t.iter() { for t in tag {
match te { tile_entities.push(BlockEntity {
Value::Compound(te) => { id: t.get_str("Id").map_err(|e| e.to_string())?.to_string(),
let id = match te.get("Id") { pos: read_offset(t.get("Pos").map_err(|e| e.to_string())?)?,
None => return Err("Invalid schematic: Id Not Found".to_string()), });
Some(id) => match id {
Value::String(id) => id.clone(),
_ => return Err("Invalid schematic: Id Wrong Type".to_string()),
},
};
let pos = read_offset(te.get("Pos"))?;
tile_entities.push(BlockEntity { id, pos });
},
_ => return Err("Invalid schematic: te Wrong Type".to_string()),
};
} }
Ok(tile_entities) Ok(tile_entities)
}, }
Value::ByteArray(_) => Ok(vec![]),
_ => return Err("Invalid schematic: te wrong type".to_string()), #[inline]
fn read_offset(offset: &Vec<i32>) -> Result<[i32; 3], String> {
match offset.len() {
3 => Ok([offset[0], offset[1], offset[2]]),
_ => Err("Invalid schematic: read_offset wrong length".to_string()),
} }
} }
#[inline] #[inline]
fn read_offset(offset: Option<&Value>) -> Result<[i32; 3], String> { fn read_palette(p: &CompoundTag) -> HashMap<String, i32> {
match offset.ok_or("Invalid schematic: read_offset missing".to_string())? {
Value::IntArray(o) => match o.len() {
3 => Ok([o[0], o[1], o[2]]),
_ => Err("Invalid schematic: Invalid IntArray".to_string()),
},
Value::ByteArray(o) => match o.len() {
3 => Ok([o[0] as i32, o[1] as i32, o[2] as i32]),
_ => Err("Invalid schematic: Invalid byteArray".to_string()),
},
Value::List(l) => match l.len() {
3 => {
let mut offset = [0; 3];
for (i, v) in l.iter().enumerate() {
match v {
Value::Int(n) => offset[i] = *n,
Value::Byte(n) => offset[i] = *n as i32,
Value::Short(n) => offset[i] = *n as i32,
_ => return Err("Invalid schematic: read_offset invalid Number".to_string()),
};
}
Ok(offset)
},
_ => Err("Invalid schematic: Invalid List".to_string()),
}
_ => Err("Invalid schematic: read_offset".to_string()),
}
}
#[inline]
fn read_palette(palette: Option<&Value>) -> Result<HashMap<String, i32>, String> {
match palette.ok_or("Invalid schematic: read_palette missing".to_string())? {
Value::Compound(p) => {
let mut palette = HashMap::new(); let mut palette = HashMap::new();
for (k, v) in p.iter() { for (key, value) in p.iter() {
match v { match value {
Value::Int(v) => { palette.insert(k.clone(), *v); }, Tag::Int(n) => { palette.insert(key.clone(), *n); },
Value::Byte(v) => { palette.insert(k.clone(), *v as i32); }, _ => {},
Value::Short(v) => { palette.insert(k.clone(), *v as i32); },
_ => return Err("Invalid schematic: read_palette invalid Number".to_string()),
}; };
} }
Ok(palette) palette
},
_ => Err("Invalid schematic: read_palette invalid Type".to_string()),
}
} }
#[inline] #[inline]
fn read_blocks(blockdata: Option<&Value>) -> Result<Vec<i32>, String> { fn read_blocks(blockdata: &Vec<i8>) -> Vec<i32> {
match blockdata.ok_or("Invalid schematic: BlockData not found".to_string())? { read_varint_array(blockdata)
Value::ByteArray(b) => Ok(read_varint_array(b)),
_ => Err("Invalid schematic: Invalid BlockData".to_string()),
}
} }
#[inline] #[inline]

Datei anzeigen

@ -7,4 +7,6 @@ license = "AGPL-3.0-or-later"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
serde = { version = "1.0.160", features = ["derive"] }
schemsearch-files = { path = "../schemsearch-files" } schemsearch-files = { path = "../schemsearch-files" }
named-binary-tag = "0.6"

Datei anzeigen

@ -17,6 +17,7 @@
pub mod pattern_mapper; pub mod pattern_mapper;
use serde::{Serialize, Deserialize};
use pattern_mapper::match_palette; use pattern_mapper::match_palette;
use schemsearch_files::SchematicVersioned; use schemsearch_files::SchematicVersioned;
use crate::pattern_mapper::match_palette_adapt; use crate::pattern_mapper::match_palette_adapt;

Datei anzeigen

@ -15,7 +15,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
use nbt::Map; use std::collections::HashMap;
use nbt::CompoundTag;
use schemsearch_files::{SchematicVersioned, SpongeV2Schematic}; use schemsearch_files::{SchematicVersioned, SpongeV2Schematic};
use crate::normalize_data; use crate::normalize_data;
@ -31,7 +32,7 @@ fn create_reverse_palette(schem: &SchematicVersioned) -> Vec<&str> {
pub fn strip_data(schem: &SchematicVersioned) -> SchematicVersioned { pub fn strip_data(schem: &SchematicVersioned) -> SchematicVersioned {
let mut data: Vec<i32> = Vec::new(); let mut data: Vec<i32> = Vec::new();
let mut palette: Map<String, i32> = Map::new(); let mut palette: HashMap<String, i32> = HashMap::new();
let mut palette_max: i32 = 0; let mut palette_max: i32 = 0;
let reverse_palette = create_reverse_palette(schem); let reverse_palette = create_reverse_palette(schem);
@ -56,7 +57,7 @@ pub fn strip_data(schem: &SchematicVersioned) -> SchematicVersioned {
height: schem.get_height(), height: schem.get_height(),
length: schem.get_length(), length: schem.get_length(),
width: schem.get_width(), width: schem.get_width(),
metadata: Map::new(), metadata: CompoundTag::new(),
offset: [0; 3], offset: [0; 3],
entities: None, entities: None,
},) },)
@ -64,7 +65,7 @@ pub fn strip_data(schem: &SchematicVersioned) -> SchematicVersioned {
} }
pub fn match_palette_adapt(schem: &SchematicVersioned, matching_palette: &Map<String, i32>, ignore_data: bool) -> Vec<i32> { pub fn match_palette_adapt(schem: &SchematicVersioned, matching_palette: &HashMap<String, i32>, ignore_data: bool) -> Vec<i32> {
let mut data: Vec<i32> = Vec::new(); let mut data: Vec<i32> = Vec::new();
let reverse_palette = create_reverse_palette(schem); let reverse_palette = create_reverse_palette(schem);
@ -109,7 +110,7 @@ fn match_palette_internal(
height: pattern.get_height(), height: pattern.get_height(),
length: pattern.get_length(), length: pattern.get_length(),
width: pattern.get_width(), width: pattern.get_width(),
metadata: Map::new(), metadata: CompoundTag::new(),
offset: [0; 3], offset: [0; 3],
entities: None, entities: None,
}) })