feat: Handle file variants
This commit is contained in:
parent
764d9c00f2
commit
f94a8c8731
2 changed files with 49 additions and 34 deletions
|
@ -237,8 +237,8 @@ where
|
||||||
Box::new(bundle.files().iter())
|
Box::new(bundle.files().iter())
|
||||||
} else {
|
} else {
|
||||||
let iter = bundle.files().iter().filter(|file| {
|
let iter = bundle.files().iter().filter(|file| {
|
||||||
let name = file.name(false);
|
let name = file.name(false, None);
|
||||||
let decompiled_name = file.name(true);
|
let decompiled_name = file.name(true, None);
|
||||||
|
|
||||||
// When there is no `includes`, all files are included
|
// When there is no `includes`, all files are included
|
||||||
let is_included = includes.is_empty()
|
let is_included = includes.is_empty()
|
||||||
|
@ -275,7 +275,7 @@ where
|
||||||
let mut tasks = Vec::with_capacity(bundle.files().len());
|
let mut tasks = Vec::with_capacity(bundle.files().len());
|
||||||
|
|
||||||
for file in files {
|
for file in files {
|
||||||
let name = file.name(options.decompile);
|
let name = file.name(options.decompile, None);
|
||||||
let data = if options.decompile {
|
let data = if options.decompile {
|
||||||
file.decompiled(ctx.clone()).await
|
file.decompiled(ctx.clone()).await
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -323,6 +323,7 @@ impl From<BundleFileType> for Murmur64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BundleFileHeader {
|
struct BundleFileHeader {
|
||||||
|
variant: u32,
|
||||||
size: usize,
|
size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,18 +333,10 @@ impl BundleFileHeader {
|
||||||
where
|
where
|
||||||
R: AsyncRead + AsyncSeek + std::marker::Unpin,
|
R: AsyncRead + AsyncSeek + std::marker::Unpin,
|
||||||
{
|
{
|
||||||
// NOTE: One of these must be the version number, or any kind of
|
let variant = read_u32(r).await?;
|
||||||
// identifier between the different file entries.
|
skip_u8(r, 0).await?;
|
||||||
// Back in VT2 days, these different 'files' were used to separate
|
|
||||||
// versions, e.g. different languages for the same `.strings` file.
|
|
||||||
skip_u32(r, 0).await?;
|
|
||||||
skip_u32(r, 0).await?;
|
|
||||||
skip_u32(r, 0).await?;
|
|
||||||
|
|
||||||
let size_1 = read_u32(r).await? as usize;
|
let size_1 = read_u32(r).await? as usize;
|
||||||
|
|
||||||
skip_u8(r, 1).await?;
|
skip_u8(r, 1).await?;
|
||||||
|
|
||||||
let size_2 = read_u32(r).await? as usize;
|
let size_2 = read_u32(r).await? as usize;
|
||||||
|
|
||||||
tracing::debug!(size_1, size_2);
|
tracing::debug!(size_1, size_2);
|
||||||
|
@ -355,7 +348,7 @@ impl BundleFileHeader {
|
||||||
size_1
|
size_1
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Self { size })
|
Ok(Self { size, variant })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,12 +389,13 @@ impl BundleFile {
|
||||||
let hash = Murmur64::from(read_u64(r).await?);
|
let hash = Murmur64::from(read_u64(r).await?);
|
||||||
let name = lookup_hash(ctx, hash, HashGroup::Filename).await;
|
let name = lookup_hash(ctx, hash, HashGroup::Filename).await;
|
||||||
|
|
||||||
let header_count = read_u8(r)
|
let header_count = read_u32(r)
|
||||||
.await
|
.await
|
||||||
.with_section(|| format!("{}.{}", name, file_type.ext_name()).header("File:"))?;
|
.with_section(|| format!("{}.{}", name, file_type.ext_name()).header("File:"))?;
|
||||||
let header_count = header_count as usize;
|
let header_count = header_count as usize;
|
||||||
|
|
||||||
let mut headers = Vec::with_capacity(header_count);
|
let mut headers = Vec::with_capacity(header_count);
|
||||||
|
skip_u32(r, 0).await?;
|
||||||
|
|
||||||
for _ in 0..header_count {
|
for _ in 0..header_count {
|
||||||
let header = BundleFileHeader::read(r)
|
let header = BundleFileHeader::read(r)
|
||||||
|
@ -438,19 +432,18 @@ impl BundleFile {
|
||||||
write_u64(w, *self.hash).await?;
|
write_u64(w, *self.hash).await?;
|
||||||
|
|
||||||
let header_count = self.variants.len();
|
let header_count = self.variants.len();
|
||||||
write_u8(w, header_count as u8).await?;
|
write_u32(w, header_count as u32).await?;
|
||||||
|
// TODO: Unknown what this is
|
||||||
|
write_u32(w, 0).await?;
|
||||||
|
|
||||||
for variant in self.variants.iter() {
|
for variant in self.variants.iter() {
|
||||||
// TODO: Unknown what these are
|
// TODO: Unknown what these are
|
||||||
write_u32(w, 0).await?;
|
write_u32(w, variant.header.variant).await?;
|
||||||
write_u32(w, 0).await?;
|
// TODO: Unknown what this is
|
||||||
write_u32(w, 0).await?;
|
write_u8(w, 0).await?;
|
||||||
|
|
||||||
write_u32(w, variant.data.len() as u32).await?;
|
write_u32(w, variant.data.len() as u32).await?;
|
||||||
|
|
||||||
// TODO: Unknown what this is
|
// TODO: Unknown what this is
|
||||||
write_u8(w, 1).await?;
|
write_u8(w, 1).await?;
|
||||||
|
|
||||||
// TODO: The previous size value and this one are somehow connected,
|
// TODO: The previous size value and this one are somehow connected,
|
||||||
// but so far it is unknown how
|
// but so far it is unknown how
|
||||||
write_u32(w, 0).await?;
|
write_u32(w, 0).await?;
|
||||||
|
@ -467,12 +460,22 @@ impl BundleFile {
|
||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(&self, decompiled: bool) -> String {
|
pub fn name(&self, decompiled: bool, variant: Option<u32>) -> String {
|
||||||
if decompiled {
|
let mut s = self.name.clone();
|
||||||
format!("{}.{}", self.name, self.file_type.decompiled_ext_name())
|
s.push('.');
|
||||||
} else {
|
|
||||||
format!("{}.{}", self.name, self.file_type.ext_name())
|
if let Some(variant) = variant {
|
||||||
|
s.push_str(&variant.to_string());
|
||||||
|
s.push('.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if decompiled {
|
||||||
|
s.push_str(&self.file_type.decompiled_ext_name());
|
||||||
|
} else {
|
||||||
|
s.push_str(&self.file_type.ext_name());
|
||||||
|
}
|
||||||
|
|
||||||
|
s
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn matches_name<S>(&self, name: S) -> bool
|
pub fn matches_name<S>(&self, name: S) -> bool
|
||||||
|
@ -480,7 +483,7 @@ impl BundleFile {
|
||||||
S: AsRef<str>,
|
S: AsRef<str>,
|
||||||
{
|
{
|
||||||
let name = name.as_ref();
|
let name = name.as_ref();
|
||||||
self.name == name || self.name(false) == name || self.name(true) == name
|
self.name == name || self.name(false, None) == name || self.name(true, None) == name
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hash(&self) -> Murmur64 {
|
pub fn hash(&self) -> Murmur64 {
|
||||||
|
@ -503,9 +506,16 @@ impl BundleFile {
|
||||||
let files = self
|
let files = self
|
||||||
.variants
|
.variants
|
||||||
.iter()
|
.iter()
|
||||||
.map(|variant| UserFile {
|
.map(|variant| {
|
||||||
data: variant.data().to_vec(),
|
let name = if self.variants.len() > 1 {
|
||||||
name: Some(self.name(false)),
|
self.name(false, Some(variant.header.variant))
|
||||||
|
} else {
|
||||||
|
self.name(false, None)
|
||||||
|
};
|
||||||
|
UserFile {
|
||||||
|
data: variant.data().to_vec(),
|
||||||
|
name: Some(name),
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
@ -518,7 +528,7 @@ impl BundleFile {
|
||||||
|
|
||||||
if tracing::enabled!(tracing::Level::DEBUG) {
|
if tracing::enabled!(tracing::Level::DEBUG) {
|
||||||
tracing::debug!(
|
tracing::debug!(
|
||||||
name = self.name(true),
|
name = self.name(true, None),
|
||||||
variants = self.variants.len(),
|
variants = self.variants.len(),
|
||||||
"Attempting to decompile"
|
"Attempting to decompile"
|
||||||
);
|
);
|
||||||
|
@ -529,6 +539,11 @@ impl BundleFile {
|
||||||
|
|
||||||
async move {
|
async move {
|
||||||
let data = variant.data();
|
let data = variant.data();
|
||||||
|
let name = if self.variants.len() > 1 {
|
||||||
|
self.name(true, Some(variant.header.variant))
|
||||||
|
} else {
|
||||||
|
self.name(true, None)
|
||||||
|
};
|
||||||
|
|
||||||
let res = match file_type {
|
let res = match file_type {
|
||||||
BundleFileType::Lua => lua::decompile(ctx, data).await,
|
BundleFileType::Lua => lua::decompile(ctx, data).await,
|
||||||
|
@ -538,7 +553,7 @@ impl BundleFile {
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
tracing::debug!("Can't decompile, unknown file type");
|
tracing::debug!("Can't decompile, unknown file type");
|
||||||
Ok(vec![UserFile::with_name(data.to_vec(), self.name(true))])
|
Ok(vec![UserFile::with_name(data.to_vec(), name.clone())])
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -547,7 +562,7 @@ impl BundleFile {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let err = err
|
let err = err
|
||||||
.wrap_err("failed to decompile file")
|
.wrap_err("failed to decompile file")
|
||||||
.with_section(|| self.name(true).header("File:"));
|
.with_section(|| name.header("File:"));
|
||||||
tracing::error!("{:?}", err);
|
tracing::error!("{:?}", err);
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue