public DownloadHandler(BLTEStream blte) { if (CASContainer.BuildConfig["download-size"][0] != null && blte.Length != long.Parse(CASContainer.BuildConfig["download-size"][0])) { CASContainer.Settings?.Logger.LogAndThrow(Logging.LogType.Critical, "Download File is corrupt."); } using (var br = new BinaryReader(blte)) { Header = new DownloadHeader() { Header = br.ReadBytes(2), Version = br.ReadByte(), ChecksumSize = br.ReadByte(), Unknown = br.ReadByte(), NumEntries = br.ReadUInt32BE(), NumTags = br.ReadUInt16BE(), }; // entries for (int i = 0; i < Header.NumEntries; i++) { var entry = new DownloadEntry() { Unknown = Header.Version > 1 ? br.ReadByte() : (byte)0, // new V2 field Hash = new MD5Hash(br), FileSize = br.ReadUInt40BE(), Stage = br.ReadByte(), UnknownData = br.ReadBytes(4) }; Entries.Add(entry); } // tags int numMaskBytes = ((int)Header.NumEntries + 7) / 8; for (int i = 0; i < Header.NumTags; i++) { var tag = new DownloadTag() { Name = br.ReadCString(), Type = br.ReadUInt16BE(), BitMask = new BoolArray(br.ReadBytes(numMaskBytes)) }; Tags.Add(tag); } EncodingMap = blte.EncodingMap.ToArray(); endofStageIndex = new int[] // store last indice of each stage { Entries.FindLastIndex(x => x.Stage == 0), Entries.FindLastIndex(x => x.Stage == 1) }; } blte?.Dispose(); }
public DownloadHandler(BLTEStream blte) { if (CASContainer.BuildConfig["download-size"][0] != null && blte.Length != long.Parse(CASContainer.BuildConfig["download-size"][0])) { CASContainer.Settings?.Logger.LogAndThrow(Logging.LogType.Critical, "Download File is corrupt."); } using (var br = new BinaryReader(blte)) { Header = new DownloadHeader() { Header = br.ReadBytes(2), Version = br.ReadByte(), ChecksumSize = br.ReadByte(), HasChecksum = br.ReadByte(), NumEntries = br.ReadUInt32BE(), NumTags = br.ReadUInt16BE(), }; if (Header.Version >= 2) { Header.NumFlags = br.ReadByte(); } if (Header.Version >= 3) { // TODO do we have a version 3 file to test with? //Header.BasePriority = br.ReadByte(); //Header.Unknown_0D = br.ReadBytes(3); throw new NotImplementedException("Download file versions newer than 2 are not supported."); } // entries for (int i = 0; i < Header.NumEntries; i++) { var entry = new DownloadEntry() { EKey = new MD5Hash(br), FileSize = br.ReadUInt40BE(), Priority = br.ReadByte() }; if (Header.HasChecksum != 0) { entry.Checksum = br.ReadUInt32BE(); } if (Header.Version >= 2) { entry.Flags = (DownloadFlags[])(object)br.ReadBytes(Header.NumFlags); } Entries.Add(entry); } // tags int numMaskBytes = ((int)Header.NumEntries + 7) / 8; for (int i = 0; i < Header.NumTags; i++) { var tag = new DownloadTag() { Name = br.ReadCString(), Type = br.ReadUInt16BE(), BitMask = new BoolArray(br.ReadBytes(numMaskBytes)) }; // We need to remove trailing bits from the padded byte array. while (tag.BitMask.Count != Entries.Count) { tag.BitMask.RemoveAt(tag.BitMask.Count - 1); } Tags.Add(tag); } EncodingMap = blte.EncodingMap.ToArray(); endofStageIndex = new int[] // store last indice of each stage { Entries.FindLastIndex(x => x.Priority == 0), Entries.FindLastIndex(x => x.Priority == 1) }; } blte?.Dispose(); }