Files
cursebreaker-parser-rust/cursebreaker-parser/src/xml_parsers/maps.rs
2026-01-26 13:05:57 +00:00

129 lines
5.4 KiB
Rust

//! Map XML Parser
use crate::types::Map;
use super::{parse_attributes, XmlParseError};
use quick_xml::events::Event;
use quick_xml::reader::Reader;
use std::fs::File;
use std::io::BufReader;
use std::path::Path;
pub fn parse_maps_xml<P: AsRef<Path>>(path: P) -> Result<Vec<Map>, XmlParseError> {
let file = File::open(path)?;
let buf_reader = BufReader::new(file);
let mut reader = Reader::from_reader(buf_reader);
reader.config_mut().trim_text(true);
let mut maps = Vec::new();
let mut buf = Vec::new();
loop {
match reader.read_event_into(&mut buf) {
Ok(Event::Start(ref e)) | Ok(Event::Empty(ref e)) => {
match e.name().as_ref() {
b"map" => {
let attrs = parse_attributes(e)?;
// Get required attributes
let scene_id = attrs.get("sceneid")
.ok_or_else(|| XmlParseError::MissingAttribute("sceneid".to_string()))?
.clone();
let music = attrs.get("music")
.ok_or_else(|| XmlParseError::MissingAttribute("music".to_string()))?
.parse::<i32>()
.map_err(|_| XmlParseError::InvalidAttribute("music".to_string()))?;
let ambience = attrs.get("ambience")
.ok_or_else(|| XmlParseError::MissingAttribute("ambience".to_string()))?
.parse::<i32>()
.map_err(|_| XmlParseError::InvalidAttribute("ambience".to_string()))?;
let mut map = Map::new(scene_id, music, ambience);
// Parse optional attributes
if let Some(v) = attrs.get("name") {
map.name = v.clone();
}
if let Some(v) = attrs.get("fogcolor") {
map.fog_color = Some(v.clone());
}
if let Some(v) = attrs.get("fogginess") {
map.fogginess = v.parse().ok();
}
if let Some(v) = attrs.get("viewdistance") {
map.view_distance = v.parse().ok();
}
if let Some(v) = attrs.get("npcviewdistance") {
map.npc_view_distance = v.parse().ok();
}
if let Some(v) = attrs.get("sunlight") {
map.sunlight = v.parse().ok();
}
if let Some(v) = attrs.get("suncolor") {
map.sun_color = Some(v.clone());
}
if let Some(v) = attrs.get("ambientcolor") {
map.ambient_color = Some(v.clone());
}
if let Some(v) = attrs.get("indoorsunlight") {
map.indoor_sunlight = v.parse().ok();
}
if let Some(v) = attrs.get("fogstart") {
map.fog_start = v.parse().ok();
}
if attrs.get("indoors").is_some() {
map.indoors = true;
}
if attrs.get("noworldmap").is_some() {
map.no_world_map = true;
}
if attrs.get("nominimap").is_some() {
map.no_minimap = true;
}
if attrs.get("tpdisabled").is_some() {
map.tp_disabled = true;
}
if attrs.get("dontloadnearbyscenes").is_some() {
map.dont_load_nearby_scenes = true;
}
if attrs.get("noborder").is_some() {
map.no_border = true;
}
if attrs.get("borderleft").is_some() {
map.border_left = true;
}
if attrs.get("borderright").is_some() {
map.border_right = true;
}
if attrs.get("borderup").is_some() {
map.border_up = true;
}
if attrs.get("borderdown").is_some() {
map.border_down = true;
}
if let Some(v) = attrs.get("respawnmap") {
map.respawn_map = Some(v.clone());
}
if let Some(v) = attrs.get("connectedmaps") {
map.connected_maps = Some(v.clone());
}
if let Some(v) = attrs.get("comment") {
map.comment = Some(v.clone());
}
maps.push(map);
}
_ => {}
}
}
Ok(Event::Eof) => break,
Err(e) => return Err(XmlParseError::XmlError(e)),
_ => {}
}
buf.clear();
}
Ok(maps)
}