private static void Explore(CASCFolder folder, string findFile, SearchType type, List <CASCFile> found) { foreach (KeyValuePair <string, ICASCEntry> node in folder.Entries) { ICASCEntry entry = node.Value; if (entry is CASCFolder) { Explore((CASCFolder)entry, findFile, type, found); } else if (entry is CASCFile) { CASCFile file = (CASCFile)entry; string fileName = file.FullName.ToLower(); if (type == SearchType.COMPLETE && fileName.Equals(fileName)) { found.Add(file); break; } if (type == SearchType.STARTS_WITH && fileName.StartsWith(findFile)) { found.Add(file); continue; } if (type == SearchType.ENDS_WITH && fileName.EndsWith(findFile)) { found.Add(file); continue; } } } }
private static void CreateSubTree(CASCFolder root, ulong filehash, string file) { string[] parts = file.Split('\\'); CASCFolder folder = root; for (int i = 0; i < parts.Length; ++i) { bool isFile = (i == parts.Length - 1); ulong hash = isFile ? filehash : Hasher.ComputeHash(parts[i]); ICASCEntry entry = folder.GetEntry(hash); if (entry == null) { if (isFile) { entry = new CASCFile(hash); CASCFile.FileNames[hash] = file; } else { entry = new CASCFolder(hash); CASCFolder.FolderNames[hash] = parts[i]; } folder.SubEntries[hash] = entry; } folder = entry as CASCFolder; } }
private void Explore(CASCFolder folder) { foreach (KeyValuePair <string, ICASCEntry> node in folder.Entries) { ICASCEntry entry = node.Value; if (entry is CASCFolder) { Explore((CASCFolder)entry); } else if (entry is CASCFile) { CASCFile file = (CASCFile)entry; // Check we have a valid extension. if (!IsValidExtension(file)) { continue; } // Ensure the file matches the filter. if (!MatchesFilter(file.FullName)) { continue; } EventManager.Trigger_FileExploreHit(id, file); } Thread.Sleep(2); } }
protected void CreateSubTree(CASCFolder root, ulong filehash, string file) { string[] parts = file.Split(PathDelimiters); CASCFolder folder = root; for (int i = 0; i < parts.Length; ++i) { bool isFile = (i == parts.Length - 1); string entryName = parts[i]; ICASCEntry entry = folder.GetEntry(entryName); if (entry == null) { if (isFile) { entry = new CASCFile(filehash); CASCFile.FileNames[filehash] = file; } else { entry = new CASCFolder(entryName); } folder.Entries[entryName] = entry; } folder = entry as CASCFolder; } }
public int CompareTo(ICASCEntry other, int col, CASCEngine casc) { int result = 0; if (other is CASCFolder) { return(1); } switch (col) { case 0: result = Name.CompareTo(other.Name); break; case 1: result = Path.GetExtension(Name).CompareTo(Path.GetExtension(other.Name)); break; case 2: { var e1 = casc.RootHandler.GetEntries(Hash); var e2 = casc.RootHandler.GetEntries(other.Hash); var flags1 = e1.Any() ? e1.First().LocaleFlags : LocaleFlags.None; var flags2 = e2.Any() ? e2.First().LocaleFlags : LocaleFlags.None; result = flags1.CompareTo(flags2); } break; case 3: { var e1 = casc.RootHandler.GetEntries(Hash); var e2 = casc.RootHandler.GetEntries(other.Hash); var flags1 = e1.Any() ? e1.First().ContentFlags : ContentFlags.None; var flags2 = e2.Any() ? e2.First().ContentFlags : ContentFlags.None; result = flags1.CompareTo(flags2); } break; case 4: var size1 = GetSize(casc); var size2 = (other as CASCFile).GetSize(casc); if (size1 == size2) { result = 0; } else { result = size1 < size2 ? -1 : 1; } break; } return(result); }
public int CompareTo(ICASCEntry other, int col, CASCEngine casc) { int result = 0; if (other is CASCFolder) return 1; switch (col) { case 0: result = Name.CompareTo(other.Name); break; case 1: result = Path.GetExtension(Name).CompareTo(Path.GetExtension(other.Name)); break; case 2: { var e1 = casc.RootHandler.GetEntries(Hash); var e2 = casc.RootHandler.GetEntries(other.Hash); var flags1 = e1.Any() ? e1.First().LocaleFlags : LocaleFlags.None; var flags2 = e2.Any() ? e2.First().LocaleFlags : LocaleFlags.None; result = flags1.CompareTo(flags2); } break; case 3: { var e1 = casc.RootHandler.GetEntries(Hash); var e2 = casc.RootHandler.GetEntries(other.Hash); var flags1 = e1.Any() ? e1.First().ContentFlags : ContentFlags.None; var flags2 = e2.Any() ? e2.First().ContentFlags : ContentFlags.None; result = flags1.CompareTo(flags2); } break; case 4: var size1 = GetSize(casc); var size2 = (other as CASCFile).GetSize(casc); if (size1 == size2) result = 0; else result = size1 < size2 ? -1 : 1; break; } return result; }
protected override void LoadHeroesMapMods() { CASCFolder currentFolder = CASCFolderData.GetDirectory(HeroesMapModsDirectoryPath); // loop through each mapmods folder foreach (KeyValuePair <string, ICASCEntry> mapFolder in currentFolder.Entries) { ICASCEntry baseStormDataFolder = ((CASCFolder)mapFolder.Value).GetEntry(BaseStormDataDirectoryName); ICASCEntry gameDataFolder = ((CASCFolder)baseStormDataFolder).GetEntry(GameDataStringName); if (LoadXmlFilesEnabled) { foreach (KeyValuePair <string, ICASCEntry> dataFiles in ((CASCFolder)gameDataFolder).Entries) { if (Path.GetExtension(dataFiles.Key) == ".xml") { string filePath = ((CASCFile)dataFiles.Value).FullName; if (!CASCHandlerData.FileExists(filePath)) { throw new FileNotFoundException(filePath); } using (Stream data = CASCHandlerData.OpenFile(filePath)) { LoadXmlFile(mapFolder.Value.Name, data, filePath); } } } } if (LoadTextFilesOnlyEnabled) { string filePath = Path.Combine(HeroesMapModsDirectoryPath, mapFolder.Value.Name, GameStringLocalization, LocalizedDataName, GameStringFile); if (CASCHandlerData.FileExists(filePath)) { LoadTextFile(mapFolder.Value.Name, CASCHandlerData.OpenFile(filePath), filePath); } } } }
public int CompareTo(ICASCEntry other, int col, CASCEngine casc) { int result = 0; if (other is CASCFile) return -1; switch (col) { case 0: case 1: case 2: case 3: result = Name.CompareTo(other.Name); break; case 4: break; } return result; }
private void Explore(CASCFolder folder) { foreach (KeyValuePair <string, ICASCEntry> node in folder.Entries) { ICASCEntry entry = node.Value; if (entry is CASCFolder) { Explore((CASCFolder)entry); } else if (entry is CASCFile) { CASCFile file = (CASCFile)entry; if (file.Name.ToLower().Contains("illidan2")) { new RunnerExtractItem(file).Begin(); return; } } } }
private void ExecPlugin(IPreview plugin, ICASCEntry file) { try { using (var stream = _casc.OpenFile(file.Hash)) { // todo: use Task var control = plugin.Show(stream, file.Name); if (m_currentControl != control) { ViewPanel.Controls.Clear(); ViewPanel.Controls.Add(control); control.Dock = DockStyle.Fill; m_currentControl = control; } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Plugin Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
private void listView1_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) { CASCFolder folder = fileList.Tag as CASCFolder; if (folder == null) { return; } if (e.ItemIndex < 0 || e.ItemIndex >= folder.SubEntries.Count) { return; } ICASCEntry entry = folder.SubEntries.ElementAt(e.ItemIndex).Value; var flags = LocaleFlags.None; if (entry is CASCFile) { var rootInfos = cascHandler.GetRootInfo(entry.Hash); if (rootInfos == null) { throw new Exception("root entry missing!"); } foreach (var rootInfo in rootInfos) { flags |= rootInfo.Block.Flags; } } var item = new ListViewItem(new string[] { entry.Name, entry is CASCFolder ? "Folder" : "File", flags.ToString() }); item.ImageIndex = entry is CASCFolder ? 0 : 2; e.Item = item; }
public override void Work() { Thread.Sleep(500); if (rootFolders != null && rootFolders.Length > 0) { foreach (KeyValuePair <string, ICASCEntry> node in Program.Root.Entries) { ICASCEntry entry = node.Value; string name = entry.Name.ToLower(); if (entry is CASCFolder && rootFolders.Any(n => n.ToLower().Equals(name))) { Explore((CASCFolder)entry); } } } else { Explore(Program.Root); } EventManager.Trigger_FileExploreDone(id); }
public int CompareTo(ICASCEntry other, int col, CASCEngine casc) { int result = 0; if (other is CASCFile) { return(-1); } switch (col) { case 0: case 1: case 2: case 3: result = Name.CompareTo(other.Name); break; case 4: break; } return(result); }
public void CreateListViewItem(RetrieveVirtualItemEventArgs e) { if (_currentFolder == null) { return; } if (e.ItemIndex < 0 || e.ItemIndex >= _displayedEntries.Count) { return; } ICASCEntry entry = _displayedEntries[e.ItemIndex]; var localeFlags = LocaleFlags.None; var contentFlags = ContentFlags.None; var size = "<DIR>"; if (entry is CASCFile) { var rootInfosLocale = _casc.Root.GetEntries(entry.Hash); if (rootInfosLocale.Any()) { if (_casc.Encoding.GetEntry(rootInfosLocale.First().MD5, out EncodingEntry enc)) { size = enc.Size.ToString("N", sizeNumberFmt) ?? "0"; } else { size = "NYI"; if (_casc.Root is OwRootHandler owRoot) { if (owRoot.GetEntry(entry.Hash, out OWRootEntry rootEntry)) { size = rootEntry.pkgIndexRec.Size.ToString("N", sizeNumberFmt) ?? "0"; } } } foreach (var rootInfo in rootInfosLocale) { localeFlags |= rootInfo.LocaleFlags; contentFlags |= rootInfo.ContentFlags; } } else { var installInfos = _casc.Install.GetEntries(entry.Hash); if (installInfos.Any()) { if (_casc.Encoding.GetEntry(installInfos.First().MD5, out EncodingEntry enc)) { size = enc.Size.ToString("N", sizeNumberFmt) ?? "0"; //foreach (var rootInfo in rootInfosLocale) //{ // if (rootInfo.Block != null) // { // localeFlags |= rootInfo.Block.LocaleFlags; // contentFlags |= rootInfo.Block.ContentFlags; // } //} } } } } e.Item = new ListViewItem(new string[] { entry.Name, entry is CASCFolder ? "Folder" : Path.GetExtension(entry.Name), localeFlags.ToString(), contentFlags.ToString(), size }) { ImageIndex = entry is CASCFolder ? 0 : 2 }; }
public int CompareTo(ICASCEntry other) { throw new NotImplementedException(); }
private static CASCFolder LoadListFile(CASCHandler cascHandler, string path, BackgroundWorker worker) { if (!File.Exists(path)) { throw new FileNotFoundException("list file missing!"); } var rootHash = CASCHandler.Hasher.ComputeHash("root"); var root = new CASCFolder(rootHash); CASCHandler.FolderNames[rootHash] = "root"; using (var sr = new StreamReader(path)) { string file; int filesCount = 0; CASCFolder folder = root; while ((file = sr.ReadLine()) != null) { filesCount++; string[] parts = file.Split('\\'); for (int i = 0; i < parts.Length; ++i) { bool isFile = (i == parts.Length - 1); ulong hash = isFile ? CASCHandler.Hasher.ComputeHash(file) : CASCHandler.Hasher.ComputeHash(parts[i]); // skip invalid names if (isFile && !cascHandler.RootData.ContainsKey(hash)) { break; } ICASCEntry entry = folder.GetEntry(hash); if (entry == null) { if (isFile) { entry = new CASCFile(hash); CASCHandler.FileNames[hash] = file; } else { entry = new CASCFolder(hash); CASCHandler.FolderNames[hash] = parts[i]; } folder.SubEntries[hash] = entry; if (isFile) { folder = root; break; } } folder = entry as CASCFolder; } } Logger.WriteLine("CASCHandler: loaded {0} file names", CASCHandler.FileNames.Count); } return(root); }
public int CompareTo(ICASCEntry other) { throw new NotImplementedException(); }
public CASCHandler(CASCFolder root, BackgroundWorker worker) { if (!OnlineMode) { var idxFiles = GetIdxFiles(Properties.Settings.Default.WowPath); if (idxFiles.Count == 0) { throw new FileNotFoundException("idx files missing!"); } 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"); } } worker.ReportProgress((int)((float)++idxIndex / (float)idxFiles.Count * 100)); } Logger.WriteLine("CASCHandler: loaded {0} indexes", LocalIndexData.Count); } 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++; } 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); } 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]); } } worker.ReportProgress((int)((float)fs.Position / (float)fs.Length * 100)); } Logger.WriteLine("CASCHandler: loaded {0} root data", RootData.Count); } worker.ReportProgress(0); if (File.Exists(listFile)) { FolderNames[Hasher.ComputeHash("root")] = "root"; using (StreamReader sr = new StreamReader(listFile)) { string file; int filesCount = 0; CASCFolder folder = root; while ((file = sr.ReadLine()) != null) { ulong fileHash = Hasher.ComputeHash(file); // skip invalid names if (!RootData.ContainsKey(fileHash)) { Logger.WriteLine("Invalid file name: {0}", file); continue; } filesCount++; string[] parts = file.Split('\\'); for (int i = 0; i < parts.Length; ++i) { bool isFile = (i == parts.Length - 1); ulong hash = isFile ? fileHash : Hasher.ComputeHash(parts[i]); ICASCEntry entry = folder.GetEntry(hash); if (entry == null) { if (isFile) { entry = new CASCFile(hash); FileNames[hash] = file; } else { entry = new CASCFolder(hash); FolderNames[hash] = parts[i]; } folder.SubEntries[hash] = entry; if (isFile) { folder = root; break; } } folder = entry as CASCFolder; } if ((filesCount % 1000) == 0) { worker.ReportProgress((int)((float)sr.BaseStream.Position / (float)sr.BaseStream.Length * 100)); } } Logger.WriteLine("CASCHandler: loaded {0} file names", FileNames.Count); } } else { throw new FileNotFoundException("list file missing!"); } }
public CASCFolder LoadListFile(List <string> list) { var rootHash = Hasher.ComputeHash("root"); var root = new CASCFolder(rootHash); CASCFolder.FolderNames[rootHash] = "root"; foreach (var file in list) { CASCFolder folder = root; { ulong fileHash = Hasher.ComputeHash(file); // skip invalid names if (!RootData.ContainsKey(fileHash)) { Logger.WriteLine("Invalid file name: {0}", file); continue; } string[] parts = file.Split('\\'); for (int i = 0; i < parts.Length; ++i) { bool isFile = (i == parts.Length - 1); ulong hash = isFile ? fileHash : Hasher.ComputeHash(parts[i]); ICASCEntry entry = folder.GetEntry(hash); if (entry == null) { if (isFile) { entry = new CASCFile(hash); CASCFile.FileNames[hash] = file; } else { entry = new CASCFolder(hash); CASCFolder.FolderNames[hash] = parts[i]; } folder.SubEntries[hash] = entry; if (isFile) { folder = root; break; } } folder = entry as CASCFolder; } } Logger.WriteLine("Found {0} ClientDB files.", CASCFile.FileNames.Count); } return(root); }
public void CreateListViewItem(RetrieveVirtualItemEventArgs e, CASCFolder folder) { if (folder == null) { return; } if (e.ItemIndex < 0 || e.ItemIndex >= folder.Entries.Count) { return; } ICASCEntry entry = folder.Entries.ElementAt(e.ItemIndex).Value; var localeFlags = LocaleFlags.None; var contentFlags = ContentFlags.None; var size = "<DIR>"; if (entry is CASCFile) { var rootInfosLocale = _casc.Root.GetEntries(entry.Hash); if (rootInfosLocale.Any()) { var enc = _casc.Encoding.GetEntry(rootInfosLocale.First().MD5); if (enc != null) { size = enc.Size.ToString("N", sizeNumberFmt); } else { size = "0"; } foreach (var rootInfo in rootInfosLocale) { if (rootInfo.Block != null) { localeFlags |= rootInfo.Block.LocaleFlags; contentFlags |= rootInfo.Block.ContentFlags; } } } else { var installInfos = _casc.Install.GetEntries(entry.Hash); if (installInfos.Any()) { var enc = _casc.Encoding.GetEntry(installInfos.First().MD5); if (enc != null) { size = enc.Size.ToString("N", sizeNumberFmt); } else { size = "0"; } //foreach (var rootInfo in rootInfosLocale) //{ // if (rootInfo.Block != null) // { // localeFlags |= rootInfo.Block.LocaleFlags; // contentFlags |= rootInfo.Block.ContentFlags; // } //} } } } e.Item = new ListViewItem(new string[] { entry.Name, entry is CASCFolder ? "Folder" : Path.GetExtension(entry.Name), localeFlags.ToString(), contentFlags.ToString(), size }) { ImageIndex = entry is CASCFolder ? 0 : 2 }; }