Beispiel #1
0
        protected override void ExtractFileOnline(MD5Hash key, string path, string name)
        {
            IndexEntry idxInfo = CDNIndex.GetIndexInfo(key);

            ExtractFileOnlineInternal(idxInfo, key, path, name);
        }
        private CASCHandlerLite(CASCConfig config, LocaleFlags locale) : base(config)
        {
            if (config.GameType != CASCGameType.WoW)
            {
                throw new Exception("Unsupported game " + config.BuildUID);
            }

            EncodingHandler EncodingHandler;

            using (var fs = OpenEncodingFile(this))
                EncodingHandler = new EncodingHandler(fs);

            WowRootHandler RootHandler;

            using (var fs = OpenRootFile(EncodingHandler, this))
                RootHandler = new WowRootHandler(fs);

            RootHandler.SetFlags(locale, false, false);

            CDNIndexData = new Dictionary <MD5Hash, IndexEntry>(comparer);

            if (LocalIndex != null)
            {
                LocalIndexData = new Dictionary <MD5Hash, IndexEntry>(comparer);
            }

            RootEntry rootEntry;

            foreach (var entry in RootHandler.GetAllEntries())
            {
                rootEntry = entry.Value;

                if ((rootEntry.LocaleFlags == locale || (rootEntry.LocaleFlags & locale) != LocaleFlags.None) && (rootEntry.ContentFlags & ContentFlags.Alternate) == ContentFlags.None)
                {
                    if (EncodingHandler.GetEntry(rootEntry.MD5, out EncodingEntry enc))
                    {
                        if (!HashToKey.ContainsKey(entry.Key))
                        {
                            HashToKey.Add(entry.Key, enc.Key);
                            FileDataIdToHash.Add(RootHandler.GetFileDataIdByHash(entry.Key), entry.Key);

                            if (LocalIndex != null)
                            {
                                IndexEntry iLocal = LocalIndex.GetIndexInfo(enc.Key);

                                if (iLocal != null && !LocalIndexData.ContainsKey(enc.Key))
                                {
                                    LocalIndexData.Add(enc.Key, iLocal);
                                }
                            }

                            IndexEntry iCDN = CDNIndex.GetIndexInfo(enc.Key);

                            if (iCDN != null && !CDNIndexData.ContainsKey(enc.Key))
                            {
                                CDNIndexData.Add(enc.Key, iCDN);
                            }
                        }
                    }
                }
            }

            CDNIndex.Clear();
            //CDNIndex = null;
            LocalIndex?.Clear();
            LocalIndex = null;
            RootHandler.Clear();
            RootHandler = null;
            EncodingHandler.Clear();
            EncodingHandler = null;
            GC.Collect();

            Console.WriteLine("CASCHandlerLite: loaded {0} files", HashToKey.Count);
        }
Beispiel #3
0
        protected override Stream OpenFileOnline(MD5Hash key)
        {
            IndexEntry idxInfo = CDNIndex.GetIndexInfo(key);

            return(OpenFileOnlineInternal(idxInfo, key));
        }
Beispiel #4
0
        private unsafe void ParseIndex(string idx)
        {
            using (var fs = new FileStream(idx, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                using (var br = new BinaryReader(fs))
                {
                    int    h2Len   = br.ReadInt32();
                    int    h2Check = br.ReadInt32();
                    byte[] h2      = br.ReadBytes(h2Len);

                    long padPos = (8 + h2Len + 0x0F) & 0xFFFFFFF0;
                    fs.Position = padPos;

                    int dataLen   = br.ReadInt32();
                    int dataCheck = br.ReadInt32();

                    int numBlocks = dataLen / 18;

                    //byte[] buf = new byte[8];

                    for (int i = 0; i < numBlocks; i++)
                    {
                        IndexEntry info     = new IndexEntry();
                        byte[]     keyBytes = br.ReadBytes(9);
                        Array.Resize(ref keyBytes, 16);

                        MD5Hash key;

                        fixed(byte *ptr = keyBytes)
                        key = *(MD5Hash *)ptr;

                        byte indexHigh = br.ReadByte();
                        int  indexLow  = br.ReadInt32BE();

                        info.Index  = (indexHigh << 2 | (byte)((indexLow & 0xC0000000) >> 30));
                        info.Offset = (indexLow & 0x3FFFFFFF);

                        //for (int j = 3; j < 8; j++)
                        //    buf[7 - j] = br.ReadByte();

                        //long val = BitConverter.ToInt64(buf, 0);
                        //info.Index = (int)(val / 0x40000000);
                        //info.Offset = (int)(val % 0x40000000);

                        info.Size = br.ReadInt32();

                        // duplicate keys wtf...
                        //IndexData[key] = info; // use last key
                        if (!LocalIndexData.ContainsKey(key)) // use first key
                        {
                            LocalIndexData.Add(key, info);
                        }
                    }

                    padPos      = (dataLen + 0x0FFF) & 0xFFFFF000;
                    fs.Position = padPos;

                    fs.Position += numBlocks * 18;
                    //for (int i = 0; i < numBlocks; i++)
                    //{
                    //    var bytes = br.ReadBytes(18); // unknown data
                    //}

                    //if (fs.Position != fs.Length)
                    //    throw new Exception("idx file under read");
                }
        }