diff --git a/server/src/rbx_session.rs b/server/src/rbx_session.rs
index 470515cc..13342379 100644
--- a/server/src/rbx_session.rs
+++ b/server/src/rbx_session.rs
@@ -9,14 +9,14 @@ use std::{
use failure::Fail;
-use rbx_tree::{RbxTree, RbxValue, RbxId};
+use rbx_tree::{RbxTree, RbxInstance, RbxValue, RbxId};
use crate::{
project::{Project, ProjectNode, InstanceProjectNodeMetadata},
message_queue::MessageQueue,
imfs::{Imfs, ImfsItem, ImfsFile},
path_map::PathMap,
- rbx_snapshot::{RbxSnapshotInstance, InstanceChanges, reify_root, reconcile_subtree},
+ rbx_snapshot::{RbxSnapshotInstance, InstanceChanges, snapshot_from_tree, reify_root, reconcile_subtree},
};
const INIT_SCRIPT: &str = "init.lua";
@@ -235,6 +235,8 @@ enum FileType {
ClientScript,
StringValue,
LocalizationTable,
+ XmlModel,
+ BinaryModel,
}
fn get_trailing<'a>(input: &'a str, trailer: &str) -> Option<&'a str> {
@@ -247,21 +249,25 @@ fn get_trailing<'a>(input: &'a str, trailer: &str) -> Option<&'a str> {
}
fn classify_file(file: &ImfsFile) -> Option<(&str, FileType)> {
+ static EXTENSIONS_TO_TYPES: &[(&str, FileType)] = &[
+ (".server.lua", FileType::ServerScript),
+ (".client.lua", FileType::ClientScript),
+ (".lua", FileType::ModuleScript),
+ (".csv", FileType::LocalizationTable),
+ (".txt", FileType::StringValue),
+ (".rbxmx", FileType::XmlModel),
+ (".rbxm", FileType::BinaryModel),
+ ];
+
let file_name = file.path.file_name()?.to_str()?;
- if let Some(instance_name) = get_trailing(file_name, ".server.lua") {
- Some((instance_name, FileType::ServerScript))
- } else if let Some(instance_name) = get_trailing(file_name, ".client.lua") {
- Some((instance_name, FileType::ClientScript))
- } else if let Some(instance_name) = get_trailing(file_name, ".lua") {
- Some((instance_name, FileType::ModuleScript))
- } else if let Some(instance_name) = get_trailing(file_name, ".csv") {
- Some((instance_name, FileType::LocalizationTable))
- } else if let Some(instance_name) = get_trailing(file_name, ".txt") {
- Some((instance_name, FileType::StringValue))
- } else {
- None
+ for (extension, file_type) in EXTENSIONS_TO_TYPES {
+ if let Some(instance_name) = get_trailing(file_name, extension) {
+ return Some((instance_name, *file_type))
+ }
}
+
+ None
}
#[derive(Debug, Serialize, Deserialize)]
@@ -307,6 +313,16 @@ enum SnapshotError {
inner: str::Utf8Error,
path: PathBuf,
},
+
+ XmlModelDecodeError {
+ inner: rbx_xml::DecodeError,
+ path: PathBuf,
+ },
+
+ BinaryModelDecodeError {
+ inner: rbx_binary::DecodeError,
+ path: PathBuf,
+ },
}
impl fmt::Display for SnapshotError {
@@ -316,10 +332,78 @@ impl fmt::Display for SnapshotError {
SnapshotError::Utf8Error { inner, path } => {
write!(output, "Invalid UTF-8: {} in path {}", inner, path.display())
},
+ SnapshotError::XmlModelDecodeError { inner, path } => {
+ write!(output, "Malformed rbxmx model: {:?} in path {}", inner, path.display())
+ },
+ SnapshotError::BinaryModelDecodeError { inner, path } => {
+ write!(output, "Malformed rbxm model: {:?} in path {}", inner, path.display())
+ },
}
}
}
+fn snapshot_xml_model<'a>(
+ instance_name: Cow<'a, str>,
+ file: &ImfsFile,
+) -> Result