From 4cf075fe45a2ea4c891a4cfdb7c1190d30bb7adc Mon Sep 17 00:00:00 2001 From: Micah Date: Tue, 24 Sep 2024 11:38:12 -0700 Subject: [PATCH] Reserialize HumanoidDescription properties that aren't deterministic --- src/syncback/mod.rs | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/syncback/mod.rs b/src/syncback/mod.rs index d3a459cba..8038910db 100644 --- a/src/syncback/mod.rs +++ b/src/syncback/mod.rs @@ -89,6 +89,7 @@ pub fn syncback_loop( } } } + reserialize_humanoid_descriptions(&mut new_tree); // Handle removing the current camera. if let Some(syncback_rules) = &project.syncback_rules { @@ -511,3 +512,39 @@ fn strip_unknown_root_children(new: &mut WeakDom, old: &RojoTree) { new.destroy(child_ref); } } + +/// HACK: There are non-deterministic properties on `HumanoidDescription` +/// and they cause spurious diffs. We can fix that by reserializing them +/// manually. +fn reserialize_humanoid_descriptions(dom: &mut WeakDom) { + log::debug!("Fixing serialization of HumanoidDescriptions"); + for referent in descendants(dom, dom.root_ref()) { + let inst = dom + .get_by_ref_mut(referent) + .expect("all descendants should be in the DOM"); + if inst.class != "HumanoidDescription" { + continue; + } + if let Some(Variant::String(content)) = inst.properties.remove("EquippedEmotesDataInternal") + { + inst.properties.insert( + "EquippedEmotesDataInternal".into(), + split_and_reorder(content).into(), + ); + } + if let Some(Variant::String(content)) = inst.properties.remove("EmotesDataInternal") { + inst.properties.insert( + "EmotesDataInternal".into(), + split_and_reorder(content).into(), + ); + } + } +} + +fn split_and_reorder(content: String) -> String { + let mut subsections: Vec<_> = content.split("\\").collect(); + subsections.pop(); + subsections.sort(); + subsections.push(""); + subsections.join("\\") +}