Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deal with either Legacy XML or ASR XML #74

Merged
merged 2 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 71 additions & 24 deletions splits/all_skills_shuffle/all_skills_shuffle.lss
Original file line number Diff line number Diff line change
Expand Up @@ -237,29 +237,76 @@
</Segment>
</Segments>
<AutoSplitterSettings>
<Ordered>True</Ordered>
<AutosplitEndRuns>False</AutosplitEndRuns>
<AutosplitStartRuns>RandoWake</AutosplitStartRuns>
<Splits>
<Split>OnObtainAllSkillsShuffleItem</Split>
<Split>OnObtainAllSkillsShuffleItem</Split>
<Split>OnObtainAllSkillsShuffleItem</Split>
<Split>OnObtainAllSkillsShuffleItem</Split>
<Split>OnObtainAllSkillsShuffleItem</Split>
<Split>OnObtainAllSkillsShuffleItem</Split>
<Split>OnObtainAllSkillsShuffleItem</Split>
<Split>OnObtainAllSkillsShuffleItem</Split>
<Split>OnObtainAllSkillsShuffleItem</Split>
<Split>OnObtainAllSkillsShuffleItem</Split>
<Split>OnObtainAllSkillsShuffleItem</Split>
<Split>OnObtainAllSkillsShuffleItem</Split>
<Split>OnObtainAllSkillsShuffleItem</Split>
<Split>OnObtainAllSkillsShuffleItem</Split>
<Split>OnObtainAllSkillsShuffleItem</Split>
<Split>OnObtainAllSkillsShuffleItem</Split>
<Split>OnObtainAllSkillsShuffleItem</Split>
<Split>OnObtainAllSkillsShuffleItem</Split>
<Split>OnObtainAllSkillsShuffleItem</Split>
</Splits>
<Version>1.0.0.0</Version>
<ScriptPath />
<CustomSettings>
<Setting id="splits" type="list">
<Setting type="string" value="RandoWake" />
<Setting type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting type="string" value="EndingSplit" />
</Setting>
<Setting id="splits_0_item" type="string" value="RandoWake" />
<Setting id="splits_1_item" type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting id="splits_2_item" type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting id="splits_3_item" type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting id="splits_4_item" type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting id="splits_5_item" type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting id="splits_6_item" type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting id="splits_7_item" type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting id="splits_8_item" type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting id="splits_9_item" type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting id="splits_10_item" type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting id="splits_11_item" type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting id="splits_12_item" type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting id="splits_13_item" type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting id="splits_14_item" type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting id="splits_15_item" type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting id="splits_16_item" type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting id="splits_17_item" type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting id="splits_18_item" type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting id="splits_19_item" type="string" value="OnObtainAllSkillsShuffleItem" />
<Setting id="splits_20_item" type="string" value="EndingSplit" />
<Setting id="timing_method" type="string" value="LoadRemovedTime" />
<Setting id="splits_insert_0" type="bool">False</Setting>
<Setting id="splits_0_action" type="string" value="None" />
<Setting id="splits_1_action" type="string" value="None" />
<Setting id="splits_2_action" type="string" value="None" />
<Setting id="splits_3_action" type="string" value="None" />
<Setting id="splits_4_action" type="string" value="None" />
<Setting id="splits_5_action" type="string" value="None" />
<Setting id="splits_6_action" type="string" value="None" />
<Setting id="splits_7_action" type="string" value="None" />
<Setting id="splits_8_action" type="string" value="None" />
<Setting id="splits_9_action" type="string" value="None" />
<Setting id="splits_10_action" type="string" value="None" />
<Setting id="splits_11_action" type="string" value="None" />
<Setting id="splits_12_action" type="string" value="None" />
<Setting id="splits_13_action" type="string" value="None" />
<Setting id="splits_14_action" type="string" value="None" />
<Setting id="splits_15_action" type="string" value="None" />
<Setting id="splits_16_action" type="string" value="None" />
<Setting id="splits_17_action" type="string" value="None" />
<Setting id="splits_18_action" type="string" value="None" />
<Setting id="splits_19_action" type="string" value="None" />
<Setting id="splits_20_action" type="string" value="None" />
</CustomSettings>
</AutoSplitterSettings>
</Run>
69 changes: 50 additions & 19 deletions splits/current/splits-direct.lss
Original file line number Diff line number Diff line change
Expand Up @@ -160,24 +160,55 @@
</Segment>
</Segments>
<AutoSplitterSettings>
<Ordered>True</Ordered>
<AutosplitEndRuns>True</AutosplitEndRuns>
<AutosplitStartRuns>StartNewGame</AutosplitStartRuns>
<Splits>
<Split>KingsPass</Split>
<Split>Grub1</Split>
<Split>EnterBroodingMawlek</Split>
<Split>MaskFragment1</Split>
<Split>Grub2</Split>
<Split>MaskFragment2</Split>
<Split>GruzMother</Split>
<Split>SlyRescued</Split>
<Split>Grub3</Split>
<Split>Grub4</Split>
<Split>Grub5</Split>
<Split>MaskFragment3</Split>
<Split>Mask1</Split>
</Splits>
<TimingMethod>LoadRemovedTime</TimingMethod>
<Version>1.0.0.0</Version>
<ScriptPath />
<CustomSettings>
<Setting id="splits" type="list">
<Setting type="string" value="StartNewGame" />
<Setting type="string" value="KingsPass" />
<Setting type="string" value="Grub1" />
<Setting type="string" value="EnterBroodingMawlek" />
<Setting type="string" value="MaskFragment1" />
<Setting type="string" value="Grub2" />
<Setting type="string" value="MaskFragment2" />
<Setting type="string" value="GruzMother" />
<Setting type="string" value="SlyRescued" />
<Setting type="string" value="Grub3" />
<Setting type="string" value="Grub4" />
<Setting type="string" value="Grub5" />
<Setting type="string" value="MaskFragment3" />
<Setting type="string" value="Mask1" />
</Setting>
<Setting id="timing_method" type="string" value="LoadRemovedTime" />
<Setting id="splits_0_item" type="string" value="StartNewGame" />
<Setting id="splits_1_item" type="string" value="KingsPass" />
<Setting id="splits_2_item" type="string" value="Grub1" />
<Setting id="splits_3_item" type="string" value="EnterBroodingMawlek" />
<Setting id="splits_4_item" type="string" value="MaskFragment1" />
<Setting id="splits_5_item" type="string" value="Grub2" />
<Setting id="splits_6_item" type="string" value="MaskFragment2" />
<Setting id="splits_7_item" type="string" value="GruzMother" />
<Setting id="splits_8_item" type="string" value="SlyRescued" />
<Setting id="splits_9_item" type="string" value="Grub3" />
<Setting id="splits_10_item" type="string" value="Grub4" />
<Setting id="splits_11_item" type="string" value="Grub5" />
<Setting id="splits_12_item" type="string" value="MaskFragment3" />
<Setting id="splits_13_item" type="string" value="Mask1" />
<Setting id="splits_insert_0" type="bool">False</Setting>
<Setting id="splits_0_action" type="string" value="None" />
<Setting id="splits_1_action" type="string" value="None" />
<Setting id="splits_2_action" type="string" value="None" />
<Setting id="splits_3_action" type="string" value="None" />
<Setting id="splits_4_action" type="string" value="None" />
<Setting id="splits_5_action" type="string" value="None" />
<Setting id="splits_6_action" type="string" value="None" />
<Setting id="splits_7_action" type="string" value="None" />
<Setting id="splits_8_action" type="string" value="None" />
<Setting id="splits_9_action" type="string" value="None" />
<Setting id="splits_10_action" type="string" value="None" />
<Setting id="splits_11_action" type="string" value="None" />
<Setting id="splits_12_action" type="string" value="None" />
<Setting id="splits_13_action" type="string" value="None" />
</CustomSettings>
</AutoSplitterSettings>
</Run>
69 changes: 50 additions & 19 deletions splits/hits/splits-direct.lss
Original file line number Diff line number Diff line change
Expand Up @@ -160,24 +160,55 @@
</Segment>
</Segments>
<AutoSplitterSettings>
<Ordered>True</Ordered>
<AutosplitEndRuns>True</AutosplitEndRuns>
<AutosplitStartRuns>StartNewGame</AutosplitStartRuns>
<Splits>
<Split>KingsPass</Split>
<Split>Grub1</Split>
<Split>EnterBroodingMawlek</Split>
<Split>MaskFragment1</Split>
<Split>Grub2</Split>
<Split>MaskFragment2</Split>
<Split>GruzMother</Split>
<Split>SlyRescued</Split>
<Split>Grub3</Split>
<Split>Grub4</Split>
<Split>Grub5</Split>
<Split>MaskFragment3</Split>
<Split>Mask1</Split>
</Splits>
<TimingMethod>HitsDreamFalls</TimingMethod>
<Version>1.0.0.0</Version>
<ScriptPath />
<CustomSettings>
<Setting id="splits" type="list">
<Setting type="string" value="StartNewGame" />
<Setting type="string" value="KingsPass" />
<Setting type="string" value="Grub1" />
<Setting type="string" value="EnterBroodingMawlek" />
<Setting type="string" value="MaskFragment1" />
<Setting type="string" value="Grub2" />
<Setting type="string" value="MaskFragment2" />
<Setting type="string" value="GruzMother" />
<Setting type="string" value="SlyRescued" />
<Setting type="string" value="Grub3" />
<Setting type="string" value="Grub4" />
<Setting type="string" value="Grub5" />
<Setting type="string" value="MaskFragment3" />
<Setting type="string" value="Mask1" />
</Setting>
<Setting id="timing_method" type="string" value="HitsDreamFalls" />
<Setting id="splits_0_item" type="string" value="StartNewGame" />
<Setting id="splits_1_item" type="string" value="KingsPass" />
<Setting id="splits_2_item" type="string" value="Grub1" />
<Setting id="splits_3_item" type="string" value="EnterBroodingMawlek" />
<Setting id="splits_4_item" type="string" value="MaskFragment1" />
<Setting id="splits_5_item" type="string" value="Grub2" />
<Setting id="splits_6_item" type="string" value="MaskFragment2" />
<Setting id="splits_7_item" type="string" value="GruzMother" />
<Setting id="splits_8_item" type="string" value="SlyRescued" />
<Setting id="splits_9_item" type="string" value="Grub3" />
<Setting id="splits_10_item" type="string" value="Grub4" />
<Setting id="splits_11_item" type="string" value="Grub5" />
<Setting id="splits_12_item" type="string" value="MaskFragment3" />
<Setting id="splits_13_item" type="string" value="Mask1" />
<Setting id="splits_insert_0" type="bool">False</Setting>
<Setting id="splits_0_action" type="string" value="None" />
<Setting id="splits_1_action" type="string" value="None" />
<Setting id="splits_2_action" type="string" value="None" />
<Setting id="splits_3_action" type="string" value="None" />
<Setting id="splits_4_action" type="string" value="None" />
<Setting id="splits_5_action" type="string" value="None" />
<Setting id="splits_6_action" type="string" value="None" />
<Setting id="splits_7_action" type="string" value="None" />
<Setting id="splits_8_action" type="string" value="None" />
<Setting id="splits_9_action" type="string" value="None" />
<Setting id="splits_10_action" type="string" value="None" />
<Setting id="splits_11_action" type="string" value="None" />
<Setting id="splits_12_action" type="string" value="None" />
<Setting id="splits_13_action" type="string" value="None" />
</CustomSettings>
</AutoSplitterSettings>
</Run>
83 changes: 83 additions & 0 deletions src/asr_xml.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@

Check failure on line 1 in src/asr_xml.rs

View workflow job for this annotation

GitHub Actions / Check formatting

Diff in /home/runner/work/hollowknight-autosplit-wasm/hollowknight-autosplit-wasm/src/asr_xml.rs
use std::str::FromStr;

use xmltree::{Element, XMLNode};

pub fn asr_settings_from_xml_nodes(xml_nodes: Vec<XMLNode>) -> Option<asr::settings::Map> {
let custom_settings = xml_nodes.iter().find_map(xml_node_find_custom_settings)?;
Some(parse_settings_map(custom_settings))
}

fn xml_node_find_custom_settings(xml: &XMLNode) -> Option<&[XMLNode]> {
let Element { name, children, .. } = xml.as_element()?;
if name != "CustomSettings" {
return None;
}
Some(children)
}

fn parse_settings_map(xml_nodes: &[XMLNode]) -> asr::settings::Map {
let settings_map = asr::settings::Map::new();
for xml_node in xml_nodes {
if let (Some(id), Some(value)) = parse_settings_entry(xml_node) {
settings_map.insert(id, value);
}
}
settings_map
}

fn parse_settings_list(xml_nodes: &[XMLNode]) -> asr::settings::List {
let settings_list = asr::settings::List::new();
for xml_node in xml_nodes {
if let (_, Some(value)) = parse_settings_entry(xml_node) {
settings_list.push(value);
}
}
settings_list
}

Check failure on line 37 in src/asr_xml.rs

View workflow job for this annotation

GitHub Actions / Check formatting

Diff in /home/runner/work/hollowknight-autosplit-wasm/hollowknight-autosplit-wasm/src/asr_xml.rs

fn parse_settings_entry(xml_node: &XMLNode) -> (Option<&String>, Option<asr::settings::Value>) {
let Some(Element { attributes, children, .. }) = xml_node.as_element() else {
return (None, None);
};
let id = attributes.get("id");
let Some(setting_type) = attributes.get("type") else {
return (id, None);
};
let value = match setting_type.as_str() {
"bool" => Some(parse_bool(&children).unwrap_or_default().into()),

Check warning on line 48 in src/asr_xml.rs

View workflow job for this annotation

GitHub Actions / Check clippy lints

this expression creates a reference which is immediately dereferenced by the compiler
"i64" => Some(parse_fromstr::<i64>(&children).unwrap_or_default().into()),

Check warning on line 49 in src/asr_xml.rs

View workflow job for this annotation

GitHub Actions / Check clippy lints

this expression creates a reference which is immediately dereferenced by the compiler
"f64" => Some(parse_fromstr::<f64>(&children).unwrap_or_default().into()),

Check warning on line 50 in src/asr_xml.rs

View workflow job for this annotation

GitHub Actions / Check clippy lints

this expression creates a reference which is immediately dereferenced by the compiler
"string" => {
if let Some(string_value) = attributes.get("value") {
Some(string_value.as_str().into())
} else {
Some(parse_text(&children).unwrap_or_default().into())

Check warning on line 55 in src/asr_xml.rs

View workflow job for this annotation

GitHub Actions / Check clippy lints

this expression creates a reference which is immediately dereferenced by the compiler
}
}
"map" => Some(parse_settings_map(&children).into()),

Check warning on line 58 in src/asr_xml.rs

View workflow job for this annotation

GitHub Actions / Check clippy lints

this expression creates a reference which is immediately dereferenced by the compiler
"list" => Some(parse_settings_list(&children).into()),

Check warning on line 59 in src/asr_xml.rs

View workflow job for this annotation

GitHub Actions / Check clippy lints

this expression creates a reference which is immediately dereferenced by the compiler
_ => None,
};
(id, value)
}

fn parse_text(xml_nodes: &[XMLNode]) -> Option<&str> {
match xml_nodes {
[] => Some(""),
[XMLNode::Text(s)] => Some(s),
_ => None,
}
}

fn parse_bool(xml_nodes: &[XMLNode]) -> Option<bool> {
match parse_text(xml_nodes)?.trim() {
"True" => Some(true),
"False" => Some(false),
_ => None,
}
}

fn parse_fromstr<F: FromStr>(xml_nodes: &[XMLNode]) -> Option<F> {
parse_text(xml_nodes)?.trim().parse().ok()
}
13 changes: 10 additions & 3 deletions src/auto_splitter_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
use std::path::Path;
use xmltree::{Element, XMLNode};

use crate::{file, legacy_xml};
use crate::{asr_xml, file, legacy_xml};

Check failure on line 8 in src/auto_splitter_settings.rs

View workflow job for this annotation

GitHub Actions / Check formatting

Diff in /home/runner/work/hollowknight-autosplit-wasm/hollowknight-autosplit-wasm/src/auto_splitter_settings.rs
pub async fn wait_asr_settings_init() -> asr::settings::Map {
let settings1 = asr::settings::Map::load();
if settings1.get("splits").is_some_and(|v| v.get_list().is_some_and(|l| !l.is_empty())) {
Expand Down Expand Up @@ -40,8 +40,11 @@
}

fn asr_settings_from_xml_nodes(xml_nodes: Vec<XMLNode>) -> Option<asr::settings::Map> {
// TODO: deal with either Legacy XML or ASR XML
legacy_xml::asr_settings_from_xml_nodes(xml_nodes)
if any_xml_nodes_from_asr(&xml_nodes) {
asr_xml::asr_settings_from_xml_nodes(xml_nodes)
} else {
legacy_xml::asr_settings_from_xml_nodes(xml_nodes)
}
}

fn file_find_auto_splitter_settings<P: AsRef<Path>>(path: P) -> Option<Vec<XMLNode>> {
Expand All @@ -53,14 +56,14 @@

fn xml_find_auto_splitter_settings(xml: &XMLNode) -> Option<Vec<XMLNode>> {
let e = xml.as_element()?;
match e.name.as_str() {

Check failure on line 59 in src/auto_splitter_settings.rs

View workflow job for this annotation

GitHub Actions / Check formatting

Diff in /home/runner/work/hollowknight-autosplit-wasm/hollowknight-autosplit-wasm/src/auto_splitter_settings.rs
"AutoSplitterSettings" => Some(e.children.clone()),
"Run" => Some(e.get_child("AutoSplitterSettings")?.children.clone()),
"Layout" => e.get_child("Components")?.children.iter().find_map(xml_find_auto_splitter_settings),
"Component" if component_is_asr(e) => Some(e.get_child("Settings")?.children.clone()),
_ => None,
}
}

Check failure on line 66 in src/auto_splitter_settings.rs

View workflow job for this annotation

GitHub Actions / Check formatting

Diff in /home/runner/work/hollowknight-autosplit-wasm/hollowknight-autosplit-wasm/src/auto_splitter_settings.rs

fn component_is_asr(e: &Element) -> bool {
let Some(p) = e.get_child("Path") else { return false; };
Expand All @@ -69,6 +72,10 @@
s.contains("LiveSplit.AutoSplittingRuntime")
}

fn any_xml_nodes_from_asr(xml_nodes: &[XMLNode]) -> bool {

Check failure on line 75 in src/auto_splitter_settings.rs

View workflow job for this annotation

GitHub Actions / Check formatting

Diff in /home/runner/work/hollowknight-autosplit-wasm/hollowknight-autosplit-wasm/src/auto_splitter_settings.rs
xml_nodes.iter().any(|n| n.as_element().is_some_and(|e| ["Version", "ScriptPath", "CustomSettings"].contains(&e.name.as_str())))
}

// --------------------------------------------------------

async fn wait_asr_settings_load_merge_store(new: &asr::settings::Map) -> asr::settings::Map {
Expand All @@ -82,7 +89,7 @@
Some(merged)
} else {
None
}

Check failure on line 92 in src/auto_splitter_settings.rs

View workflow job for this annotation

GitHub Actions / Check formatting

Diff in /home/runner/work/hollowknight-autosplit-wasm/hollowknight-autosplit-wasm/src/auto_splitter_settings.rs
}

fn maybe_asr_settings_map_merge(old: Option<asr::settings::Map>, new: &asr::settings::Map) -> asr::settings::Map {
Expand All @@ -94,14 +101,14 @@
om.insert(&key, &maybe_asr_settings_value_merge(om.get(&key), &new_v));
}
}
om

Check failure on line 104 in src/auto_splitter_settings.rs

View workflow job for this annotation

GitHub Actions / Check formatting

Diff in /home/runner/work/hollowknight-autosplit-wasm/hollowknight-autosplit-wasm/src/auto_splitter_settings.rs
}

fn maybe_asr_settings_value_merge(old: Option<asr::settings::Value>, new: &asr::settings::Value) -> asr::settings::Value {
if let Some(b) = new.get_bool() {
asr::settings::Value::from(b)
} else if let Some(s) = new.get_string() {
asr::settings::Value::from(s.as_str())

Check failure on line 111 in src/auto_splitter_settings.rs

View workflow job for this annotation

GitHub Actions / Check formatting

Diff in /home/runner/work/hollowknight-autosplit-wasm/hollowknight-autosplit-wasm/src/auto_splitter_settings.rs
} else if let Some(l) = new.get_list() {
asr::settings::Value::from(&maybe_asr_settings_list_merge(old.and_then(|o| o.get_list()), &l))
} else if let Some(m) = new.get_map() {
Expand All @@ -112,7 +119,7 @@
}

fn is_asr_settings_list_length(l: &asr::settings::List, n: u64) -> bool {
l.len() == n

Check failure on line 122 in src/auto_splitter_settings.rs

View workflow job for this annotation

GitHub Actions / Check formatting

Diff in /home/runner/work/hollowknight-autosplit-wasm/hollowknight-autosplit-wasm/src/auto_splitter_settings.rs
}

fn maybe_asr_settings_list_merge(old: Option<asr::settings::List>, new: &asr::settings::List) -> asr::settings::List {
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

extern crate alloc;

mod asr_xml;
mod auto_splitter_settings;
mod file;
mod hollow_knight_memory;
Expand Down
Loading