public static CDNHandler Initialize(CASCConfig config) { var handler = new CDNHandler(config); for (int i = 0; i < config.Archives.Count; i++) { string index = config.Archives[i]; handler.OpenFile(index, i); } Logger.WriteLine("CDNHandler: loaded {0} indexes", handler.CDNIndexData.Count); return(handler); }
private CASCHandler(CASCConfig config, CDNHandler cdn, BackgroundWorker worker) { this.config = config; this.cdn = cdn; if (!config.OnlineMode) { var idxFiles = GetIdxFiles(this.config.BasePath); if (idxFiles.Count == 0) { throw new FileNotFoundException("idx files missing!"); } if (worker != null) { worker.ReportProgress(0); } int idxIndex = 0; foreach (var idx in idxFiles) { 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; for (int i = 0; i < numBlocks; i++) { IndexEntry info = new IndexEntry(); byte[] key = br.ReadBytes(9); int indexHigh = br.ReadByte(); int indexLow = br.ReadInt32BE(); info.Index = (int)((byte)(indexHigh << 2) | ((indexLow & 0xC0000000) >> 30)); info.Offset = (indexLow & 0x3FFFFFFF); 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; if (fs.Position != fs.Position) { throw new Exception("idx file under read"); } } if (worker != null) { worker.ReportProgress((int)((float)++idxIndex / (float)idxFiles.Count * 100)); } } Logger.WriteLine("CASCHandler: loaded {0} indexes", LocalIndexData.Count); } if (worker != null) { worker.ReportProgress(0); } using (var fs = OpenEncodingFile()) using (var br = new BinaryReader(fs)) { br.ReadBytes(2); // EN byte b1 = br.ReadByte(); byte b2 = br.ReadByte(); byte b3 = br.ReadByte(); ushort s1 = br.ReadUInt16(); ushort s2 = br.ReadUInt16(); int numEntries = br.ReadInt32BE(); int i1 = br.ReadInt32BE(); byte b4 = br.ReadByte(); int entriesOfs = br.ReadInt32BE(); fs.Position += entriesOfs; // skip strings fs.Position += numEntries * 32; for (int i = 0; i < numEntries; ++i) { ushort keysCount; while ((keysCount = br.ReadUInt16()) != 0) { int fileSize = br.ReadInt32BE(); byte[] md5 = br.ReadBytes(16); var entry = new EncodingEntry(); entry.Size = fileSize; for (int ki = 0; ki < keysCount; ++ki) { byte[] key = br.ReadBytes(16); entry.Keys.Add(key); } EncodingData.Add(md5, entry); } while (br.PeekChar() == 0) { fs.Position++; } if (worker != null) { worker.ReportProgress((int)((float)fs.Position / (float)fs.Length * 100)); } } Logger.WriteLine("CASCHandler: loaded {0} encoding data", EncodingData.Count); } if (worker != null) { worker.ReportProgress(0); } using (var fs = OpenRootFile()) using (var br = new BinaryReader(fs)) { while (fs.Position < fs.Length) { int count = br.ReadInt32(); RootBlock block = new RootBlock(); block.Unk1 = br.ReadUInt32(); block.Flags = (LocaleFlags)br.ReadUInt32(); if (block.Flags == LocaleFlags.None) { throw new Exception("block.Flags == LocaleFlags.None"); } RootEntry[] entries = new RootEntry[count]; for (var i = 0; i < count; ++i) { entries[i] = new RootEntry(); entries[i].Block = block; entries[i].Unk1 = br.ReadInt32(); } for (var i = 0; i < count; ++i) { entries[i].MD5 = br.ReadBytes(16); ulong hash = br.ReadUInt64(); entries[i].Hash = hash; if (!RootData.ContainsKey(hash)) { RootData[hash] = new List <RootEntry>(); RootData[hash].Add(entries[i]); } else { RootData[hash].Add(entries[i]); } } if (worker != null) { worker.ReportProgress((int)((float)fs.Position / (float)fs.Length * 100)); } } Logger.WriteLine("CASCHandler: loaded {0} root data", RootData.Count); } if (worker != null) { worker.ReportProgress(0); } }
private static CASCHandler Open(BackgroundWorker worker, CASCConfig config) { var cdn = CDNHandler.Initialize(config); return(new CASCHandler(config, cdn, worker)); }