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); }
protected override Stream OpenFileOnline(MD5Hash key) { IndexEntry idxInfo = CDNIndex.GetIndexInfo(key); return(OpenFileOnlineInternal(idxInfo, key)); }
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"); } }