public void SetExtractData(CASCHandler handler, ICollection <CASCFile> files) { NumExtracted = 0; progressBar1.Value = 0; CASC = handler; this.files = files; }
public void LoadFileDataComplete(CASCHandler casc) { if (!casc.FileExists("DBFilesClient\\FileDataComplete.db2")) { return; } Logger.WriteLine("WowRootHandler: loading file names from FileDataComplete.db2..."); using (var s = casc.OpenFile("DBFilesClient\\FileDataComplete.db2")) { WDC1Reader fd = new WDC1Reader(s); Jenkins96 hasher = new Jenkins96(); foreach (var row in fd) { string path = row.Value.GetField <string>(0); string name = row.Value.GetField <string>(1); string fullname = path + name; ulong fileHash = hasher.ComputeHash(fullname); // skip invalid names if (!casc.FileExists(fileHash)) { //Logger.WriteLine("Invalid file name: {0}", fullname); continue; } CASCFile.Files[fileHash] = new CASCFile(fileHash, fullname); } } }
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { string arg = (string)e.Argument; CASCConfig config = _onlineMode ? CASCConfig.LoadOnlineStorageConfig(arg, "us") : CASCConfig.LoadLocalStorageConfig(arg); if (_onlineMode) { using (SelectBuildForm sb = new SelectBuildForm(config)) { var result = sb.ShowDialog(); if (result != DialogResult.OK || sb.SelectedIndex == -1) { e.Cancel = true; return; } config.ActiveBuild = sb.SelectedIndex; } } var casc = CASCHandler.OpenStorage(config, backgroundWorker1); casc.Root.LoadListFile(Path.Combine(Application.StartupPath, "listfile.txt"), backgroundWorker1); var fldr = casc.Root.SetFlags(Settings.Default.LocaleFlags, Settings.Default.ContentFlags); casc.Root.MergeInstall(casc.Install); e.Result = new object[] { casc, fldr }; }
public void SetExtractData(CASCHandler handler, ICollection<CASCFile> files) { NumExtracted = 0; progressBar1.Value = 0; CASC = handler; this.files = files; }
public void OpenStorage(string arg, bool online) { Cleanup(); using (var initForm = new InitForm()) { if (online) { initForm.LoadOnlineStorage(arg); } else { initForm.LoadLocalStorage(arg); } DialogResult res = initForm.ShowDialog(); if (res != DialogResult.OK) { return; } _casc = initForm.CASC; _root = initForm.Root; } Sorter.CASC = _casc; OnStorageChanged?.Invoke(); }
public void SetExtractData(CASCHandler cascHandler, ICollection<CASCFile> files) { this.cascHandler = cascHandler; NumExtracted = 0; NumFiles = files.Count; progressBar1.Value = 0; this.files = files; }
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 SetExtractData(CASCHandler cascHandler, ICollection <CASCFile> files) { this.cascHandler = cascHandler; NumExtracted = 0; NumFiles = files.Count; progressBar1.Value = 0; this.files = files; }
public void SetExtractData(CASCHandler _cascHandler, CASCFolder _folder, ListView.SelectedIndexCollection _selection) { cascHandler = _cascHandler; folder = _folder; selection = _selection.Cast<int>().ToArray(); NumExtracted = 0; NumFiles = GetFilesCount(folder, selection); progressBar1.Value = 0; }
public void SetExtractData(CASCHandler _cascHandler, CASCFolder _folder, ListView.SelectedIndexCollection _selection) { cascHandler = _cascHandler; folder = _folder; selection = _selection.Cast <int>().ToArray(); NumExtracted = 0; NumFiles = GetFilesCount(folder, selection); progressBar1.Value = 0; }
public int CompareTo(ICASCEntry other, int col, CASCHandler 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.Root.GetEntries(Hash); var e2 = casc.Root.GetEntries(other.Hash); var flags1 = e1.Any() ? e1.First().Block.LocaleFlags : LocaleFlags.None; var flags2 = e2.Any() ? e2.First().Block.LocaleFlags : LocaleFlags.None; result = flags1.CompareTo(flags2); } break; case 3: { var e1 = casc.Root.GetEntries(Hash); var e2 = casc.Root.GetEntries(other.Hash); var flags1 = e1.Any() ? e1.First().Block.ContentFlags : ContentFlags.None; var flags2 = e2.Any() ? e2.First().Block.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 GetSize(CASCHandler casc) { var encoding = casc.GetEncodingEntry(hash); if (encoding != null) { return(encoding.Size); } return(0); }
private void loadDataWorker_DoWork(object sender, DoWorkEventArgs e) { var worker = sender as BackgroundWorker; cascHandler = Settings.Default.OnlineMode ? CASCHandler.OpenOnlineStorage(worker) : CASCHandler.OpenLocalStorage(Settings.Default.WowPath, worker); root = LoadListFile(cascHandler, Path.Combine(Application.StartupPath, "listfile.txt"), worker); e.Result = CASCHandler.FileNames.Count; }
public OwRootHandler(BinaryReader stream, BackgroundWorkerEx worker, CASCHandler casc) { worker?.ReportProgress(0, "Loading \"root\"..."); string str = Encoding.ASCII.GetString(stream.ReadBytes((int)stream.BaseStream.Length)); string[] array = str.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); List <string> APMNames = new List <string>(); for (int i = 1; i < array.Length; i++) { string[] filedata = array[i].Split('|'); string name = filedata[4]; if (Path.GetExtension(name) == ".apm" && name.Contains("RDEV")) { APMNames.Add(Path.GetFileNameWithoutExtension(name)); if (!name.Contains("L" + LanguageScan)) { continue; } // add apm file for dev purposes ulong apmNameHash = Hasher.ComputeHash(name); MD5Hash apmMD5 = filedata[0].ToByteArray().ToMD5(); _rootData[apmNameHash] = new OWRootEntry() { baseEntry = new RootEntry() { MD5 = apmMD5, LocaleFlags = LocaleFlags.All, ContentFlags = ContentFlags.None } }; CASCFile.FileNames[apmNameHash] = name; EncodingEntry apmEnc; if (!casc.Encoding.GetEntry(apmMD5, out apmEnc)) { continue; } using (Stream apmStream = casc.OpenFile(apmEnc.Key)) { apmFiles.Add(new APMFile(name, apmStream, casc)); } } worker?.ReportProgress((int)(i / (array.Length / 100f))); } APMList = APMNames.ToArray(); APMNames.Clear(); }
private void OnStorageChanged() { CASCHandler casc = viewHelper.CASC; CASCConfig cfg = casc.Config; CASCGameType gameType = cfg.GameType; bool isWoW = gameType == CASCGameType.WoW; extractInstallFilesToolStripMenuItem.Enabled = true; extractCASCSystemFilesToolStripMenuItem.Enabled = true; scanFilesToolStripMenuItem.Enabled = isWoW; analyseUnknownFilesToolStripMenuItem.Enabled = isWoW || gameType == CASCGameType.Overwatch; addFileDataIDToSoundFilesToolStripMenuItem.Enabled = isWoW; analyzeSoundFilesToolStripMenuItem.Enabled = isWoW; localeFlagsToolStripMenuItem.Enabled = CASCGame.SupportsLocaleSelection(gameType); useLVToolStripMenuItem.Enabled = isWoW; exportListfileToolStripMenuItem.Enabled = true; CASCFolder root = viewHelper.Root; TreeNode node = new TreeNode() { Name = root.Name, Tag = root, Text = "Root [Read only]" }; folderTree.Nodes.Add(node); node.Nodes.Add(new TreeNode() { Name = "tempnode" }); // add dummy node node.Expand(); folderTree.SelectedNode = node; if (cfg.OnlineMode) { CDNBuildsToolStripMenuItem.Enabled = true; if (cfg.Builds.Count > 1) { foreach (var bld in cfg.Builds) { CDNBuildsToolStripMenuItem.DropDownItems.Add(bld["build-name"][0]); } } else { CDNBuildsToolStripMenuItem.DropDownItems.Add(cfg.BuildName); } } statusProgress.Visible = false; statusLabel.Text = string.Format("Loaded {0} files ({1} names missing)", casc.Root.CountSelect - casc.Root.CountUnknown, casc.Root.CountUnknown); }
public void Cleanup() { OnCleanup?.Invoke(); Sorter.CASC = null; _root = null; if (_casc != null) { _casc.Clear(); _casc = null; } }
public void Cleanup() { Sorter.CASC = null; _currentFolder = null; _root = null; _displayedEntries?.Clear(); _displayedEntries = null; _casc?.Clear(); _casc = null; OnCleanup?.Invoke(); }
public int CompareTo(ICASCEntry other, int col, CASCHandler 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.Root.GetEntries(Hash); var e2 = casc.Root.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.Root.GetEntries(Hash); var e2 = casc.Root.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; }
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { string arg = (string)e.Argument; CASCConfig.LoadFlags |= LoadFlags.Install; CASCConfig config = _onlineMode ? CASCConfig.LoadOnlineStorageConfig(arg, "us") : CASCConfig.LoadLocalStorageConfig(arg); if (_onlineMode) { using (SelectBuildForm sb = new SelectBuildForm(config)) { var result = sb.ShowDialog(); if (result != DialogResult.OK || sb.SelectedIndex == -1) { e.Cancel = true; return; } config.ActiveBuild = sb.SelectedIndex; } } var casc = CASCHandler.OpenStorage(config, backgroundWorker1); casc.Root.SetFlags(Settings.Default.LocaleFlags, Settings.Default.ContentFlags, false); LoadFileDataComplete(casc); using (var _ = new PerfCounter("LoadListFile()")) { casc.Root.LoadListFile(Settings.Default.ListFilePath, backgroundWorker1); } var fldr = casc.Root.SetFlags(Settings.Default.LocaleFlags, Settings.Default.ContentFlags); casc.Root.MergeInstall(casc.Install); GC.Collect(); e.Result = new object[] { casc, fldr }; }
public static void InitCasc(BackgroundWorkerEx worker = null, string basedir = null, string program = "wowt"){ CASCConfig.LoadFlags &= ~(LoadFlags.Download | LoadFlags.Install); if (basedir == null) { CASCConfig config = CASCConfig.LoadOnlineStorageConfig(program, "us", true); Console.WriteLine("Initializing CASC from web with program " + program + " and build " + config.BuildName); cascHandler = CASCHandler.OpenStorage(config, worker); } else { Console.WriteLine("Initializing CASC from local disk with basedir " + basedir); cascHandler = CASCHandler.OpenLocalStorage(basedir, worker); } cascHandler.Root.SetFlags(LocaleFlags.enUS, ContentFlags.None, false); fIsCASCInit = true; }
public void OpenStorage(bool online, string path, string product) { Cleanup(); using (var initForm = new InitForm()) { initForm.LoadStorage((online, path, product)); DialogResult res = initForm.ShowDialog(); if (res != DialogResult.OK) { return; } _casc = initForm.CASC; _root = initForm.Root; } Sorter.CASC = _casc; OnStorageChanged?.Invoke(); }
public int CompareTo(ICASCEntry other, int col, CASCHandler 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 Initialize(CASCHandler casc, CASCFolder root) { CASC = casc; Root = root; scanner = new FileScanner(CASC, Root); }
public D3RootHandler(BinaryReader stream, BackgroundWorkerEx worker, CASCHandler casc) { worker?.ReportProgress(0, "Loading \"root\"..."); byte b1 = stream.ReadByte(); byte b2 = stream.ReadByte(); byte b3 = stream.ReadByte(); byte b4 = stream.ReadByte(); int count = stream.ReadInt32(); for (int j = 0; j < count; j++) { MD5Hash md5 = stream.Read<MD5Hash>(); string name = stream.ReadCString(); var entries = new List<D3RootEntry>(); D3RootData[name] = entries; EncodingEntry enc; if (!casc.Encoding.GetEntry(md5, out enc)) continue; using (BinaryReader s = new BinaryReader(casc.OpenFile(enc.Key))) { uint magic = s.ReadUInt32(); int nEntries0 = s.ReadInt32(); for (int i = 0; i < nEntries0; i++) { entries.Add(D3RootEntry.Read(0, s)); } int nEntries1 = s.ReadInt32(); for (int i = 0; i < nEntries1; i++) { entries.Add(D3RootEntry.Read(1, s)); } int nNamedEntries = s.ReadInt32(); for (int i = 0; i < nNamedEntries; i++) { entries.Add(D3RootEntry.Read(2, s)); } } worker?.ReportProgress((int)((j + 1) / (float)(count + 2) * 100)); } // Parse CoreTOC.dat var coreTocEntry = D3RootData["Base"].Find(e => e.Name == "CoreTOC.dat"); EncodingEntry enc1; casc.Encoding.GetEntry(coreTocEntry.MD5, out enc1); using (var file = casc.OpenFile(enc1.Key)) tocParser = new CoreTOCParser(file); worker?.ReportProgress((int)((count + 1) / (float)(count + 2) * 100)); // Parse Packages.dat var pkgEntry = D3RootData["Base"].Find(e => e.Name == "Data_D3\\PC\\Misc\\Packages.dat"); EncodingEntry enc2; casc.Encoding.GetEntry(pkgEntry.MD5, out enc2); using (var file = casc.OpenFile(enc2.Key)) pkgParser = new PackagesParser(file); worker?.ReportProgress(100); }
public OWRootHandler(BinaryReader stream, BackgroundWorkerEx worker, CASCHandler casc) { worker?.ReportProgress(0, "Loading \"root\"..."); string str = Encoding.ASCII.GetString(stream.ReadBytes((int)stream.BaseStream.Length)); string[] array = str.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); // need to figure out what to do with those apm files for (int i = 1; i < array.Length; i++) { string[] filedata = array[i].Split('|'); if (Path.GetExtension(filedata[2]) == ".apm") { // add apm file for dev purposes ulong fileHash1 = Hasher.ComputeHash(filedata[2]); RootData[fileHash1] = new RootEntry() { MD5 = filedata[0].ToByteArray(), Block = RootBlock.Empty }; CASCFile.FileNames[fileHash1] = filedata[2]; // add files listed in apm file byte[] md5 = filedata[0].ToByteArray(); EncodingEntry enc = casc.Encoding.GetEntry(md5); using (BinaryReader s = new BinaryReader(casc.OpenFile(enc.Key))) { if (s != null) { // still need to figure out complete apm structure // at start of file there's a lot of data that is same in all apm files s.BaseStream.Position = 0xC; uint count = s.ReadUInt32(); s.BaseStream.Position = 0x894; // size of each entry seems to be 0x48 bytes (0x2C bytes unk data; int size; ulong unk; byte[16] md5) for (int j = 0; j < count; j++) { s.BaseStream.Position += 0x2C; // skip unknown int size = s.ReadInt32(); // size (matches size in encoding file) s.BaseStream.Position += 8; // skip unknown byte[] md5_2 = s.ReadBytes(16); EncodingEntry enc2 = casc.Encoding.GetEntry(md5_2); if (enc2 == null) { throw new Exception("enc2 == null"); } string fakeName = Path.GetFileNameWithoutExtension(filedata[2]) + "/" + md5_2.ToHexString(); ulong fileHash = Hasher.ComputeHash(fakeName); RootData[fileHash] = new RootEntry() { MD5 = md5_2, Block = RootBlock.Empty }; CASCFile.FileNames[fileHash] = fakeName; } } } } } int current = 0; Func<string, LocaleFlags> tag2locale = (s) => { LocaleFlags locale; if (Enum.TryParse(s, out locale)) return locale; return LocaleFlags.All; }; foreach (var entry in casc.Encoding.Entries) { DownloadEntry dl = casc.Download.GetEntry(entry.Value.Key); if (dl != null) { string fakeName = "unknown" + "/" + entry.Key[0].ToString("X2") + "/" + entry.Key.ToHexString(); var locales = dl.Tags.Where(tag => tag.Value.Type == 4).Select(tag => tag2locale(tag.Key)); LocaleFlags locale = LocaleFlags.None; foreach (var loc in locales) locale |= loc; ulong fileHash = Hasher.ComputeHash(fakeName); RootData.Add(fileHash, new RootEntry() { MD5 = entry.Key, Block = new RootBlock() { LocaleFlags = locale } }); CASCFile.FileNames[fileHash] = fakeName; } worker?.ReportProgress((int)(++current / (float)casc.Encoding.Count * 100)); } }
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 GetSize(CASCHandler casc) { EncodingEntry enc; return casc.GetEncodingEntry(hash, out enc) ? enc.Size : 0; }
public D3RootHandler(BinaryReader stream, BackgroundWorkerEx worker, CASCHandler casc) { worker?.ReportProgress(0, "Loading \"root\"..."); byte b1 = stream.ReadByte(); byte b2 = stream.ReadByte(); byte b3 = stream.ReadByte(); byte b4 = stream.ReadByte(); int count = stream.ReadInt32(); for (int j = 0; j < count; j++) { byte[] md5 = stream.ReadBytes(16); string name = stream.ReadCString(); var entries = new List <D3RootEntry>(); D3RootData[name] = entries; EncodingEntry enc = casc.Encoding.GetEntry(md5); using (BinaryReader s = new BinaryReader(casc.OpenFile(enc.Key))) { if (s != null) { uint magic = s.ReadUInt32(); int nEntries0 = s.ReadInt32(); for (int i = 0; i < nEntries0; i++) { entries.Add(D3RootEntry.Read(0, s)); } int nEntries1 = s.ReadInt32(); for (int i = 0; i < nEntries1; i++) { entries.Add(D3RootEntry.Read(1, s)); } int nNamedEntries = s.ReadInt32(); for (int i = 0; i < nNamedEntries; i++) { entries.Add(D3RootEntry.Read(2, s)); } } } worker?.ReportProgress((int)((j + 1) / (float)(count + 2) * 100)); } // Parse CoreTOC.dat var coreTocEntry = D3RootData["Base"].Find(e => e.Name == "CoreTOC.dat"); EncodingEntry enc1 = casc.Encoding.GetEntry(coreTocEntry.MD5); using (var file = casc.OpenFile(enc1.Key)) tocParser = new CoreTOCParser(file); worker?.ReportProgress((int)((count + 1) / (float)(count + 2) * 100)); // Parse Packages.dat var pkgEntry = D3RootData["Base"].Find(e => e.Name == "Data_D3\\PC\\Misc\\Packages.dat"); EncodingEntry enc2 = casc.Encoding.GetEntry(pkgEntry.MD5); using (var file = casc.OpenFile(enc2.Key)) pkgParser = new PackagesParser(file); worker?.ReportProgress(100); }
public static void InitCasc(AsyncAction bgAction = null, string basedir = null, string program = "wowt") { CASC.bgAction = bgAction; //bgAction.ProgressChanged += new EventHandler<AsyncActionProgressChangedEventArgs>(bgAction_ProgressChanged); if (basedir == null) { Console.WriteLine("Initializing CASC from web with program " + program); cascHandler = CASCHandler.OpenOnlineStorage(program, bgAction); } else { Console.WriteLine("Initializing CASC from local disk with basedir " + basedir); cascHandler = CASCHandler.OpenLocalStorage(basedir, bgAction); } cascHandler.Root.SetFlags(LocaleFlags.enUS, ContentFlags.None, false); fIsCASCInit = true; }
public OWRootHandler(BinaryReader stream, BackgroundWorkerEx worker, CASCHandler casc) { worker?.ReportProgress(0, "Loading \"root\"..."); string str = Encoding.ASCII.GetString(stream.ReadBytes((int)stream.BaseStream.Length)); string[] array = str.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); // need to figure out what to do with those apm files for (int i = 1; i < array.Length; i++) { string[] filedata = array[i].Split('|'); if (Path.GetExtension(filedata[2]) == ".apm") { // add apm file for dev purposes ulong fileHash1 = Hasher.ComputeHash(filedata[2]); RootData[fileHash1] = new RootEntry() { MD5 = filedata[0].ToByteArray(), Block = RootBlock.Empty }; CASCFile.FileNames[fileHash1] = filedata[2]; // add files listed in apm file byte[] md5 = filedata[0].ToByteArray(); EncodingEntry enc = casc.Encoding.GetEntry(md5); using (BinaryReader s = new BinaryReader(casc.OpenFile(enc.Key))) { if (s != null) { // still need to figure out complete apm structure // at start of file there's a lot of data that is same in all apm files s.BaseStream.Position = 0xC; uint count = s.ReadUInt32(); s.BaseStream.Position = 0x894; // size of each entry seems to be 0x48 bytes (0x2C bytes unk data; int size; ulong unk; byte[16] md5) for (int j = 0; j < count; j++) { s.BaseStream.Position += 0x2C; // skip unknown int size = s.ReadInt32(); // size (matches size in encoding file) s.BaseStream.Position += 8; // skip unknown byte[] md5_2 = s.ReadBytes(16); EncodingEntry enc2 = casc.Encoding.GetEntry(md5_2); if (enc2 == null) { throw new Exception("enc2 == null"); } string fakeName = Path.GetFileNameWithoutExtension(filedata[2]) + "/" + md5_2.ToHexString(); ulong fileHash = Hasher.ComputeHash(fakeName); RootData[fileHash] = new RootEntry() { MD5 = md5_2, Block = RootBlock.Empty }; CASCFile.FileNames[fileHash] = fakeName; } } } } } int current = 0; Func <string, LocaleFlags> tag2locale = (s) => { LocaleFlags locale; if (Enum.TryParse(s, out locale)) { return(locale); } return(LocaleFlags.All); }; foreach (var entry in casc.Encoding.Entries) { DownloadEntry dl = casc.Download.GetEntry(entry.Value.Key); if (dl != null) { string fakeName = "unknown" + "/" + entry.Key[0].ToString("X2") + "/" + entry.Key.ToHexString(); var locales = dl.Tags.Where(tag => tag.Value.Type == 4).Select(tag => tag2locale(tag.Key)); LocaleFlags locale = LocaleFlags.None; foreach (var loc in locales) { locale |= loc; } ulong fileHash = Hasher.ComputeHash(fakeName); RootData.Add(fileHash, new RootEntry() { MD5 = entry.Key, Block = new RootBlock() { LocaleFlags = locale } }); CASCFile.FileNames[fileHash] = fakeName; } worker?.ReportProgress((int)(++current / (float)casc.Encoding.Count * 100)); } }
public APMFile(string name, Stream stream, CASCHandler casc) { Name = name; using (BinaryReader reader = new BinaryReader(stream)) { ulong buildVersion = reader.ReadUInt64(); uint buildNumber = reader.ReadUInt32(); uint packageCount = reader.ReadUInt32(); uint entryCount = reader.ReadUInt32(); uint unk = reader.ReadUInt32(); entries = new APMEntry[entryCount]; for (int j = 0; j < entryCount; j++) { entries[j] = reader.Read<APMEntry>(); } packages = new APMPackage[packageCount]; indexes = new PackageIndex[packageCount]; records = new PackageIndexRecord[packageCount][]; dependencies = new uint[packageCount][]; for (int j = 0; j < packages.Length; j++) { packages[j] = reader.Read<APMPackage>(); EncodingEntry pkgIndexEnc; if (!casc.Encoding.GetEntry(packages[j].indexContentKey, out pkgIndexEnc)) throw new Exception("pkgIndexEnc missing"); using (Stream pkgIndexStream = casc.OpenFile(pkgIndexEnc.Key)) using (BinaryReader pkgIndexReader = new BinaryReader(pkgIndexStream)) { indexes[j] = pkgIndexReader.Read<PackageIndex>(); pkgIndexStream.Position = indexes[j].recordsOffset; using (GZipStream recordsStream = new GZipStream(pkgIndexStream, CompressionMode.Decompress, true)) using (BinaryReader recordsReader = new BinaryReader(recordsStream)) { PackageIndexRecord[] recs = new PackageIndexRecord[indexes[j].numRecords]; for (int k = 0; k < recs.Length; k++) recs[k] = recordsReader.Read<PackageIndexRecord>(); records[j] = recs; } pkgIndexStream.Position = indexes[j].depsOffset; uint[] deps = new uint[indexes[j].numDeps]; for (int k = 0; k < deps.Length; k++) deps[k] = pkgIndexReader.ReadUInt32(); dependencies[j] = deps; } } } }
public OwRootHandler(BinaryReader stream, BackgroundWorkerEx worker, CASCHandler casc) { worker?.ReportProgress(0, "Loading \"root\"..."); string str = Encoding.ASCII.GetString(stream.ReadBytes((int)stream.BaseStream.Length)); string[] array = str.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); List<string> APMNames = new List<string>(); for (int i = 1; i < array.Length; i++) { string[] filedata = array[i].Split('|'); string name = filedata[4]; if (Path.GetExtension(name) == ".apm" && name.Contains("RDEV")) { APMNames.Add(Path.GetFileNameWithoutExtension(name)); if(!name.Contains("L"+LanguageScan)) { continue; } // add apm file for dev purposes ulong apmNameHash = Hasher.ComputeHash(name); MD5Hash apmMD5 = filedata[0].ToByteArray().ToMD5(); _rootData[apmNameHash] = new OWRootEntry() { baseEntry = new RootEntry() { MD5 = apmMD5, LocaleFlags = LocaleFlags.All, ContentFlags = ContentFlags.None } }; CASCFile.FileNames[apmNameHash] = name; EncodingEntry apmEnc; if (!casc.Encoding.GetEntry(apmMD5, out apmEnc)) continue; using (Stream apmStream = casc.OpenFile(apmEnc.Key)) { apmFiles.Add(new APMFile(name, apmStream, casc)); } } worker?.ReportProgress((int)(i / (array.Length / 100f))); } APMList = APMNames.ToArray(); APMNames.Clear(); }
public int GetSize(CASCHandler casc) { EncodingEntry enc; return(casc.GetEncodingEntry(hash, out enc) ? enc.Size : 0); }
public APMFile(string name, Stream stream, CASCHandler casc) { Name = name; using (BinaryReader reader = new BinaryReader(stream)) { ulong buildVersion = reader.ReadUInt64(); uint buildNumber = reader.ReadUInt32(); uint packageCount = reader.ReadUInt32(); uint entryCount = reader.ReadUInt32(); uint unk = reader.ReadUInt32(); entries = new APMEntry[entryCount]; for (int j = 0; j < entryCount; j++) { entries[j] = reader.Read <APMEntry>(); } packages = new APMPackage[packageCount]; indexes = new PackageIndex[packageCount]; records = new PackageIndexRecord[packageCount][]; dependencies = new uint[packageCount][]; for (int j = 0; j < packages.Length; j++) { packages[j] = reader.Read <APMPackage>(); if (!casc.Encoding.GetEntry(packages[j].indexContentKey, out EncodingEntry pkgIndexEnc)) { throw new Exception("pkgIndexEnc missing"); } using (Stream pkgIndexStream = casc.OpenFile(pkgIndexEnc.Key)) using (BinaryReader pkgIndexReader = new BinaryReader(pkgIndexStream)) { indexes[j] = pkgIndexReader.Read <PackageIndex>(); pkgIndexStream.Position = indexes[j].recordsOffset; using (GZipStream recordsStream = new GZipStream(pkgIndexStream, CompressionMode.Decompress, true)) using (BinaryReader recordsReader = new BinaryReader(recordsStream)) { PackageIndexRecord[] recs = new PackageIndexRecord[indexes[j].numRecords]; for (int k = 0; k < recs.Length; k++) { recs[k] = recordsReader.Read <PackageIndexRecord>(); } records[j] = recs; } pkgIndexStream.Position = indexes[j].depsOffset; uint[] deps = new uint[indexes[j].numDeps]; for (int k = 0; k < deps.Length; k++) { deps[k] = pkgIndexReader.ReadUInt32(); } dependencies[j] = deps; } } } }
public FileScanner(CASCHandler casc, CASCFolder root) { CASC = casc; Root = root; }
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 void OpenStorage(string arg, bool online) { Cleanup(); using (var initForm = new InitForm()) { if (online) initForm.LoadOnlineStorage(arg); else initForm.LoadLocalStorage(arg); DialogResult res = initForm.ShowDialog(); if (res != DialogResult.OK) return; _casc = initForm.CASC; _root = initForm.Root; } Sorter.CASC = _casc; OnStorageChanged?.Invoke(); }
public void LoadFileDataComplete(CASCHandler casc) { if (!casc.FileExists("DBFilesClient\\FileDataComplete.db2")) return; Logger.WriteLine("WowRootHandler: loading file names from FileDataComplete.db2..."); using (var s = casc.OpenFile("DBFilesClient\\FileDataComplete.db2")) { DB5Reader fd = new DB5Reader(s); foreach (var row in fd) { string path = row.Value.GetField<string>(0); string name = row.Value.GetField<string>(1); string fullname = path + name; ulong fileHash = Hasher.ComputeHash(fullname); // skip invalid names if (!RootData.ContainsKey(fileHash)) { //Logger.WriteLine("Invalid file name: {0}", fullname); continue; } CASCFile.FileNames[fileHash] = fullname; } } }
public int CompareTo(ICASCEntry other, int col, CASCHandler 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 int GetSize(CASCHandler casc) { var encoding = casc.GetEncodingEntry(hash); if (encoding != null) return encoding.Size; return 0; }