public static CASCConfig LoadOnlineStorageConfig() { var config = new CASCConfig { OnlineMode = true }; using (var cdnsStream = CDNHandler.OpenFileDirect("http://us.patch.battle.net/wow_beta/cdns")) { config._CDNData = KeyValueConfig.ReadVerBarConfig(cdnsStream); } using (var versionsStream = CDNHandler.OpenFileDirect("http://us.patch.battle.net/wow_beta/versions")) { config._VersionsData = KeyValueConfig.ReadVerBarConfig(versionsStream); } string buildKey = config._VersionsData["BuildConfig"][0]; using (Stream stream = CDNHandler.OpenConfigFileDirect(config.CDNUrl, buildKey)) { config._BuildConfig = KeyValueConfig.ReadKeyValueConfig(stream); } string cdnKey = config._VersionsData["CDNConfig"][0]; using (Stream stream = CDNHandler.OpenConfigFileDirect(config.CDNUrl, cdnKey)) { config._CDNConfig = KeyValueConfig.ReadKeyValueConfig(stream); } return(config); }
private void loadDataWorker_DoWork(object sender, DoWorkEventArgs e) { CASCConfig.Load(CASCHandler.OnlineMode); CDNHandler.Initialize(CASCHandler.OnlineMode); cascHandler = new CASCHandler(root, sender as BackgroundWorker); e.Result = CASCHandler.FileNames.Count; }
public void ExtractFile(byte[] key, string path, string name) { try { if (OnlineMode) { throw new Exception(); } var idxInfo = GetLocalIndexInfo(key); if (idxInfo == null) { throw new Exception("local index missing"); } var stream = GetDataStream(idxInfo.Index); stream.Position = idxInfo.Offset; stream.Position += 30; //byte[] unkHash = reader.ReadBytes(16); //int __size = reader.ReadInt32(); //byte[] unkData1 = reader.ReadBytes(2); //byte[] unkData2 = reader.ReadBytes(8); using (BLTEHandler blte = new BLTEHandler(stream, idxInfo.Size - 30)) blte.ExtractToFile(path, name); } catch { if (key.EqualsTo(CASCConfig.EncodingKey)) { using (Stream s = CDNHandler.OpenDataFileDirect(key, out int len)) using (BLTEHandler blte = new BLTEHandler(s, len)) blte.ExtractToFile(path, name); } else { var idxInfo = CDNHandler.GetCDNIndexInfo(key); if (idxInfo == null) { throw new Exception("CDN index missing"); } using (Stream s = CDNHandler.OpenDataFile(key)) using (BLTEHandler blte = new BLTEHandler(s, idxInfo.Size)) blte.ExtractToFile(path, name); } } }
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]; if (config.OnlineMode) handler.DownloadFile(index, i); else handler.OpenFile(index, i); } Logger.WriteLine("CDNHandler: loaded {0} indexes", handler.CDNIndexData.Count); return handler; }
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]; if (config.OnlineMode) { handler.DownloadFile(index, i); } else { handler.OpenFile(index, i); } } Logger.WriteLine("CDNHandler: loaded {0} indexes", handler.CDNIndexData.Count); return(handler); }
public static void Load(bool online) { string wowPath = Properties.Settings.Default.WowPath; if (online) { using (var cdnsStream = CDNHandler.OpenFileDirect("http://us.patch.battle.net/wow_beta/cdns")) _CDNData = new VerBarConfig(cdnsStream); using (var versionsStream = CDNHandler.OpenFileDirect("http://us.patch.battle.net/wow_beta/versions")) _VersionsData = new VerBarConfig(versionsStream); string buildKey = _VersionsData["BuildConfig"][0]; using (Stream buildConfigStream = CDNHandler.OpenConfigFileDirect(buildKey)) _BuildConfig = new KeyValueConfig(buildConfigStream); string cdnKey = _VersionsData["CDNConfig"][0]; using (Stream CDNConfigStream = CDNHandler.OpenConfigFileDirect(cdnKey)) _CDNConfig = new KeyValueConfig(CDNConfigStream); } else { string buildInfoPath = Path.Combine(wowPath, ".build.info"); using (Stream buildInfoStream = new FileStream(buildInfoPath, FileMode.Open)) _BuildInfo = new VerBarConfig(buildInfoStream); string buildKey = _BuildInfo["Build Key"][0]; string buildCfgPath = Path.Combine(wowPath, "Data\\config\\", buildKey.Substring(0, 2), buildKey.Substring(2, 2), buildKey); using (Stream buildConfigStream = new FileStream(buildCfgPath, FileMode.Open)) _BuildConfig = new KeyValueConfig(buildConfigStream); string cdnKey = _BuildInfo["CDN Key"][0]; string cdnCfgPath = Path.Combine(wowPath, "Data\\config\\", cdnKey.Substring(0, 2), cdnKey.Substring(2, 2), cdnKey); using (Stream CDNConfigStream = new FileStream(cdnCfgPath, FileMode.Open)) _CDNConfig = new KeyValueConfig(CDNConfigStream); } }
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; //for (int i = 0; i < numBlocks; i++) //{ // var bytes = br.ReadBytes(18); // unknown data //} 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) //{ // br.ReadBytes(16); // br.ReadBytes(16); //} 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); } //Encodings[md5] = entry; EncodingData.Add(md5, entry); } //br.ReadBytes(28); while (br.PeekChar() == 0) fs.Position++; if (worker != null) worker.ReportProgress((int)((float)fs.Position / (float)fs.Length * 100)); } //var pos = br.BaseStream.Position; //for (int i = 0; i < i1; ++i) //{ // br.ReadBytes(16); // br.ReadBytes(16); //} 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; // don't load other locales //if (block.Flags != LocaleFlags.All && (block.Flags & LocaleFlags.enUS) == 0) // continue; 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 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; //for (int i = 0; i < numBlocks; i++) //{ // var bytes = br.ReadBytes(18); // unknown data //} 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) //{ // br.ReadBytes(16); // br.ReadBytes(16); //} 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); } //Encodings[md5] = entry; EncodingData.Add(md5, entry); } //br.ReadBytes(28); while (br.PeekChar() == 0) { fs.Position++; } if (worker != null) { worker.ReportProgress((int)((float)fs.Position / (float)fs.Length * 100)); } } //var pos = br.BaseStream.Position; //for (int i = 0; i < i1; ++i) //{ // br.ReadBytes(16); // br.ReadBytes(16); //} 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; // don't load other locales //if (block.Flags != LocaleFlags.All && (block.Flags & LocaleFlags.enUS) == 0) // continue; 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)); }