예제 #1
0
 public void SetExtractData(CASCHandler handler, ICollection <CASCFile> files)
 {
     NumExtracted       = 0;
     progressBar1.Value = 0;
     CASC       = handler;
     this.files = files;
 }
예제 #2
0
        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);
                }
            }
        }
예제 #3
0
        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 };
        }
예제 #4
0
 public void SetExtractData(CASCHandler handler, ICollection<CASCFile> files)
 {
     NumExtracted = 0;
     progressBar1.Value = 0;
     CASC = handler;
     this.files = files;
 }
예제 #5
0
        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();
        }
예제 #6
0
 public void SetExtractData(CASCHandler cascHandler, ICollection<CASCFile> files)
 {
     this.cascHandler = cascHandler;
     NumExtracted = 0;
     NumFiles = files.Count;
     progressBar1.Value = 0;
     this.files = files;
 }
예제 #7
0
        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;
        }
예제 #8
0
 public void SetExtractData(CASCHandler cascHandler, ICollection <CASCFile> files)
 {
     this.cascHandler   = cascHandler;
     NumExtracted       = 0;
     NumFiles           = files.Count;
     progressBar1.Value = 0;
     this.files         = files;
 }
예제 #9
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;
 }
예제 #10
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;
 }
예제 #11
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);
        }
예제 #12
0
        public int GetSize(CASCHandler casc)
        {
            var encoding = casc.GetEncodingEntry(hash);

            if (encoding != null)
            {
                return(encoding.Size);
            }

            return(0);
        }
예제 #13
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;
        }
예제 #14
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;
        }
예제 #15
0
        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();
        }
예제 #16
0
        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);
        }
예제 #17
0
        public void Cleanup()
        {
            OnCleanup?.Invoke();

            Sorter.CASC = null;

            _root = null;

            if (_casc != null)
            {
                _casc.Clear();
                _casc = null;
            }
        }
예제 #18
0
        public void Cleanup()
        {
            Sorter.CASC = null;

            _currentFolder = null;
            _root          = null;

            _displayedEntries?.Clear();
            _displayedEntries = null;

            _casc?.Clear();
            _casc = null;

            OnCleanup?.Invoke();
        }
예제 #19
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().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;
        }
예제 #20
0
        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 };
        }
예제 #21
0
        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;
        }
예제 #22
0
        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();
        }
예제 #23
0
        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);
        }
예제 #24
0
파일: ScanForm.cs 프로젝트: aeo24/WoWMap
 public void Initialize(CASCHandler casc, CASCFolder root)
 {
     CASC = casc;
     Root = root;
     scanner = new FileScanner(CASC, Root);
 }
예제 #25
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++)
            {
                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);
        }
예제 #26
0
        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));
            }
        }
예제 #27
0
        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);
        }
예제 #28
0
        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;
        }
예제 #29
0
 public int GetSize(CASCHandler casc)
 {
     EncodingEntry enc;
     return casc.GetEncodingEntry(hash, out enc) ? enc.Size : 0;
 }
예제 #30
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);
        }
예제 #31
0
        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;
        }
예제 #32
0
        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));
            }
        }
예제 #33
0
        public void Cleanup()
        {
            Sorter.CASC = null;

            _currentFolder = null;
            _root = null;

            _displayedEntries?.Clear();
            _displayedEntries = null;

            _casc?.Clear();
            _casc = null;

            OnCleanup?.Invoke();
        }
예제 #34
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>();

                    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;
                    }
                }
            }
        }
예제 #35
0
        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();
        }
예제 #36
0
        public int GetSize(CASCHandler casc)
        {
            EncodingEntry enc;

            return(casc.GetEncodingEntry(hash, out enc) ? enc.Size : 0);
        }
예제 #37
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;
                        }
                }
            }
        }
예제 #38
0
파일: FileScanner.cs 프로젝트: aeo24/WoWMap
 public FileScanner(CASCHandler casc, CASCFolder root)
 {
     CASC = casc;
     Root = root;
 }
예제 #39
0
        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;
        }
예제 #40
0
        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();
        }
예제 #41
0
        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;
                }
            }
        }
예제 #42
0
        public void Cleanup()
        {
            OnCleanup?.Invoke();

            Sorter.CASC = null;

            _root = null;

            if (_casc != null)
            {
                _casc.Clear();
                _casc = null;
            }
        }
예제 #43
0
        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;
        }
예제 #44
0
파일: ScanForm.cs 프로젝트: lyragosa/aleph
 public void Initialize(CASCHandler casc, CASCFolder root)
 {
     CASC    = casc;
     Root    = root;
     scanner = new FileScanner(CASC, Root);
 }
예제 #45
0
 public FileScanner(CASCHandler casc, CASCFolder root)
 {
     CASC = casc;
     Root = root;
 }
예제 #46
0
파일: CASCEntry.cs 프로젝트: aeo24/WoWMap
        public int GetSize(CASCHandler casc)
        {
            var encoding = casc.GetEncodingEntry(hash);

            if (encoding != null)
                return encoding.Size;

            return 0;
        }