1use bitvec::{order::Lsb0, prelude::BitVec};
4use byteorder::LE;
5use lazy_static::lazy_static;
6
7use unreal_helpers::BitVecExt;
8
9use crate::custom_version::FAssetRegistryVersionType;
10use crate::error::{Error, RegistryError};
11use crate::flags::EDependencyProperty;
12use crate::reader::{archive_reader::ArchiveReader, archive_writer::ArchiveWriter};
13use crate::types::fname::FName;
14
15#[derive(Debug, Clone, Default)]
17pub struct AssetIdentifier {
18 pub package_name: Option<FName>,
20 pub primary_asset_type: Option<FName>,
22 pub object_name: Option<FName>,
24 pub value_name: Option<FName>,
26}
27
28type LoadedDependencyNodes = (Vec<DependsNode>, Vec<DependsNode>, BitVec<u32, Lsb0>);
29
30impl AssetIdentifier {
31 pub fn new<Reader: ArchiveReader>(asset: &mut Reader) -> Result<Self, Error> {
33 let field_bits = asset.read_u8()?;
34 let package_name = match (field_bits & (1 << 0)) != 0 {
35 true => Some(asset.read_fname()?),
36 false => None,
37 };
38
39 let primary_asset_type = match (field_bits & (1 << 1)) != 0 {
40 true => Some(asset.read_fname()?),
41 false => None,
42 };
43
44 let object_name = match (field_bits & (1 << 2)) != 0 {
45 true => Some(asset.read_fname()?),
46 false => None,
47 };
48
49 let value_name = match (field_bits & (1 << 3)) != 0 {
50 true => Some(asset.read_fname()?),
51 false => None,
52 };
53
54 Ok(Self {
55 package_name,
56 primary_asset_type,
57 object_name,
58 value_name,
59 })
60 }
61
62 pub fn write<Writer: ArchiveWriter>(&self, writer: &mut Writer) -> Result<(), Error> {
64 #[allow(clippy::identity_op)]
65 let field_bits = (self.package_name.is_some() as u8) << 0u8
66 | (self.primary_asset_type.is_some() as u8) << 1u8
67 | (self.object_name.is_some() as u8) << 2u8
68 | (self.value_name.is_some() as u8) << 3u8;
69
70 writer.write_u8(field_bits)?;
71 if let Some(package_name) = &self.package_name {
72 writer.write_fname(package_name)?;
73 }
74 if let Some(primary_asset_type) = &self.primary_asset_type {
75 writer.write_fname(primary_asset_type)?;
76 }
77 if let Some(object_name) = &self.object_name {
78 writer.write_fname(object_name)?;
79 }
80 if let Some(value_name) = &self.value_name {
81 writer.write_fname(value_name)?;
82 }
83 Ok(())
84 }
85}
86
87#[derive(Clone, Debug)]
89pub struct DependsNode {
90 pub identifier: AssetIdentifier,
92
93 pub hard_dependencies: Vec<DependsNode>,
95 pub soft_dependencies: Vec<DependsNode>,
97
98 pub name_dependencies: Vec<DependsNode>,
100
101 pub hard_manage_dependencies: Vec<DependsNode>,
103 pub soft_manage_dependencies: Vec<DependsNode>,
105
106 pub referencers: Vec<DependsNode>,
108
109 pub package_flags: Option<BitVec<u32, Lsb0>>,
111 pub manage_flags: Option<BitVec<u32, Lsb0>>,
113
114 index: i32,
116 version: FAssetRegistryVersionType,
118}
119
120#[allow(unused)]
121const PACKAGE_FLAG_WIDTH: i32 = 3;
122#[allow(unused)]
123const PACKAGE_FLAG_SET_WIDTH: i32 = 1 << PACKAGE_FLAG_WIDTH;
124#[allow(unused)]
125const MANAGE_FLAG_WIDTH: i32 = 1;
126const MANAGE_FLAG_SET_WIDTH: i32 = 1;
127
128lazy_static! {
129 static ref HARD_BIT: u8 = DependsNode::package_properties_to_byte(
130 EDependencyProperty::HARD | EDependencyProperty::GAME | EDependencyProperty::BUILD
131 );
132 static ref SOFT_BIT: u8 = DependsNode::package_properties_to_byte(
133 EDependencyProperty::GAME | EDependencyProperty::BUILD
134 );
135}
136
137#[allow(unused)]
138const HARD_MANAGE_BITS: u32 = 0x1;
139#[allow(unused)]
140const SOFT_MANAGE_BITS: u32 = 0x0;
141
142impl DependsNode {
143 #[allow(clippy::identity_op)] fn package_properties_to_byte(properties: EDependencyProperty) -> u8 {
146 (0x1 * (properties & EDependencyProperty::HARD).bits() as u8)
147 | (0x2 * (properties & EDependencyProperty::GAME).bits() as u8)
148 | (0x4 * (properties & EDependencyProperty::BUILD).bits() as u8)
149 }
150
151 fn read_dependencies<Reader: ArchiveReader>(
153 asset: &mut Reader,
154 preallocated_depends_node_buffer: &Vec<DependsNode>,
155 flag_set_width: i32,
156 ) -> Result<LoadedDependencyNodes, Error> {
157 let mut sort_indexes = Vec::new();
158 let mut pointer_dependencies = Vec::new();
159
160 let in_dependencies = asset.read_array(|asset: &mut Reader| Ok(asset.read_i32::<LE>()?))?;
161
162 let num_flag_bits = flag_set_width * in_dependencies.len() as i32;
163 let num_flag_words = (num_flag_bits + 31) / 32;
164 let in_flag_bits = match num_flag_words != 0 {
165 true => BitVec::from_vec(
166 asset.read_array_with_length(num_flag_words, |asset: &mut Reader| {
167 Ok(asset.read_u32::<LE>()?)
168 })?,
169 ),
170 false => BitVec::<u32, Lsb0>::new(),
171 };
172
173 for serialize_index in &in_dependencies {
174 if *serialize_index < 0
175 || preallocated_depends_node_buffer.len() <= *serialize_index as usize
176 {
177 return Err(RegistryError::InvalidIndex(*serialize_index).into());
178 }
179
180 let depends_node = &preallocated_depends_node_buffer[*serialize_index as usize];
181 pointer_dependencies.push(depends_node);
182 }
183
184 for i in 0..in_dependencies.len() {
185 sort_indexes.push(i as i32);
186 }
187
188 sort_indexes.sort_by(|a, b| {
189 let cmp =
190 pointer_dependencies[*a as usize].index - pointer_dependencies[*b as usize].index;
191
192 cmp.cmp(&0)
193 });
194
195 let mut hard_dependencies = Vec::new();
196 let mut soft_dependencies = Vec::new();
197
198 for index in &sort_indexes {
199 let node = pointer_dependencies[*index as usize];
200 let package_flags = node.package_flags.as_ref().ok_or_else(|| {
201 Error::invalid_file(
202 "No package flags on asset registry with version >= AddedDependencyFlags"
203 .to_string(),
204 )
205 })?;
206
207 if package_flags
208 .get(*HARD_BIT as usize)
209 .as_deref()
210 .copied()
211 .unwrap_or(false)
212 {
213 hard_dependencies.push(node.clone());
214 } else {
215 soft_dependencies.push(node.clone());
216 }
217 }
218
219 let mut out_flag_bits = BitVec::with_capacity(num_flag_bits as usize);
220 for write_index in 0..in_dependencies.len() as i32 {
221 let read_index = &sort_indexes[write_index as usize];
222
223 out_flag_bits.set_range_from_range(
224 write_index * flag_set_width,
225 flag_set_width,
226 &in_flag_bits,
227 read_index * flag_set_width,
228 );
229 }
230
231 Ok((hard_dependencies, soft_dependencies, out_flag_bits))
232 }
233
234 fn write_dependencies<Writer: ArchiveWriter>(
236 writer: &mut Writer,
237 flag_set_width: i32,
238 flags: &BitVec<u32, Lsb0>,
239 hard_dependencies: &Vec<DependsNode>,
240 soft_dependencies: &Vec<DependsNode>,
241 ) -> Result<(), Error> {
242 let dependencies_length = hard_dependencies.len() as i32 + soft_dependencies.len() as i32;
243 let mut out_flag_bits = BitVec::<u32, Lsb0>::new();
244
245 writer.write_i32::<LE>(dependencies_length)?;
246
247 for (i, hard_dependency) in hard_dependencies.iter().enumerate() {
248 writer.write_i32::<LE>(hard_dependency.index)?;
249
250 let index = out_flag_bits.len() as i32;
251 out_flag_bits.reserve(flag_set_width as usize);
252 out_flag_bits.set_range_from_range(
253 index,
254 flag_set_width,
255 flags,
256 i as i32 * flag_set_width,
257 );
258 }
259
260 let inital_soft_index = hard_dependencies.len() as i32;
261
262 for (i, soft_dependency) in soft_dependencies.iter().enumerate() {
263 writer.write_i32::<LE>(soft_dependency.index)?;
264
265 let index = out_flag_bits.len() as i32 + inital_soft_index;
266 out_flag_bits.reserve(flag_set_width as usize);
267 out_flag_bits.set_range_from_range(
268 index,
269 flag_set_width,
270 flags,
271 (i as i32 + inital_soft_index) * flag_set_width,
272 );
273 }
274
275 let bit_vec_size = ((out_flag_bits.len() + 31) / 32) as i32;
276 writer.write_i32::<LE>(bit_vec_size)?;
277
278 for byte in out_flag_bits.chunks(8).map(|chunk| {
279 let mut byte = 0u8;
280 for i in 0..8 {
281 if chunk[i] {
282 byte |= 1 << i;
283 }
284 }
285 byte
286 }) {
287 writer.write_u8(byte)?;
288 }
289
290 Ok(())
291 }
292
293 fn read_dependencies_no_flags<Reader: ArchiveReader>(
295 asset: &mut Reader,
296 preallocated_depends_node_buffer: &Vec<DependsNode>,
297 ) -> Result<Vec<DependsNode>, Error> {
298 let mut pointer_dependencies = Vec::new();
299 let in_dependencies = asset.read_array(|asset: &mut Reader| Ok(asset.read_i32::<LE>()?))?;
300
301 for serialize_index in &in_dependencies {
302 if *serialize_index < 0
303 || preallocated_depends_node_buffer.len() <= *serialize_index as usize
304 {
305 return Err(RegistryError::InvalidIndex(*serialize_index).into());
306 }
307
308 let depends_node = &preallocated_depends_node_buffer[*serialize_index as usize];
309 pointer_dependencies.push(depends_node);
310 }
311
312 let mut sort_indexes = Vec::new();
313
314 for i in 0..in_dependencies.len() as i32 {
315 sort_indexes.push(i);
316 }
317
318 sort_indexes.sort_by(|a, b| {
319 let cmp =
320 pointer_dependencies[*a as usize].index - pointer_dependencies[*b as usize].index;
321
322 cmp.cmp(&0)
323 });
324
325 let mut out_dependencies = Vec::with_capacity(in_dependencies.len());
326 for index in sort_indexes {
327 out_dependencies.push(pointer_dependencies[index as usize].clone());
328 }
329
330 Ok(out_dependencies)
331 }
332
333 fn write_dependencies_no_flags<Writer: ArchiveWriter>(
335 writer: &mut Writer,
336 dependencies: &Vec<DependsNode>,
337 ) -> Result<(), Error> {
338 writer.write_i32::<LE>(dependencies.len() as i32)?;
339 for dependency in dependencies {
340 writer.write_i32::<LE>(dependency.index)?;
341 }
342 Ok(())
343 }
344
345 pub fn new(index: i32, version: FAssetRegistryVersionType) -> Self {
347 Self {
348 identifier: AssetIdentifier::default(),
349 hard_dependencies: Vec::new(),
350 soft_dependencies: Vec::new(),
351 name_dependencies: Vec::new(),
352 hard_manage_dependencies: Vec::new(),
353 soft_manage_dependencies: Vec::new(),
354 referencers: Vec::new(),
355 package_flags: None,
356 manage_flags: None,
357 index,
358 version,
359 }
360 }
361
362 pub fn load_dependencies<Reader: ArchiveReader>(
364 &mut self,
365 asset: &mut Reader,
366 preallocated_depends_node_buffer: &Vec<DependsNode>,
367 ) -> Result<(), Error> {
368 let identifier = AssetIdentifier::new(asset)?;
369
370 let (hard_dependencies, soft_dependencies, package_flags) = Self::read_dependencies(
371 asset,
372 preallocated_depends_node_buffer,
373 PACKAGE_FLAG_SET_WIDTH,
374 )?;
375
376 let name_dependencies =
377 Self::read_dependencies_no_flags(asset, preallocated_depends_node_buffer)?;
378
379 let (hard_manage_dependencies, soft_manage_dependencies, manage_flags) =
380 Self::read_dependencies(
381 asset,
382 preallocated_depends_node_buffer,
383 MANAGE_FLAG_SET_WIDTH,
384 )?;
385
386 let referencers =
387 Self::read_dependencies_no_flags(asset, preallocated_depends_node_buffer)?;
388
389 self.identifier = identifier;
390
391 self.hard_dependencies = hard_dependencies;
392 self.soft_dependencies = soft_dependencies;
393
394 self.package_flags = Some(package_flags);
395 self.name_dependencies = name_dependencies;
396
397 self.hard_manage_dependencies = hard_manage_dependencies;
398 self.soft_manage_dependencies = soft_manage_dependencies;
399
400 self.manage_flags = Some(manage_flags);
401 self.referencers = referencers;
402
403 Ok(())
404 }
405
406 pub fn save_dependencies<Writer: ArchiveWriter>(
408 &self,
409 writer: &mut Writer,
410 ) -> Result<(), Error> {
411 self.identifier.write(writer)?;
412
413 let package_flags = self
414 .package_flags
415 .as_ref()
416 .ok_or_else(|| RegistryError::version("Package flags".to_string(), self.version))?;
417
418 Self::write_dependencies(
419 writer,
420 PACKAGE_FLAG_SET_WIDTH,
421 package_flags,
422 &self.hard_dependencies,
423 &self.soft_dependencies,
424 )?;
425
426 Self::write_dependencies_no_flags(writer, &self.name_dependencies)?;
427
428 let manage_flags = self
429 .manage_flags
430 .as_ref()
431 .ok_or_else(|| RegistryError::version("Manage Flags".to_string(), self.version))?;
432
433 Self::write_dependencies(
434 writer,
435 MANAGE_FLAG_SET_WIDTH,
436 manage_flags,
437 &self.hard_manage_dependencies,
438 &self.soft_manage_dependencies,
439 )?;
440
441 Self::write_dependencies_no_flags(writer, &self.referencers)?;
442
443 Ok(())
444 }
445
446 fn read_node_array<Reader: ArchiveReader>(
448 asset: &mut Reader,
449 preallocated_depends_node_buffer: &[DependsNode],
450 num: i32,
451 nodes: &mut Vec<DependsNode>,
452 ) -> Result<(), Error> {
453 for _ in 0..num {
454 let index = asset.read_i32::<LE>()?;
455 if index < 0 || nodes.len() <= index as usize {
456 return Err(RegistryError::InvalidIndex(index).into());
457 }
458
459 let depends_node = &preallocated_depends_node_buffer[index as usize];
460 nodes.push(depends_node.clone());
461 }
462
463 Ok(())
464 }
465
466 pub fn load_dependencies_before_flags<Reader: ArchiveReader>(
468 &mut self,
469 asset: &mut Reader,
470 preallocated_depends_node_buffer: &[DependsNode],
471 ) -> Result<(), Error> {
472 let identifier = AssetIdentifier::new(asset)?;
473
474 let num_hard = asset.read_i32::<LE>()?;
475 let num_soft = asset.read_i32::<LE>()?;
476 let num_name = asset.read_i32::<LE>()?;
477 let num_soft_manage = asset.read_i32::<LE>()?;
478 let num_hard_manage = match self.version >= FAssetRegistryVersionType::AddedHardManage {
479 true => asset.read_i32::<LE>()?,
480 false => 0,
481 };
482 let num_referencers = asset.read_i32::<LE>()?;
483
484 let mut name_dependencies = Vec::with_capacity(num_name as usize);
485 let mut referencers = Vec::with_capacity(num_referencers as usize);
486
487 Self::read_node_array(
488 asset,
489 preallocated_depends_node_buffer,
490 num_hard,
491 &mut self.hard_dependencies,
492 )?;
493 Self::read_node_array(
494 asset,
495 preallocated_depends_node_buffer,
496 num_soft,
497 &mut self.soft_dependencies,
498 )?;
499 Self::read_node_array(
500 asset,
501 preallocated_depends_node_buffer,
502 num_name,
503 &mut name_dependencies,
504 )?;
505 Self::read_node_array(
506 asset,
507 preallocated_depends_node_buffer,
508 num_soft_manage,
509 &mut self.soft_manage_dependencies,
510 )?;
511 Self::read_node_array(
512 asset,
513 preallocated_depends_node_buffer,
514 num_hard_manage,
515 &mut self.hard_manage_dependencies,
516 )?;
517 Self::read_node_array(
518 asset,
519 preallocated_depends_node_buffer,
520 num_referencers,
521 &mut referencers,
522 )?;
523
524 self.identifier = identifier;
525 self.name_dependencies = name_dependencies;
526 self.referencers = referencers;
527
528 self.package_flags = None;
529 self.manage_flags = None;
530 Ok(())
531 }
532
533 pub fn save_dependencies_before_flags<Writer: ArchiveWriter>(
535 &self,
536 writer: &mut Writer,
537 ) -> Result<(), Error> {
538 self.identifier.write(writer)?;
539
540 writer.write_i32::<LE>(self.hard_dependencies.len() as i32)?;
541 writer.write_i32::<LE>(self.soft_dependencies.len() as i32)?;
542 writer.write_i32::<LE>(self.name_dependencies.len() as i32)?;
543 writer.write_i32::<LE>(self.soft_manage_dependencies.len() as i32)?;
544 if self.version >= FAssetRegistryVersionType::AddedHardManage {
545 writer.write_i32::<LE>(self.hard_manage_dependencies.len() as i32)?;
546 }
547 writer.write_i32::<LE>(self.referencers.len() as i32)?;
548
549 for hard_dependency in &self.hard_dependencies {
550 writer.write_i32::<LE>(hard_dependency.index)?;
551 }
552
553 for soft_dependency in &self.soft_dependencies {
554 writer.write_i32::<LE>(soft_dependency.index)?;
555 }
556
557 for name_dependency in &self.name_dependencies {
558 writer.write_i32::<LE>(name_dependency.index)?;
559 }
560
561 for soft_manage_dependency in &self.soft_manage_dependencies {
562 writer.write_i32::<LE>(soft_manage_dependency.index)?;
563 }
564
565 if self.version >= FAssetRegistryVersionType::AddedHardManage {
566 for hard_manage_dependency in &self.hard_manage_dependencies {
567 writer.write_i32::<LE>(hard_manage_dependency.index)?;
568 }
569 }
570
571 for referencer in &self.referencers {
572 writer.write_i32::<LE>(referencer.index)?;
573 }
574
575 Ok(())
576 }
577}