Skip to content

Implement UniqueId #256

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

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
ceb9aab
Implement UniqueId as a type
Dekkonot Mar 24, 2023
00862e3
Add UniqueId support for rbx_binary
Dekkonot Mar 24, 2023
2652351
Implement UniqueId for rbx_xml
Dekkonot Mar 24, 2023
b7cae0d
Enable yaml feature in rbx_xml
Dekkonot Mar 24, 2023
66c748c
Update test files
Dekkonot Mar 24, 2023
c007c23
Derive Eq for UniqueId
Dekkonot Mar 24, 2023
16e5eed
Update changelogs for rbx_types, rbx_xml, and rbx_binary
Dekkonot Mar 24, 2023
10daba0
Update test-files
Dekkonot Mar 30, 2023
d8ab1be
Implement generic interleaving read/write methods
Dekkonot May 8, 2023
ceea328
Swap (de)serialization of UniqueId to use methods for (de)interleaving
Dekkonot May 8, 2023
f544844
Update test-files to what it's meant to be
Dekkonot May 8, 2023
64b7076
Implement serde manually for UniqueId
Dekkonot May 10, 2023
18f8dba
Actually use `UniqueId` in text deserializer
Dekkonot May 10, 2023
acbcb93
Update snapshots with new serde implementation
Dekkonot May 10, 2023
0aad9e2
Document ZSTD compression and Bytecode data type in binary spec file …
Dekkonot Mar 30, 2023
84d1dfa
Release rbx_types v1.5.0
LPGhatguy Apr 22, 2023
8255445
Update database and release rbx_reflection_database 0.2.6+roblox-572
LPGhatguy Apr 22, 2023
7d4cdc9
Release rbx_binary v0.7.0
LPGhatguy Apr 22, 2023
4841077
Release rbx_xml v0.13.0
LPGhatguy Apr 22, 2023
7b8ece6
Fix support for empty Font tags in rbx_xml (#261)
Dekkonot Apr 25, 2023
f24c432
Fill out XML spec document (#247)
Dekkonot Apr 28, 2023
088d213
Add 'Compatibility' document (#262)
Dekkonot Apr 28, 2023
39e6bfb
Patch `MaterialService.Use2022Materials` (#259)
wackbyte Apr 29, 2023
11a93df
Update reflection database to v573
Dekkonot Apr 29, 2023
02a8f3e
Make Blockquotes more reasonably sized in doc site (#264)
Dekkonot May 1, 2023
eca438c
Include latest database and patches in snapshots
Dekkonot May 10, 2023
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
2 changes: 2 additions & 0 deletions rbx_binary/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
## Unreleased
* Added support for `Font` values. ([#248])
* Fixed the nondeterministic output of SSTR chunk when multiple shared strings are present. ([#254])
* Added support for `UniqueId` values. ([#256])

[#248]: https://github.com/rojo-rbx/rbx-dom/pull/248
[#254]: https://github.com/rojo-rbx/rbx-dom/pull/254
[#256]: https://github.com/rojo-rbx/rbx-dom/pull/256

## 0.6.6 (2022-06-29)
* Fixed unserialized properties getting deserialized, like `BasePart.MaterialVariant`. ([#230])
Expand Down
14 changes: 14 additions & 0 deletions rbx_binary/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,20 @@ pub trait RbxReadExt: Read {
Ok(f64::from_le_bytes(bytes))
}

fn read_be_u32(&mut self) -> io::Result<u32> {
let mut bytes = [0; 4];
self.read_exact(&mut bytes)?;

Ok(u32::from_be_bytes(bytes))
}

fn read_be_i64(&mut self) -> io::Result<i64> {
let mut bytes = [0; 8];
self.read_exact(&mut bytes)?;

Ok(i64::from_be_bytes(bytes))
}

fn read_u8(&mut self) -> io::Result<u8> {
let mut buffer = [0u8];
self.read_exact(&mut buffer)?;
Expand Down
39 changes: 37 additions & 2 deletions rbx_binary/src/deserializer/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use rbx_dom_weak::{
Attributes, Axes, BinaryString, BrickColor, CFrame, Color3, Color3uint8, ColorSequence,
ColorSequenceKeypoint, Content, CustomPhysicalProperties, Enum, Faces, Font, FontStyle,
FontWeight, Matrix3, NumberRange, NumberSequence, NumberSequenceKeypoint,
PhysicalProperties, Ray, Rect, Ref, SharedString, Tags, UDim, UDim2, Variant, VariantType,
Vector2, Vector3, Vector3int16,
PhysicalProperties, Ray, Rect, Ref, SharedString, Tags, UDim, UDim2, UniqueId, Variant,
VariantType, Vector2, Vector3, Vector3int16,
},
InstanceBuilder, WeakDom,
};
Expand Down Expand Up @@ -1224,6 +1224,41 @@ impl<'a, R: Read> DeserializerState<'a, R> {
});
}
},
Type::UniqueId => match canonical_type {
VariantType::UniqueId => {
// This is technically inefficient but memory is cheap
// and we can optimize it later.
let n = type_info.referents.len();
let mut value = Vec::with_capacity(16);
let mut blob = vec![0; 16 * n];

chunk.read_exact(&mut blob)?;
for (x, referent) in (0..n).zip(&type_info.referents) {
for y in 0..16 {
value.push(blob[x + y * n]);
}
let mut value_ref = value.as_slice();
let instance = self.instances_by_ref.get_mut(referent).unwrap();
instance.builder.add_property(
&canonical_name,
UniqueId::new(
value_ref.read_be_u32()?,
value_ref.read_be_u32()?,
value_ref.read_be_i64()?.rotate_right(1),
),
);
value.clear();
}
}
invalid_type => {
return Err(InnerError::PropTypeMismatch {
type_name: type_info.type_name.clone(),
prop_name,
valid_type_names: "UniqueId",
actual_type_name: format!("{:?}", invalid_type),
});
}
},
}

Ok(())
Expand Down
24 changes: 23 additions & 1 deletion rbx_binary/src/serializer/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use rbx_dom_weak::{
Attributes, Axes, BinaryString, BrickColor, CFrame, Color3, Color3uint8, ColorSequence,
ColorSequenceKeypoint, Content, Enum, Faces, Font, Matrix3, NumberRange, NumberSequence,
NumberSequenceKeypoint, PhysicalProperties, Ray, Rect, Ref, SharedString, Tags, UDim,
UDim2, Variant, VariantType, Vector2, Vector3, Vector3int16,
UDim2, UniqueId, Variant, VariantType, Vector2, Vector3, Vector3int16,
},
Instance, WeakDom,
};
Expand Down Expand Up @@ -1112,6 +1112,27 @@ impl<'dom, W: Write> SerializerState<'dom, W> {
chunk.write_u8(Type::Bool as u8)?;
chunk.write_all(bools.as_slice())?;
}
Type::UniqueId => {
let mut blob = vec![0; values.len() * 16];
let mut bytes = Vec::with_capacity(16);

for (i, rbx_value) in values {
if let Variant::UniqueId(value) = rbx_value.as_ref() {
bytes.extend_from_slice(&value.index().to_be_bytes());
bytes.extend_from_slice(&value.time().to_be_bytes());
bytes.extend_from_slice(
&value.random().rotate_left(1).to_be_bytes(),
);
for (y, byte) in (0..16).zip(&bytes) {
blob[y + i * 16] = *byte;
}
} else {
return type_mismatch(i, &rbx_value, "UniqueId");
}
}

chunk.write_all(&blob)?;
}
}

chunk.dump(&mut self.output)?;
Expand Down Expand Up @@ -1251,6 +1272,7 @@ impl<'dom, W: Write> SerializerState<'dom, W> {
VariantType::Tags => Variant::Tags(Tags::new()),
VariantType::Content => Variant::Content(Content::new()),
VariantType::Attributes => Variant::Attributes(Attributes::new()),
VariantType::UniqueId => Variant::UniqueId(UniqueId::now().unwrap()),
VariantType::Font => Variant::Font(Font::default()),
_ => return None,
})
Expand Down
1 change: 1 addition & 0 deletions rbx_binary/src/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod models;
mod places;
mod serializer;
mod util;
29 changes: 29 additions & 0 deletions rbx_binary/src/tests/places.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use std::path::PathBuf;

use heck::ToKebabCase;

use super::util::run_model_base_suite;

macro_rules! place_tests {
($($test_name: ident,)*) => {
$(
#[test]
fn $test_name() {
let _ = env_logger::try_init();

let mut test_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
assert!(test_path.pop());
test_path.push("test-files");
test_path.push("places");
test_path.push(stringify!($test_name).to_kebab_case());
test_path.push("binary.rbxl");

run_model_base_suite(test_path);
}
)*
};
}

place_tests! {
baseplate_566,
}
Loading