Ejemplo n.º 1
0
        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();
        }
Ejemplo n.º 2
0
        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();
        }