From 9f804354e4429471af2f725f0ae0ca0d58728cba Mon Sep 17 00:00:00 2001 From: SabrePenguin Date: Wed, 16 Apr 2025 18:34:30 -0500 Subject: [PATCH 1/5] Add GameplayTagContainer basics --- src/properties/struct_property.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/properties/struct_property.rs b/src/properties/struct_property.rs index 3b641d6..4443a39 100644 --- a/src/properties/struct_property.rs +++ b/src/properties/struct_property.rs @@ -80,6 +80,8 @@ pub enum StructPropertyValue { LinearColor(LinearColor), /// An `IntPoint` value. IntPoint(IntPoint), + /// A `GameplayTagContainer` value. + GameplayTagContainer(Vec), /// A custom struct value. CustomStruct(HashableIndexMap>), } @@ -168,6 +170,7 @@ impl StructProperty { "LinearColor" => StructPropertyValue::read_linearcolor(cursor)?, "IntPoint" => StructPropertyValue::read_intpoint(cursor)?, "Guid" => StructPropertyValue::read_guid(cursor)?, + "GameplayTagContainer" => StructPropertyValue::read_gameplaytagcontainer(cursor)?, _ => StructPropertyValue::read_custom(cursor, options)?, }; Ok(value) @@ -344,6 +347,13 @@ impl PropertyTrait for StructPropertyValue { cursor.write_guid(guid)?; Ok(16) } + StructPropertyValue::GameplayTagContainer(tags) => { + let mut len = tags.len(); + for gameplaytag in tags { + len += cursor.write_string(gameplaytag)?; + } + Ok(len) + } StructPropertyValue::CustomStruct(properties) => { let mut len = 0; for (key, values) in properties { @@ -380,6 +390,15 @@ impl StructPropertyValue { Ok(StructPropertyValue::CustomStruct(properties)) } + fn read_gameplaytagcontainer(cursor: &mut R) -> Result { + let len = cursor.read_i32::()?; + let mut tags: Vec = Vec::with_capacity(len as usize); + for _ in 0..len { + tags.push(cursor.read_string()?); + } + Ok(Self::GameplayTagContainer(tags)) + } + fn read_guid(cursor: &mut R) -> Result { Ok(Self::Guid(cursor.read_guid()?)) } From df9847f497dd08af4ac4bd9d0312ea0b6c99a3de Mon Sep 17 00:00:00 2001 From: SabrePenguin Date: Sat, 19 Apr 2025 22:25:52 -0500 Subject: [PATCH 2/5] Fix tag number not appending to front --- src/properties/struct_property.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/properties/struct_property.rs b/src/properties/struct_property.rs index 4443a39..d762f2d 100644 --- a/src/properties/struct_property.rs +++ b/src/properties/struct_property.rs @@ -349,6 +349,7 @@ impl PropertyTrait for StructPropertyValue { } StructPropertyValue::GameplayTagContainer(tags) => { let mut len = tags.len(); + cursor.write_i32::(len as i32)?; for gameplaytag in tags { len += cursor.write_string(gameplaytag)?; } From a80d28bf0509005aa3901f310e99404d15559ae8 Mon Sep 17 00:00:00 2001 From: SabrePenguin Date: Sat, 19 Apr 2025 22:40:11 -0500 Subject: [PATCH 3/5] Add initial tests for tagcontainer --- resources/test/tagcontainer.sav | Bin 0 -> 1388 bytes tests/common/mod.rs | 2 + tests/common/tagcontainer.rs | 81 +++++++++++++++++++++++ tests/serde_tests/serde_json_template.rs | 22 ++++++ 4 files changed, 105 insertions(+) create mode 100644 resources/test/tagcontainer.sav create mode 100644 tests/common/tagcontainer.rs diff --git a/resources/test/tagcontainer.sav b/resources/test/tagcontainer.sav new file mode 100644 index 0000000000000000000000000000000000000000..ef40fe8b5f63ab6aed54bdc4f3778d2632e49d56 GIT binary patch literal 1388 zcmZ<{a|~u;U|`?^5-beT3?McGgD?YC^onKLj0g-w9?H&4^@ zNay7WB03>G0q2#cu>r+?Rek-_>{J#I@oeQzBi#l6U4UZCe_wKV>f_;E8fCFzo~K_2 zJ5Wqhd1={JS7lDe8|!A=$kIR03KV0{+!Mdf;Y4W5$Min?kN@Ksfnt6&&zqJyD;pmb z&ffBw*Kj&eh(YOU$eextYAf8>6{lQi+LEXZ6nkQHV*{^$r~LN1^J^A){WaqPifK3> zdl>Aiv#6~vXK~M7@f46=n}c!YzdfF?eQ06WT34v0#sU<3o3Y`^OQ$JcxNjLQa@_5v zrvVhRFZpx6!DWNElt*)0EDqX$+)@#=@X$Z6=llOp5YGwyE*lIAzblK^R@w%|?w*(H`|OHmu_{m%Q!-G0%_PWA1xJRNyJVr>$#2`&C9YwleZTXpUDD_(t| zSVl6(^9Ud1>;h@amWgp{Vjy+b_WYk4!RYVVB&7JLW5pyJP#mqfur%c?bKqJ#v!n zj!_KW^3SD%6{MG~_2H&N=Zl?ofAL$&zN@UAPJoQ@_EN zKh=YCS?|n=bC&Q)OaLYL=kw|dtvolpG@7`%gT2v0ngb{nV3ZNE-eYFNv>7M5xBp!G z8z{se>C59>;2BbwIXkoc>4pjSL1DGm=-(<4pQ*vBaar5$UNjN_+0plKy>f)#L!Y2S ziM`wR1@GhrioM#Nw8YA9<`?-l2WM`2sL}*Ve|!IK)f4bt!`T1Xtnt>;$;P0(;BPuN zK;QG(w@s~{%Vm;nKv{;t;dPkT9l@^xbtac5JcGKZnYjl zKy__DDnsRctR`1;>}uBEnV1Yx7qm}5k=r5o)}ElLTV@;N+srf)ah#ip1Q4oK(Hw#IjWP#N1Q{P+*26riY{!moR_=EV!ho zG`S?8D8C@JsHBo%4NwRKM1dHjz91*D5~$ocKd&S)GcUCWEQvyZT&oVm&KZeCiOD6Y zMS6|}1*t%GUUI6Qe_3i#Vor{8eolUoo_l^y3Iixp6IL3Yky(<;pn^-STTW?O8pP0` d)D#9#p@7v)By~{Q1r{sO9fI43;+ Date: Sun, 20 Apr 2025 11:52:19 -0500 Subject: [PATCH 4/5] Add remaining tests --- tests/gvas.rs | 5 +++++ tests/serde_tests/serde_json_round_trip.rs | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/tests/gvas.rs b/tests/gvas.rs index 62b487c..7c0890c 100644 --- a/tests/gvas.rs +++ b/tests/gvas.rs @@ -137,6 +137,11 @@ fn slot3() { test_gvas_file(SLOT3_PATH); } +#[test] +fn tagcontainer() { + test_gvas_file(TAGCONTAINER_PATH); +} + #[test] fn text_property_noarray() { test_gvas_file(TEXT_PROPERTY_NOARRAY); diff --git a/tests/serde_tests/serde_json_round_trip.rs b/tests/serde_tests/serde_json_round_trip.rs index 3fe9a74..4179d47 100644 --- a/tests/serde_tests/serde_json_round_trip.rs +++ b/tests/serde_tests/serde_json_round_trip.rs @@ -90,6 +90,11 @@ fn serde_slot3() { test_file(SLOT3_PATH); } +#[test] +fn serde_tagcontainer() { + test_file(TAGCONTAINER_PATH); +} + #[ignore] // This test takes ~5 seconds to run #[test] fn serde_transform() { From 991003efbdda89a81f8a2f454f543c592a6a249c Mon Sep 17 00:00:00 2001 From: SabrePenguin Date: Sun, 20 Apr 2025 21:51:31 -0500 Subject: [PATCH 5/5] Fix cargo fmt --- tests/common/mod.rs | 4 ++-- tests/common/tagcontainer.rs | 2 +- tests/serde_tests/serde_json_template.rs | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 396d384..74a4051 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -8,8 +8,8 @@ pub mod profile0; pub mod regression; pub mod saveslot3; pub mod slot1; -pub mod vector2d; pub mod tagcontainer; +pub mod vector2d; pub const ASSERT_FAILED_PATH: &str = "resources/test/assert_failed.sav"; pub const COMPONENT8_PATH: &str = "resources/test/component8.sav"; @@ -31,4 +31,4 @@ pub const SLOT3_PATH: &str = "resources/test/Slot3.sav"; pub const TEXT_PROPERTY_NOARRAY: &str = "resources/test/text_property_noarray.bin"; pub const TRANSFORM_PATH: &str = "resources/test/transform.sav"; pub const VECTOR2D_PATH: &str = "resources/test/vector2d.sav"; -pub const TAGCONTAINER_PATH: &str = "resources/test/tagcontainer.sav"; \ No newline at end of file +pub const TAGCONTAINER_PATH: &str = "resources/test/tagcontainer.sav"; diff --git a/tests/common/tagcontainer.rs b/tests/common/tagcontainer.rs index 04bf530..4c8b907 100644 --- a/tests/common/tagcontainer.rs +++ b/tests/common/tagcontainer.rs @@ -78,4 +78,4 @@ pub const TAGCONTAINER_JSON: &str = r#"{ ] } } -}"#; \ No newline at end of file +}"#; diff --git a/tests/serde_tests/serde_json_template.rs b/tests/serde_tests/serde_json_template.rs index e1f80ef..18ff46f 100644 --- a/tests/serde_tests/serde_json_template.rs +++ b/tests/serde_tests/serde_json_template.rs @@ -104,7 +104,7 @@ fn file_saveslot_03() { #[test] fn file_tagcontainer() { - file(TAGCONTAINER_PATH,tagcontainer::TAGCONTAINER_JSON) + file(TAGCONTAINER_PATH, tagcontainer::TAGCONTAINER_JSON) } #[test] @@ -1589,7 +1589,7 @@ fn struct_gameplaytag() { serde_json( &Property::from(StructPropertyValue::GameplayTagContainer(vec![ String::from("Gameplaytag.One"), - String::from("Gameplaytag.Two") + String::from("Gameplaytag.Two"), ])), r#"{ "type": "StructPropertyValue", @@ -1597,7 +1597,7 @@ fn struct_gameplaytag() { "Gameplaytag.One", "Gameplaytag.Two" ] -}"# +}"#, ) }