diff --git a/src/main.rs b/src/main.rs
index 18dfbb9..5bc10f3 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -105,6 +105,24 @@ fn get_texture_refs(dom:&rbx_dom_weak::WeakDom) -> Vec<rbx_dom_weak::types::Ref>
     objects
 }
 
+fn get_dom<R:Read+Seek>(input:&mut R)->Result<rbx_dom_weak::WeakDom,String>{
+    let mut first_8=[0u8;8];
+    if let (Ok(()),Ok(()))=(std::io::Read::read_exact(input, &mut first_8),std::io::Seek::rewind(input)){
+        match &first_8[0..4]{
+            b"<rob"=>{
+                match &first_8[4..8]{
+                    b"lox!"=>rbx_binary::from_reader(input).map_err(|e|format!("{:?}",e)),
+                    b"lox "=>rbx_xml::from_reader(input,rbx_xml::DecodeOptions::default()).map_err(|e|format!("{:?}",e)),
+                    other=>Err(format!("Unknown Roblox file type {:?}",other)),
+                }
+            }
+            _=>Err("unsupported file type".to_owned()),
+        }
+    }else{
+        Err("peek failed".to_owned())
+    }
+}
+
 fn get_id() -> BoxResult<u32>{
     match std::fs::read_to_string("id"){
         Ok(id_file)=>Ok(id_file.parse::<u32>()?),
@@ -261,9 +279,9 @@ fn download_textures(paths: Vec<std::path::PathBuf>) -> BoxResult<()>{
     ];
     let mut texture_list=std::collections::HashSet::new();
     for path in paths {
-        let input = std::io::BufReader::new(std::fs::File::open(path.clone())?);
+        let mut input = std::io::BufReader::new(std::fs::File::open(path.clone())?);
 
-        match rbx_binary::from_reader(input){
+        match get_dom(&mut input){
             Ok(dom)=>{
                 let object_refs = get_texture_refs(&dom);
                 for &object_ref in object_refs.iter() {
@@ -391,9 +409,9 @@ fn scan() -> BoxResult<()>{
 
     for entry in std::fs::read_dir("maps/unprocessed")? {
         let file_thing=entry?;
-        let input = std::io::BufReader::new(std::fs::File::open(file_thing.path())?);
+        let mut input = std::io::BufReader::new(std::fs::File::open(file_thing.path())?);
 
-        let dom = rbx_binary::from_reader(input)?;
+        let dom = get_dom(&mut input)?;
 
         let script_refs = get_script_refs(&dom);
 
@@ -449,9 +467,9 @@ fn extract(paths: Vec<std::path::PathBuf>) -> BoxResult<()>{
 
     for path in paths {
         let file_name=path.file_name();
-        let input = std::io::BufReader::new(std::fs::File::open(&path)?);
+        let mut input = std::io::BufReader::new(std::fs::File::open(&path)?);
 
-        let dom = rbx_binary::from_reader(input)?;
+        let dom = get_dom(&mut input)?;
 
         let script_refs = get_script_refs(&dom);
 
@@ -484,8 +502,8 @@ fn replace() -> BoxResult<()>{
     for entry in std::fs::read_dir("maps/blocked")? {
         let file_thing=entry?;
 
-        let input = std::io::BufReader::new(std::fs::File::open(file_thing.path())?);
-        let mut dom = rbx_binary::from_reader(input)?;
+        let mut input = std::io::BufReader::new(std::fs::File::open(file_thing.path())?);
+        let mut dom = get_dom(&mut input)?;
 
         let script_refs = get_script_refs(&dom);
 
@@ -555,9 +573,9 @@ fn upload() -> BoxResult<()>{
     for entry in std::fs::read_dir("maps/passed")? {
         let file_thing=entry?;
         println!("map file: {:?}",file_thing.file_name());
-        let input = std::io::BufReader::new(std::fs::File::open(file_thing.path())?);
+        let mut input = std::io::BufReader::new(std::fs::File::open(file_thing.path())?);
 
-        let dom = rbx_binary::from_reader(input)?;
+        let dom = get_dom(&mut input)?;
         let (modelname,creator,displayname) = get_mapinfo(&dom)?;
 
         //Creator: [auto fill creator]
@@ -670,8 +688,8 @@ fn interactive() -> BoxResult<()>{
     'map_loop: for entry in std::fs::read_dir("maps/unprocessed")? {
         let file_thing=entry?;
         println!("processing map={:?}",file_thing.file_name());
-        let input = std::io::BufReader::new(std::fs::File::open(file_thing.path())?);
-        let mut dom = rbx_binary::from_reader(input)?;
+        let mut input = std::io::BufReader::new(std::fs::File::open(file_thing.path())?);
+        let mut dom = get_dom(&mut input)?;
 
         let script_refs = get_script_refs(&dom);