예제 #1
0
    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);
    }
예제 #5
0
    public virtual void SetPropertyValue(object value) {
      ByteArrayReader reader = value as ByteArrayReader;

      if (reader == null) return;

      DataReader = reader;
    }
예제 #6
0
    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();
    }
예제 #7
0
    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();
    }
예제 #9
0
    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);
    }
예제 #11
0
    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));
    }
예제 #12
0
    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;
    }
예제 #14
0
    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;
    }
예제 #15
0
    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;
    }
예제 #17
0
    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;
      });
    }
예제 #18
0
    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>();
    }
예제 #19
0
    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);
    }
예제 #21
0
    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;
    }
예제 #23
0
    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);
    }
예제 #24
0
    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);
    }
예제 #25
0
    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);
      }
    }
예제 #26
0
    public async Task ReadNameTableEntry(ByteArrayReader reader) {
      await Name.ReadString(reader);

      Flags = reader.ReadUInt64();
    }
예제 #27
0
 public override async Task ReadPropertyValue(ByteArrayReader reader, int size, DomainHeader header) {
   await Task.Run(() => NameIndexValue.ReadNameTableIndex(reader, header));
 }
예제 #28
0
    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);
    }
예제 #29
0
 public override async Task ReadPropertyValue(ByteArrayReader reader, int size, DomainHeader header) {
   await stringValue.ReadString(reader);
 }
예제 #30
0
 internal async Task ReadDomainObject(ByteArrayReader reader) {
   DomainObjectReader = await reader.Splice(SerialDataOffset, SerialDataSize);
 }