internal async Task ReadExportTableEntry(ByteArrayReader reader, DomainHeader header) { TypeReference = reader.ReadInt32(); ParentReference = reader.ReadInt32(); OwnerReference = reader.ReadInt32(); NameTableIndex.ReadNameTableIndex(reader, header); ArchetypeReference = reader.ReadInt32(); FlagsHigh = reader.ReadUInt32(); FlagsLow = reader.ReadUInt32(); SerialDataSize = reader.ReadInt32(); SerialDataOffset = reader.ReadInt32(); ExportFlags = reader.ReadUInt32(); NetObjectCount = reader.ReadInt32(); Guid = await reader.ReadBytes(16); Unknown1 = reader.ReadUInt32(); Unknown2 = await reader.ReadBytes(sizeof(uint) * NetObjectCount); }
public async Task<int> BuildCompressedChunkHeader(ByteArrayReader reader, uint flags) { Signature = Signatures.Signature; BlockSize = 0x00020000; CompressedSize = 0; UncompressedSize = reader.Remaining; int blockCount = (reader.Remaining + BlockSize - 1) / BlockSize; int builderSize = 0; Blocks.Clear(); for(int i = 0; i < blockCount; ++i) { DomainCompressedChunkBlock block = new DomainCompressedChunkBlock(); ByteArrayReader uncompressed = await reader.ReadByteArray(Math.Min(BlockSize, reader.Remaining)); builderSize += await block.BuildCompressedChunkBlockData(uncompressed); CompressedSize += block.CompressedSize; Blocks.Add(block); } builderSize += sizeof(uint) + sizeof(int) * 3; return builderSize; }
public async Task ReadCompressedChunkHeader(ByteArrayReader reader, uint flags, int uncompressedSize, int compressedSize) { if (flags > 0) { Signature = reader.ReadUInt32(); if (Signature != Signatures.Signature) throw new Exception("Compressed Header Signature not found."); BlockSize = reader.ReadInt32(); CompressedSize = reader.ReadInt32(); UncompressedSize = reader.ReadInt32(); Blocks.Clear(); int blockCount = (UncompressedSize + BlockSize - 1) / BlockSize; for(int i = 0; i < blockCount; ++i) { DomainCompressedChunkBlock block = new DomainCompressedChunkBlock(); block.ReadCompressedChunkBlock(reader); Blocks.Add(block); } } else { Blocks = new List<DomainCompressedChunkBlock> { new DomainCompressedChunkBlock { UncompressedSize = uncompressedSize, CompressedSize = compressedSize } }; } foreach(DomainCompressedChunkBlock block in Blocks) await block.ReadCompressedChunkBlockData(reader); }
public override async Task ReadDomainObject(ByteArrayReader reader, DomainHeader header, DomainExportTableEntry export, bool skipProperties, bool skipParse) { ArchetypeObjectReference = reader.ReadInt32(); ArchetypeObjectNameIndex = header.GetObjectTableEntry(ArchetypeObjectReference)?.NameTableIndex; await base.ReadDomainObject(reader, header, export, skipProperties, skipParse); }
public virtual void SetPropertyValue(object value) { ByteArrayReader reader = value as ByteArrayReader; if (reader == null) return; DataReader = reader; }
public virtual async Task ReadDomainObject(ByteArrayReader reader, DomainHeader header, DomainExportTableEntry export, bool skipProperties, bool skipParse) { if (!skipProperties) await PropertyHeader.ReadPropertyHeader(reader, header); AdditionalDataOffset = export.SerialDataOffset + reader.CurrentOffset; AdditionalDataReader = await reader.Splice(); }
public void ReadNameTableIndex(ByteArrayReader reader, DomainHeader header) { Index = reader.ReadInt32(); Numeric = reader.ReadInt32(); if (Index < 0 || Index > header.NameTable.Count) throw new ArgumentOutOfRangeException(nameof(Index), $"Index ({Index:X8}) is out of range of the NameTable size."); Name = Numeric > 0 ? $"{header.NameTable[Index].Name.String}_{Numeric - 1}" : $"{header.NameTable[Index].Name.String}"; }
public override async Task ReadDomainObject(ByteArrayReader reader, DomainHeader header, DomainExportTableEntry export, bool skipProperties, bool skipParse) { await base.ReadDomainObject(reader, header, export, skipProperties, skipParse); if (skipParse) return; Unknown1 = await reader.ReadBytes(sizeof(uint) * 3); CompressedChunkOffset = reader.ReadInt32(); }
public async Task<ByteArrayReader> ReadByteArray(int Length) { if (index + Length < 0 || index + Length > data.Length) throw new ArgumentOutOfRangeException(nameof(Length), "Index + Length is out of the bounds of the byte array."); ByteArrayReader reader = new ByteArrayReader(); reader.Initialize(await ReadBytes(Length), 0); return reader; }
protected async Task ProcessCompressedBulkData(ByteArrayReader reader, Func<DomainCompressedChunkBulkData, Task> chunkHandler) { DomainCompressedChunkBulkData compressedChunk = new DomainCompressedChunkBulkData(); // CompressedChunks.Add(compressedChunk); await compressedChunk.ReadCompressedChunk(reader); await chunkHandler(compressedChunk); }
public async Task ReadImportTableEntry(ByteArrayReader reader, DomainHeader header) { await Task.Run(() => PackageNameIndex.ReadNameTableIndex(reader, header)); await Task.Run(() => TypeNameIndex.ReadNameTableIndex(reader, header)); OwnerReference = reader.ReadInt32(); await Task.Run(() => NameTableIndex.ReadNameTableIndex(reader, header)); }
public ByteArrayReader Branch(int Offset) { ByteArrayReader reader = new ByteArrayReader(); if (Offset < 0 || Offset > data.Length) throw new ArgumentOutOfRangeException(nameof(Offset), "Index value is outside the bounds of the byte array."); reader.Initialize(data, Offset); return reader; }
protected async Task<int> ProcessUncompressedBulkData(ByteArrayReader reader, BulkDataCompressionTypes compressionFlags) { DomainCompressedChunkBulkData compressedChunk = new DomainCompressedChunkBulkData(); CompressedChunks.Add(compressedChunk); int builderSize = await compressedChunk.BuildCompressedChunk(reader, compressionFlags); return builderSize; }
public static ByteArrayReader CreateNew(byte[] Data, int Index) { ByteArrayReader reader = new ByteArrayReader(); if (Data == null) Data = new byte[0]; if (Index < 0 || Index > Data.Length) throw new ArgumentOutOfRangeException(nameof(Index), "Index value is outside the bounds of the byte array."); reader.Initialize(Data, Index); return reader; }
public virtual async Task ReadCompressedChunk(ByteArrayReader reader) { UncompressedOffset = reader.ReadInt32(); UncompressedSize = reader.ReadInt32(); CompressedOffset = reader.ReadInt32(); CompressedSize = reader.ReadInt32(); Header = new DomainCompressedChunkHeader(); await Header.ReadCompressedChunkHeader(reader.Branch(CompressedOffset), 1, UncompressedSize, CompressedSize); }
public async Task<int> BuildCompressedChunkBlockData(ByteArrayReader reader) { UncompressedSize = reader.Remaining; byte[] compressed = await reader.Compress(); CompressedData = ByteArrayReader.CreateNew(compressed, 0); await CompressedData.Encrypt(); // TODO: Fix this to use the flag CompressedSize = CompressedData.Remaining; return CompressedSize + sizeof(int) * 2; }
public override async Task ReadDomainObject(ByteArrayReader reader, DomainHeader header, DomainExportTableEntry export, bool skipProperties, bool skipParse) { await base.ReadDomainObject(reader, header, export, skipProperties, skipParse); if (skipParse) return; await ProcessCompressedBulkData(reader, async bulkChunk => { byte[] bik = (await bulkChunk.DecompressChunk(0))?.GetBytes(); if (bik == null || bik.Length == 0) return; Movie = bik; }); }
public DomainHeader(ByteArrayReader Reader) { reader = Reader; Group = new DomainString(); GenerationTable = new List<DomainGenerationTableEntry>(); CompressedChunks = new List<DomainCompressedChunk>(); NameTable = new List<DomainNameTableEntry>(); ExportTable = new List<DomainExportTableEntry>(); ImportTable = new List<DomainImportTableEntry>(); }
public async Task ReadProperty(ByteArrayReader reader, DomainHeader header) { await Task.Run(() => NameIndex.ReadNameTableIndex(reader, header)); if (NameIndex.Name == ObjectTypes.None.ToString()) return; await Task.Run(() => TypeNameIndex.ReadNameTableIndex(reader, header)); Size = reader.ReadInt32(); ArrayIndex = reader.ReadInt32(); Value = propertyValueFactory(); await Value.ReadPropertyValue(reader, Size, header); }
public override async Task ReadCompressedChunk(ByteArrayReader reader) { BulkDataFlags = reader.ReadUInt32(); UncompressedSize = reader.ReadInt32(); CompressedSize = reader.ReadInt32(); CompressedOffset = reader.ReadInt32(); if (((BulkDataCompressionTypes)BulkDataFlags & NothingToDo) > 0) return; Header = new DomainCompressedChunkHeader(); await Header.ReadCompressedChunkHeader(reader, BulkDataFlags, UncompressedSize, CompressedSize); }
internal async Task ReadPropertyHeader(ByteArrayReader reader, DomainHeader header) { TypeIndex = reader.ReadInt32(); do { DomainProperty property = new DomainProperty(); await property.ReadProperty(reader, header); Properties.Add(property); if (property.NameIndex.Name == ObjectTypes.None.ToString()) break; } while(true); }
public async Task<int> BuildCompressedChunk(ByteArrayReader reader, BulkDataCompressionTypes compressionFlags) { BulkDataFlags = (uint)compressionFlags; int builderSize = sizeof(uint) + sizeof(int) * 3; if ((compressionFlags & NothingToDo) > 0) return builderSize; reader.Seek(0); UncompressedSize = reader.Remaining; Header = new DomainCompressedChunkHeader(); builderSize += await Header.BuildCompressedChunkHeader(reader, BulkDataFlags); CompressedSize = builderSize - 16; return builderSize; }
public override async Task ReadDomainObject(ByteArrayReader reader, DomainHeader header, DomainExportTableEntry export, bool skipProperties, bool skipParse) { await base.ReadDomainObject(reader, header, export, skipProperties, skipParse); if (skipParse) return; bool done = false; do { await ProcessCompressedBulkData(reader, async bulkChunk => { byte[] ogg = (await bulkChunk.DecompressChunk(0))?.GetBytes(); if (ogg == null || ogg.Length == 0) { done = true; return; } Sounds.Add(ogg); }); } while(!done); }
public override async Task ReadDomainObject(ByteArrayReader reader, DomainHeader header, DomainExportTableEntry export, bool skipProperties, bool skipParse) { await base.ReadDomainObject(reader, header, export, skipProperties, skipParse); if (skipParse) return; MipMapsCount = reader.ReadInt32(); for(int i = 0; i < MipMapsCount; ++i) { await ProcessCompressedBulkData(reader, async bulkChunk => { DomainMipMap mip = new DomainMipMap { Width = reader.ReadInt32(), Height = reader.ReadInt32() }; if (mip.Width >= 4 || mip.Height >= 4) mip.ImageData = (await bulkChunk.DecompressChunk(0))?.GetBytes(); MipMaps.Add(mip); }); } Guid = await reader.ReadBytes(16); }
public async Task ReadString(ByteArrayReader reader) { Size = reader.ReadInt32(); if (Size == 0) { String = String.Empty; return; } if (Size < 0) { int size = -Size * 2; byte[] str = await reader.ReadBytes(size); String = Encoding.Unicode.GetString(str); } else { byte[] str = await reader.ReadBytes(Size - 1); reader.Skip(1); // NULL Terminator String = Encoding.ASCII.GetString(str); } }
public async Task ReadNameTableEntry(ByteArrayReader reader) { await Name.ReadString(reader); Flags = reader.ReadUInt64(); }
public override async Task ReadPropertyValue(ByteArrayReader reader, int size, DomainHeader header) { await Task.Run(() => NameIndexValue.ReadNameTableIndex(reader, header)); }
public async Task ReadHeaderAsync(Action<DomainLoadProgress> progress) { DomainLoadProgress message = new DomainLoadProgress { Text = "Parsing Header..." }; progress?.Invoke(message); await readUpkHeader(); const CompressionTypes validCompression = CompressionTypes.LZO | CompressionTypes.LZO_ENC; if (((CompressionTypes)CompressionFlags & validCompression) > 0 ) { message.Text = "Decompressing..."; progress?.Invoke(message); reader = await decompressChunks(); } else if (CompressionFlags > 0) throw new Exception($"Unsupported compression type 0x{CompressionFlags:X8}."); await readNameTable(progress); await readImportTable(progress); await readExportTable(progress); message.Text = "Slicing and Dicing..."; progress?.Invoke(message); await readDependsTable(); if (CookerVersion != 0) await decodePointers(); message.Text = "Reading Objects..."; message.Total = ExportTableCount; progress?.Invoke(message); await ExportTable.ForEachAsync(export => { return export.ReadDomainObject(reader).ContinueWith(t => { message.IncrementCurrent(); if (ExportTableCount > 100) progress?.Invoke(message); }); }); message.IsComplete = true; progress?.Invoke(message); }
public override async Task ReadPropertyValue(ByteArrayReader reader, int size, DomainHeader header) { await stringValue.ReadString(reader); }
internal async Task ReadDomainObject(ByteArrayReader reader) { DomainObjectReader = await reader.Splice(SerialDataOffset, SerialDataSize); }