예제 #1
0
        public CASCHandlerBase(CASCConfig config, BackgroundWorkerEx worker)
        {
            Config = config;

            Logger.WriteLine("CASCHandlerBase: loading CDN indices...");

            using (var _ = new PerfCounter("CDNIndexHandler.Initialize()"))
            {
                CDNIndex = CDNIndexHandler.Initialize(config, worker);
            }

            Logger.WriteLine("CASCHandlerBase: loaded {0} CDN indexes", CDNIndex.Count);

            if (!config.OnlineMode)
            {
                CDNIndexHandler.Cache.Enabled = false;

                Logger.WriteLine("CASCHandlerBase: loading local indices...");

                using (var _ = new PerfCounter("LocalIndexHandler.Initialize()"))
                {
                    LocalIndex = LocalIndexHandler.Initialize(config, worker);
                }

                Logger.WriteLine("CASCHandlerBase: loaded {0} local indexes", LocalIndex.Count);
            }
        }
예제 #2
0
        private CASCHandlerLite(CASCConfig config, LocaleFlags locale, BackgroundWorkerEx worker) : base(config, worker)
        {
            if (config.GameType != CASCGameType.WoW)
                throw new Exception("Unsupported game " + config.BuildUID);

            Logger.WriteLine("CASCHandlerLite: loading encoding data...");

            EncodingHandler EncodingHandler;

            using (var _ = new PerfCounter("new EncodingHandler()"))
            {
                using (var fs = OpenEncodingFile(this))
                    EncodingHandler = new EncodingHandler(fs, worker);
            }

            Logger.WriteLine("CASCHandlerLite: loaded {0} encoding data", EncodingHandler.Count);

            Logger.WriteLine("CASCHandlerLite: loading root data...");

            RootHandlerBase RootHandler;

            using (var _ = new PerfCounter("new RootHandler()"))
            {
                using (var fs = OpenRootFile(EncodingHandler, this))
                    RootHandler = new WowRootHandler(fs, worker);
            }

            Logger.WriteLine("CASCHandlerLite: loaded {0} root data", RootHandler.Count);

            RootHandler.SetFlags(locale, ContentFlags.None, false);

            RootEntry rootEntry;

            foreach (var entry in RootHandler.GetAllEntries())
            {
                rootEntry = entry.Value;

                if ((rootEntry.Block.LocaleFlags == locale || (rootEntry.Block.LocaleFlags & locale) != LocaleFlags.None) && (rootEntry.Block.ContentFlags & ContentFlags.LowViolence) == ContentFlags.None)
                {
                    var enc = EncodingHandler.GetEntry(rootEntry.MD5);

                    if (enc != null)
                    {
                        if (!HashToKey.ContainsKey(entry.Key))
                        {
                            HashToKey.Add(entry.Key, enc.Key);
                            FileDataIdToHash.Add(rootEntry.FileDataId, entry.Key);
                        }
                    }
                }
            }

            RootHandler.Clear();
            EncodingHandler.Clear();
            RootHandler = null;
            EncodingHandler = null;
            GC.Collect();

            Logger.WriteLine("CASCHandlerLite: loaded {0} files", HashToKey.Count);
        }
예제 #3
0
        public SelectBuildForm(CASCConfig config)
        {
            InitializeComponent();

            foreach (var cfg in config.Builds)
            {
                listBox1.Items.Add(cfg["build-name"][0]);
            }

            listBox1.SelectedIndex = 0;
        }
예제 #4
0
        public static Stream OpenConfigFileDirect(CASCConfig cfg, string key)
        {
            string file = cfg.CDNPath + "/config/" + key.Substring(0, 2) + "/" + key.Substring(2, 2) + "/" + key;
            string url = "http://" + cfg.CDNHost + "/" + file;

            Stream stream = Cache.OpenFile(file, url, false);

            if (stream != null)
                return stream;

            return OpenFileDirect(url);
        }
예제 #5
0
        public SelectBuildForm(CASCConfig config)
        {
            InitializeComponent();

            if (config.Builds.Count > 1)
            {
                foreach (var cfg in config.Builds)
                {
                    listBox1.Items.Add(cfg["build-name"][0]);
                }
            }
            else
                listBox1.Items.Add(config.BuildName);

            listBox1.SelectedIndex = 0;
        }
예제 #6
0
        public static CDNHandler Initialize(CASCConfig config)
        {
            var handler = new CDNHandler(config);

            for (int i = 0; i < config.Archives.Count; i++)
            {
                string index = config.Archives[i];

                if (config.OnlineMode)
                    handler.DownloadFile(index, i);
                else
                    handler.OpenFile(index, i);
            }

            Logger.WriteLine("CDNHandler: loaded {0} indexes", handler.CDNIndexData.Count);
            return handler;
        }
예제 #7
0
        private static List<string> GetIdxFiles(CASCConfig config)
        {
            List<string> latestIdx = new List<string>();

            string dataFolder = CASCGame.GetDataFolder(config.GameType);
            string dataPath = Path.Combine(dataFolder, "data");

            for (int i = 0; i < 0x10; ++i)
            {
                var files = Directory.EnumerateFiles(Path.Combine(config.BasePath, dataPath), string.Format("{0:X2}*.idx", i));

                if (files.Count() > 0)
                    latestIdx.Add(files.Last());
            }

            return latestIdx;
        }
예제 #8
0
        public static CDNIndexHandler Initialize(CASCConfig config, BackgroundWorkerEx worker)
        {
            var handler = new CDNIndexHandler(config, worker);

            worker?.ReportProgress(0, "Loading \"CDN indexes\"...");

            for (int i = 0; i < config.Archives.Count; i++)
            {
                string archive = config.Archives[i];

                if (config.OnlineMode)
                    handler.DownloadIndexFile(archive, i);
                else
                    handler.OpenIndexFile(archive, i);

                worker?.ReportProgress((int)((i + 1) / (float)config.Archives.Count * 100));
            }

            return handler;
        }
예제 #9
0
        public static LocalIndexHandler Initialize(CASCConfig config, BackgroundWorkerEx worker)
        {
            var handler = new LocalIndexHandler();

            var idxFiles = GetIdxFiles(config);

            if (idxFiles.Count == 0)
                throw new FileNotFoundException("idx files missing!");

            worker?.ReportProgress(0, "Loading \"local indexes\"...");

            int idxIndex = 0;

            foreach (var idx in idxFiles)
            {
                handler.ParseIndex(idx);

                worker?.ReportProgress((int)(++idxIndex / (float)idxFiles.Count * 100));
            }

            Logger.WriteLine("LocalIndexHandler: loaded {0} indexes", handler.Count);

            return handler;
        }
예제 #10
0
        private static CASCHandler Open(BackgroundWorker worker, CASCConfig config)
        {
            var cdn = CDNHandler.Initialize(config);

            return(new CASCHandler(config, cdn, worker));
        }
예제 #11
0
        private CASCHandler(CASCConfig config, BackgroundWorkerEx worker) : base(config, worker)
        {
            Logger.WriteLine("CASCHandler: loading encoding data...");

            using (var _ = new PerfCounter("new EncodingHandler()"))
            {
                using (var fs = OpenEncodingFile(this))
                    EncodingHandler = new EncodingHandler(fs, worker);
            }

            Logger.WriteLine("CASCHandler: loaded {0} encoding data", EncodingHandler.Count);

            if ((CASCConfig.LoadFlags & LoadFlags.Download) != 0)
            {
                Logger.WriteLine("CASCHandler: loading download data...");

                using (var _ = new PerfCounter("new DownloadHandler()"))
                {
                    using (var fs = OpenDownloadFile(EncodingHandler, this))
                        DownloadHandler = new DownloadHandler(fs, worker);
                }

                Logger.WriteLine("CASCHandler: loaded {0} download data", EncodingHandler.Count);
            }

            Logger.WriteLine("CASCHandler: loading root data...");

            using (var _ = new PerfCounter("new RootHandler()"))
            {
                using (var fs = OpenRootFile(EncodingHandler, this))
                {
                    if (config.GameType == CASCGameType.S2 || config.GameType == CASCGameType.HotS)
                        RootHandler = new MNDXRootHandler(fs, worker);
                    else if (config.GameType == CASCGameType.D3)
                        RootHandler = new D3RootHandler(fs, worker, this);
                    else if (config.GameType == CASCGameType.WoW)
                        RootHandler = new WowRootHandler(fs, worker);
                    else if (config.GameType == CASCGameType.Agent || config.GameType == CASCGameType.Bna || config.GameType == CASCGameType.Client)
                        RootHandler = new AgentRootHandler(fs, worker);
                    else if (config.GameType == CASCGameType.Hearthstone)
                        RootHandler = new HSRootHandler(fs, worker);
                    else if (config.GameType == CASCGameType.Overwatch)
                        RootHandler = new OwRootHandler(fs, worker, this);
                    else
                        throw new Exception("Unsupported game " + config.BuildUID);
                }
            }

            Logger.WriteLine("CASCHandler: loaded {0} root data", RootHandler.Count);

            if ((CASCConfig.LoadFlags & LoadFlags.Install) != 0)
            {
                Logger.WriteLine("CASCHandler: loading install data...");

                using (var _ = new PerfCounter("new InstallHandler()"))
                {
                    using (var fs = OpenInstallFile(EncodingHandler, this))
                        InstallHandler = new InstallHandler(fs, worker);

                    InstallHandler.Print();
                }

                Logger.WriteLine("CASCHandler: loaded {0} install data", InstallHandler.Count);
            }
        }
예제 #12
0
파일: CASCHandler.cs 프로젝트: aeo24/WoWMap
        private CASCHandler(CASCConfig config, BackgroundWorkerEx worker)
        {
            Config = config;

            Logger.WriteLine("CASCHandler: loading CDN indices...");

            using (var _ = new PerfCounter("CDNIndexHandler.Initialize()"))
            {
                CDNIndex = CDNIndexHandler.Initialize(config, worker);
            }

            Logger.WriteLine("CASCHandler: loaded {0} CDN indexes", CDNIndex.Count);

            if (!config.OnlineMode)
            {
                CDNIndexHandler.Cache.Enabled = false;

                Logger.WriteLine("CASCHandler: loading local indices...");

                using (var _ = new PerfCounter("LocalIndexHandler.Initialize()"))
                {
                    LocalIndex = LocalIndexHandler.Initialize(config, worker);
                }

                Logger.WriteLine("CASCHandler: loaded {0} local indexes", LocalIndex.Count);
            }

            Logger.WriteLine("CASCHandler: loading encoding data...");

            using (var _ = new PerfCounter("new EncodingHandler()"))
            {
                using (var fs = OpenEncodingFile())
                    EncodingHandler = new EncodingHandler(fs, worker);
            }

            Logger.WriteLine("CASCHandler: loaded {0} encoding data", EncodingHandler.Count);

            if ((CASCConfig.LoadFlags & LoadFlags.Download) != 0)
            {
                Logger.WriteLine("CASCHandler: loading download data...");

                using (var _ = new PerfCounter("new DownloadHandler()"))
                {
                    using (var fs = OpenDownloadFile())
                        DownloadHandler = new DownloadHandler(fs, worker);
                }

                Logger.WriteLine("CASCHandler: loaded {0} download data", EncodingHandler.Count);
            }

            Logger.WriteLine("CASCHandler: loading root data...");

            using (var _ = new PerfCounter("new RootHandler()"))
            {
                using (var fs = OpenRootFile())
                {
                    if (config.GameType == CASCGameType.S2 || config.GameType == CASCGameType.HotS)
                        RootHandler = new MNDXRootHandler(fs, worker);
                    else if (config.GameType == CASCGameType.D3)
                        RootHandler = new D3RootHandler(fs, worker, this);
                    else if (config.GameType == CASCGameType.WoW)
                        RootHandler = new WowRootHandler(fs, worker);
                    else if (config.GameType == CASCGameType.Agent)
                        RootHandler = new AgentRootHandler(fs, worker);
                    else if (config.GameType == CASCGameType.Hearthstone)
                        RootHandler = new HSRootHandler(fs, worker);
                    else if (config.GameType == CASCGameType.Overwatch)
                        RootHandler = new OWRootHandler(fs, worker, this);
                    else
                        throw new Exception("Unsupported game " + config.BuildUID);
                }
            }

            Logger.WriteLine("CASCHandler: loaded {0} root data", RootHandler.Count);

            if ((CASCConfig.LoadFlags & LoadFlags.Install) != 0)
            {
                Logger.WriteLine("CASCHandler: loading install data...");

                using (var _ = new PerfCounter("new InstallHandler()"))
                {
                    using (var fs = OpenInstallFile())
                        InstallHandler = new InstallHandler(fs, worker);
                }

                Logger.WriteLine("CASCHandler: loaded {0} install data", InstallHandler.Count);
            }
        }
예제 #13
0
 private static CASCHandler Open(BackgroundWorker worker, CASCConfig config)
 {
     var cdn = CDNHandler.Initialize(config);
     return new CASCHandler(config, cdn, worker);
 }
예제 #14
0
        public void Clear()
        {
            CDNIndexData.Clear();
            CDNIndexData = null;

            config = null;
            worker = null;
            downloader = null;
        }
예제 #15
0
        public static CASCHandler OpenLocalStorage(string basePath, BackgroundWorkerEx worker = null)
        {
            CASCConfig config = CASCConfig.LoadLocalStorageConfig(basePath);

            return(Open(worker, config));
        }
예제 #16
0
 public static CASCHandler OpenStorage(CASCConfig config, BackgroundWorkerEx worker = null)
 {
     return(Open(worker, config));
 }
예제 #17
0
 private CDNHandler(CASCConfig cascConfig)
 {
     CASCConfig = cascConfig;
 }
예제 #18
0
 private CDNIndexHandler(CASCConfig cascConfig, BackgroundWorkerEx worker)
 {
     config      = cascConfig;
     this.worker = worker;
     downloader  = new SyncDownloader(worker);
 }
예제 #19
0
        private CASCHandler(CASCConfig config, CDNHandler cdn, BackgroundWorker worker)
        {
            this.config = config;
            this.cdn    = cdn;
            if (!config.OnlineMode)
            {
                var idxFiles = GetIdxFiles(this.config.BasePath);

                if (idxFiles.Count == 0)
                {
                    throw new FileNotFoundException("idx files missing!");
                }

                if (worker != null)
                {
                    worker.ReportProgress(0);
                }

                int idxIndex = 0;

                foreach (var idx in idxFiles)
                {
                    using (var fs = new FileStream(idx, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                        using (var br = new BinaryReader(fs))
                        {
                            int    h2Len   = br.ReadInt32();
                            int    h2Check = br.ReadInt32();
                            byte[] h2      = br.ReadBytes(h2Len);

                            long padPos = (8 + h2Len + 0x0F) & 0xFFFFFFF0;
                            fs.Position = padPos;

                            int dataLen   = br.ReadInt32();
                            int dataCheck = br.ReadInt32();

                            int numBlocks = dataLen / 18;

                            for (int i = 0; i < numBlocks; i++)
                            {
                                IndexEntry info      = new IndexEntry();
                                byte[]     key       = br.ReadBytes(9);
                                int        indexHigh = br.ReadByte();
                                int        indexLow  = br.ReadInt32BE();

                                info.Index  = (int)((byte)(indexHigh << 2) | ((indexLow & 0xC0000000) >> 30));
                                info.Offset = (indexLow & 0x3FFFFFFF);
                                info.Size   = br.ReadInt32();

                                // duplicate keys wtf...
                                //IndexData[key] = info; // use last key
                                if (!LocalIndexData.ContainsKey(key)) // use first key
                                {
                                    LocalIndexData.Add(key, info);
                                }
                            }

                            padPos      = (dataLen + 0x0FFF) & 0xFFFFF000;
                            fs.Position = padPos;

                            fs.Position += numBlocks * 18;
                            //for (int i = 0; i < numBlocks; i++)
                            //{
                            //    var bytes = br.ReadBytes(18); // unknown data
                            //}

                            if (fs.Position != fs.Position)
                            {
                                throw new Exception("idx file under read");
                            }
                        }

                    if (worker != null)
                    {
                        worker.ReportProgress((int)((float)++idxIndex / (float)idxFiles.Count * 100));
                    }
                }

                Logger.WriteLine("CASCHandler: loaded {0} indexes", LocalIndexData.Count);
            }

            if (worker != null)
            {
                worker.ReportProgress(0);
            }

            using (var fs = OpenEncodingFile())
                using (var br = new BinaryReader(fs))
                {
                    br.ReadBytes(2); // EN
                    byte   b1         = br.ReadByte();
                    byte   b2         = br.ReadByte();
                    byte   b3         = br.ReadByte();
                    ushort s1         = br.ReadUInt16();
                    ushort s2         = br.ReadUInt16();
                    int    numEntries = br.ReadInt32BE();
                    int    i1         = br.ReadInt32BE();
                    byte   b4         = br.ReadByte();
                    int    entriesOfs = br.ReadInt32BE();

                    fs.Position += entriesOfs; // skip strings

                    fs.Position += numEntries * 32;
                    //for (int i = 0; i < numEntries; ++i)
                    //{
                    //    br.ReadBytes(16);
                    //    br.ReadBytes(16);
                    //}

                    for (int i = 0; i < numEntries; ++i)
                    {
                        ushort keysCount;

                        while ((keysCount = br.ReadUInt16()) != 0)
                        {
                            int    fileSize = br.ReadInt32BE();
                            byte[] md5      = br.ReadBytes(16);

                            var entry = new EncodingEntry();
                            entry.Size = fileSize;

                            for (int ki = 0; ki < keysCount; ++ki)
                            {
                                byte[] key = br.ReadBytes(16);

                                entry.Keys.Add(key);
                            }

                            //Encodings[md5] = entry;
                            EncodingData.Add(md5, entry);
                        }

                        //br.ReadBytes(28);
                        while (br.PeekChar() == 0)
                        {
                            fs.Position++;
                        }

                        if (worker != null)
                        {
                            worker.ReportProgress((int)((float)fs.Position / (float)fs.Length * 100));
                        }
                    }
                    //var pos = br.BaseStream.Position;
                    //for (int i = 0; i < i1; ++i)
                    //{
                    //    br.ReadBytes(16);
                    //    br.ReadBytes(16);
                    //}
                    Logger.WriteLine("CASCHandler: loaded {0} encoding data", EncodingData.Count);
                }

            if (worker != null)
            {
                worker.ReportProgress(0);
            }

            using (var fs = OpenRootFile())
                using (var br = new BinaryReader(fs))
                {
                    while (fs.Position < fs.Length)
                    {
                        int count = br.ReadInt32();

                        RootBlock block = new RootBlock();
                        block.Unk1  = br.ReadUInt32();
                        block.Flags = (LocaleFlags)br.ReadUInt32();

                        if (block.Flags == LocaleFlags.None)
                        {
                            throw new Exception("block.Flags == LocaleFlags.None");
                        }

                        RootEntry[] entries = new RootEntry[count];

                        for (var i = 0; i < count; ++i)
                        {
                            entries[i]       = new RootEntry();
                            entries[i].Block = block;
                            entries[i].Unk1  = br.ReadInt32();
                        }

                        for (var i = 0; i < count; ++i)
                        {
                            entries[i].MD5 = br.ReadBytes(16);

                            ulong hash = br.ReadUInt64();
                            entries[i].Hash = hash;

                            // don't load other locales
                            //if (block.Flags != LocaleFlags.All && (block.Flags & LocaleFlags.enUS) == 0)
                            //    continue;

                            if (!RootData.ContainsKey(hash))
                            {
                                RootData[hash] = new List <RootEntry>();
                                RootData[hash].Add(entries[i]);
                            }
                            else
                            {
                                RootData[hash].Add(entries[i]);
                            }
                        }

                        if (worker != null)
                        {
                            worker.ReportProgress((int)((float)fs.Position / (float)fs.Length * 100));
                        }
                    }

                    Logger.WriteLine("CASCHandler: loaded {0} root data", RootData.Count);
                }

            if (worker != null)
            {
                worker.ReportProgress(0);
            }
        }
예제 #20
0
 private static CASCHandlerLite Open(LocaleFlags locale, BackgroundWorkerEx worker, CASCConfig config)
 {
     using (var _ = new PerfCounter("new CASCHandlerLite()"))
     {
         return new CASCHandlerLite(config, locale, worker);
     }
 }
예제 #21
0
 private CDNIndexHandler(CASCConfig cascConfig, BackgroundWorkerEx worker)
 {
     config = cascConfig;
     this.worker = worker;
     downloader = new SyncDownloader(worker);
 }
예제 #22
0
        public static CASCHandler OpenOnlineStorage(string product, string region = "us", BackgroundWorkerEx worker = null)
        {
            CASCConfig config = CASCConfig.LoadOnlineStorageConfig(product, region);

            return(Open(worker, config));
        }
예제 #23
0
 public static CASCHandlerLite OpenStorage(LocaleFlags locale, CASCConfig config, BackgroundWorkerEx worker = null)
 {
     return(Open(locale, worker, config));
 }
예제 #24
0
        private CASCHandler(CASCConfig config, BackgroundWorkerEx worker) : base(config, worker)
        {
            Logger.WriteLine("CASCHandler: loading encoding data...");

            using (var _ = new PerfCounter("new EncodingHandler()"))
            {
                using (var fs = OpenEncodingFile(this))
                    EncodingHandler = new EncodingHandler(fs, worker);
            }

            Logger.WriteLine("CASCHandler: loaded {0} encoding data", EncodingHandler.Count);

            if ((CASCConfig.LoadFlags & LoadFlags.Download) != 0)
            {
                Logger.WriteLine("CASCHandler: loading download data...");

                using (var _ = new PerfCounter("new DownloadHandler()"))
                {
                    using (var fs = OpenDownloadFile(EncodingHandler, this))
                        DownloadHandler = new DownloadHandler(fs, worker);
                }

                Logger.WriteLine("CASCHandler: loaded {0} download data", EncodingHandler.Count);
            }

            Logger.WriteLine("CASCHandler: loading root data...");

            using (var _ = new PerfCounter("new RootHandler()"))
            {
                using (var fs = OpenRootFile(EncodingHandler, this))
                {
                    if (config.GameType == CASCGameType.S2 || config.GameType == CASCGameType.HotS)
                    {
                        RootHandler = new MNDXRootHandler(fs, worker);
                    }
                    else if (config.GameType == CASCGameType.D3)
                    {
                        RootHandler = new D3RootHandler(fs, worker, this);
                    }
                    else if (config.GameType == CASCGameType.WoW)
                    {
                        RootHandler = new WowRootHandler(fs, worker);
                    }
                    else if (config.GameType == CASCGameType.Agent || config.GameType == CASCGameType.Bna || config.GameType == CASCGameType.Client)
                    {
                        RootHandler = new AgentRootHandler(fs, worker);
                    }
                    else if (config.GameType == CASCGameType.Hearthstone)
                    {
                        RootHandler = new HSRootHandler(fs, worker);
                    }
                    else if (config.GameType == CASCGameType.Overwatch)
                    {
                        RootHandler = new OWRootHandler(fs, worker, this);
                    }
                    else
                    {
                        throw new Exception("Unsupported game " + config.BuildUID);
                    }
                }
            }

            Logger.WriteLine("CASCHandler: loaded {0} root data", RootHandler.Count);

            if ((CASCConfig.LoadFlags & LoadFlags.Install) != 0)
            {
                Logger.WriteLine("CASCHandler: loading install data...");

                using (var _ = new PerfCounter("new InstallHandler()"))
                {
                    using (var fs = OpenInstallFile(EncodingHandler, this))
                        InstallHandler = new InstallHandler(fs, worker);
                }

                Logger.WriteLine("CASCHandler: loaded {0} install data", InstallHandler.Count);
            }
        }
예제 #25
0
 private static CASCHandlerLite Open(LocaleFlags locale, BackgroundWorkerEx worker, CASCConfig config)
 {
     using (var _ = new PerfCounter("new CASCHandlerLite()"))
     {
         return(new CASCHandlerLite(config, locale, worker));
     }
 }
예제 #26
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);

            (casc.Root as WowRootHandler)?.LoadFileDataComplete(casc);

            using (var _ = new PerfCounter("LoadListFile()"))
            {
                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);

            GC.Collect();

            e.Result = new object[] { casc, fldr };
        }
예제 #27
0
        private CASCHandler(CASCConfig config, CDNHandler cdn, BackgroundWorker worker)
        {
            this.config = config;
            this.cdn = cdn;
            if (!config.OnlineMode)
            {
                var idxFiles = GetIdxFiles(this.config.BasePath);

                if (idxFiles.Count == 0)
                    throw new FileNotFoundException("idx files missing!");

                if (worker != null) worker.ReportProgress(0);

                int idxIndex = 0;

                foreach (var idx in idxFiles)
                {
                    using (var fs = new FileStream(idx, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                    using (var br = new BinaryReader(fs))
                    {
                        int h2Len = br.ReadInt32();
                        int h2Check = br.ReadInt32();
                        byte[] h2 = br.ReadBytes(h2Len);

                        long padPos = (8 + h2Len + 0x0F) & 0xFFFFFFF0;
                        fs.Position = padPos;

                        int dataLen = br.ReadInt32();
                        int dataCheck = br.ReadInt32();

                        int numBlocks = dataLen / 18;

                        for (int i = 0; i < numBlocks; i++)
                        {
                            IndexEntry info = new IndexEntry();
                            byte[] key = br.ReadBytes(9);
                            int indexHigh = br.ReadByte();
                            int indexLow = br.ReadInt32BE();

                            info.Index = (int)((byte)(indexHigh << 2) | ((indexLow & 0xC0000000) >> 30));
                            info.Offset = (indexLow & 0x3FFFFFFF);
                            info.Size = br.ReadInt32();

                            // duplicate keys wtf...
                            //IndexData[key] = info; // use last key
                            if (!LocalIndexData.ContainsKey(key)) // use first key
                                LocalIndexData.Add(key, info);
                        }

                        padPos = (dataLen + 0x0FFF) & 0xFFFFF000;
                        fs.Position = padPos;

                        fs.Position += numBlocks * 18;
                        //for (int i = 0; i < numBlocks; i++)
                        //{
                        //    var bytes = br.ReadBytes(18); // unknown data
                        //}

                        if (fs.Position != fs.Position)
                            throw new Exception("idx file under read");
                    }

                    if (worker != null) worker.ReportProgress((int)((float)++idxIndex / (float)idxFiles.Count * 100));
                }

                Logger.WriteLine("CASCHandler: loaded {0} indexes", LocalIndexData.Count);
            }

            if (worker != null) worker.ReportProgress(0);

            using (var fs = OpenEncodingFile())
            using (var br = new BinaryReader(fs))
            {
                br.ReadBytes(2); // EN
                byte b1 = br.ReadByte();
                byte b2 = br.ReadByte();
                byte b3 = br.ReadByte();
                ushort s1 = br.ReadUInt16();
                ushort s2 = br.ReadUInt16();
                int numEntries = br.ReadInt32BE();
                int i1 = br.ReadInt32BE();
                byte b4 = br.ReadByte();
                int entriesOfs = br.ReadInt32BE();

                fs.Position += entriesOfs; // skip strings

                fs.Position += numEntries * 32;
                //for (int i = 0; i < numEntries; ++i)
                //{
                //    br.ReadBytes(16);
                //    br.ReadBytes(16);
                //}

                for (int i = 0; i < numEntries; ++i)
                {
                    ushort keysCount;

                    while ((keysCount = br.ReadUInt16()) != 0)
                    {
                        int fileSize = br.ReadInt32BE();
                        byte[] md5 = br.ReadBytes(16);

                        var entry = new EncodingEntry();
                        entry.Size = fileSize;

                        for (int ki = 0; ki < keysCount; ++ki)
                        {
                            byte[] key = br.ReadBytes(16);

                            entry.Keys.Add(key);
                        }

                        //Encodings[md5] = entry;
                        EncodingData.Add(md5, entry);
                    }

                    //br.ReadBytes(28);
                    while (br.PeekChar() == 0)
                        fs.Position++;

                    if (worker != null) worker.ReportProgress((int)((float)fs.Position / (float)fs.Length * 100));
                }
                //var pos = br.BaseStream.Position;
                //for (int i = 0; i < i1; ++i)
                //{
                //    br.ReadBytes(16);
                //    br.ReadBytes(16);
                //}
                Logger.WriteLine("CASCHandler: loaded {0} encoding data", EncodingData.Count);
            }

            if (worker != null) worker.ReportProgress(0);

            using (var fs = OpenRootFile())
            using (var br = new BinaryReader(fs))
            {
                while (fs.Position < fs.Length)
                {
                    int count = br.ReadInt32();

                    RootBlock block = new RootBlock();
                    block.Unk1 = br.ReadUInt32();
                    block.Flags = (LocaleFlags)br.ReadUInt32();

                    if (block.Flags == LocaleFlags.None)
                        throw new Exception("block.Flags == LocaleFlags.None");

                    RootEntry[] entries = new RootEntry[count];

                    for (var i = 0; i < count; ++i)
                    {
                        entries[i] = new RootEntry();
                        entries[i].Block = block;
                        entries[i].Unk1 = br.ReadInt32();
                    }

                    for (var i = 0; i < count; ++i)
                    {
                        entries[i].MD5 = br.ReadBytes(16);

                        ulong hash = br.ReadUInt64();
                        entries[i].Hash = hash;

                        // don't load other locales
                        //if (block.Flags != LocaleFlags.All && (block.Flags & LocaleFlags.enUS) == 0)
                        //    continue;

                        if (!RootData.ContainsKey(hash))
                        {
                            RootData[hash] = new List<RootEntry>();
                            RootData[hash].Add(entries[i]);
                        }
                        else
                            RootData[hash].Add(entries[i]);
                    }

                    if (worker != null) worker.ReportProgress((int)((float)fs.Position / (float)fs.Length * 100));
                }

                Logger.WriteLine("CASCHandler: loaded {0} root data", RootData.Count);
            }

            if (worker != null) worker.ReportProgress(0);
        }
예제 #28
0
        public static CASCConfig LoadOnlineStorageConfig()
        {
            var config = new CASCConfig {OnlineMode = true};
            using (var cdnsStream = CDNHandler.OpenFileDirect("http://us.patch.battle.net/wow_beta/cdns"))
            {
                config._CDNData = KeyValueConfig.ReadVerBarConfig(cdnsStream);
            }

            using (var versionsStream = CDNHandler.OpenFileDirect("http://us.patch.battle.net/wow_beta/versions"))
            {
                config._VersionsData = KeyValueConfig.ReadVerBarConfig(versionsStream);
            }

            string buildKey = config._VersionsData["BuildConfig"][0];
            using (Stream stream = CDNHandler.OpenConfigFileDirect(config.CDNUrl, buildKey))
            {
                config._BuildConfig = KeyValueConfig.ReadKeyValueConfig(stream);
            }

            string cdnKey = config._VersionsData["CDNConfig"][0];
            using (Stream stream = CDNHandler.OpenConfigFileDirect(config.CDNUrl, cdnKey))
            {
                config._CDNConfig = KeyValueConfig.ReadKeyValueConfig(stream);
            }
            return config;
        }
예제 #29
0
 private static CASCHandler Open(BackgroundWorkerEx worker, CASCConfig config)
 {
     using (var _ = new PerfCounter("new CASCHandler()"))
     {
         return new CASCHandler(config, worker);
     }
 }
예제 #30
0
파일: CASCConfig.cs 프로젝트: aeo24/WoWMap
        public static CASCConfig LoadLocalStorageConfig(string basePath)
        {
            var config = new CASCConfig { OnlineMode = false, BasePath = basePath };

            config.GameType = CASCGame.DetectLocalGame(basePath);

            if (config.GameType == CASCGameType.Agent || config.GameType == CASCGameType.Hearthstone)
                throw new Exception("Local mode not supported for this game!");

            string buildInfoPath = Path.Combine(basePath, ".build.info");

            using (Stream buildInfoStream = new FileStream(buildInfoPath, FileMode.Open))
            {
                config._BuildInfo = VerBarConfig.ReadVerBarConfig(buildInfoStream);
            }

            Dictionary<string, string> bi = null;

            for (int i = 0; i < config._BuildInfo.Count; ++i)
            {
                if (config._BuildInfo[i]["Active"] == "1")
                {
                    bi = config._BuildInfo[i];
                    break;
                }
            }

            if (bi == null)
                throw new Exception("Can't find active BuildInfoEntry");

            string dataFolder = CASCGame.GetDataFolder(config.GameType);

            config.ActiveBuild = 0;

            config._Builds = new List<KeyValueConfig>();

            string buildKey = bi["BuildKey"];
            string buildCfgPath = Path.Combine(basePath, string.Format("{0}\\config\\", dataFolder), buildKey.Substring(0, 2), buildKey.Substring(2, 2), buildKey);
            using (Stream stream = new FileStream(buildCfgPath, FileMode.Open))
            {
                config._Builds.Add(KeyValueConfig.ReadKeyValueConfig(stream));
            }

            string cdnKey = bi["CDNKey"];
            string cdnCfgPath = Path.Combine(basePath, string.Format("{0}\\config\\", dataFolder), cdnKey.Substring(0, 2), cdnKey.Substring(2, 2), cdnKey);
            using (Stream stream = new FileStream(cdnCfgPath, FileMode.Open))
            {
                config._CDNConfig = KeyValueConfig.ReadKeyValueConfig(stream);
            }

            return config;
        }
예제 #31
0
 public static CASCHandler OpenStorage(CASCConfig config, BackgroundWorkerEx worker = null) => Open(worker, config);
예제 #32
0
        private CASCHandlerLite(CASCConfig config, LocaleFlags locale, BackgroundWorkerEx worker) : base(config, worker)
        {
            if (config.GameType != CASCGameType.WoW)
            {
                throw new Exception("Unsupported game " + config.BuildUID);
            }

            Logger.WriteLine("CASCHandlerLite: loading encoding data...");

            EncodingHandler EncodingHandler;

            using (var _ = new PerfCounter("new EncodingHandler()"))
            {
                using (var fs = OpenEncodingFile(this))
                    EncodingHandler = new EncodingHandler(fs, worker);
            }

            Logger.WriteLine("CASCHandlerLite: loaded {0} encoding data", EncodingHandler.Count);

            Logger.WriteLine("CASCHandlerLite: loading root data...");

            WowRootHandler RootHandler;

            using (var _ = new PerfCounter("new RootHandler()"))
            {
                using (var fs = OpenRootFile(EncodingHandler, this))
                    RootHandler = new WowRootHandler(fs, worker);
            }

            Logger.WriteLine("CASCHandlerLite: loaded {0} root data", RootHandler.Count);

            RootHandler.SetFlags(locale, ContentFlags.None, false);

            CDNIndexData = new Dictionary <MD5Hash, IndexEntry>(comparer);

            if (LocalIndex != null)
            {
                LocalIndexData = new Dictionary <MD5Hash, IndexEntry>(comparer);
            }

            RootEntry rootEntry;

            foreach (var entry in RootHandler.GetAllEntries())
            {
                rootEntry = entry.Value;

                if ((rootEntry.LocaleFlags == locale || (rootEntry.LocaleFlags & locale) != LocaleFlags.None) && (rootEntry.ContentFlags & ContentFlags.LowViolence) == ContentFlags.None)
                {
                    EncodingEntry enc;

                    if (EncodingHandler.GetEntry(rootEntry.MD5, out enc))
                    {
                        if (!HashToKey.ContainsKey(entry.Key))
                        {
                            HashToKey.Add(entry.Key, enc.Key);
                            FileDataIdToHash.Add(RootHandler.GetFileDataIdByHash(entry.Key), entry.Key);

                            if (LocalIndex != null)
                            {
                                IndexEntry iLocal = LocalIndex.GetIndexInfo(enc.Key);

                                if (iLocal != null && !LocalIndexData.ContainsKey(enc.Key))
                                {
                                    LocalIndexData.Add(enc.Key, iLocal);
                                }
                            }

                            IndexEntry iCDN = CDNIndex.GetIndexInfo(enc.Key);

                            if (iCDN != null && !CDNIndexData.ContainsKey(enc.Key))
                            {
                                CDNIndexData.Add(enc.Key, iCDN);
                            }
                        }
                    }
                }
            }

            CDNIndex.Clear();
            //CDNIndex = null;
            LocalIndex?.Clear();
            LocalIndex = null;
            RootHandler.Clear();
            RootHandler = null;
            EncodingHandler.Clear();
            EncodingHandler = null;
            GC.Collect();

            Logger.WriteLine("CASCHandlerLite: loaded {0} files", HashToKey.Count);
        }
예제 #33
0
        public static CASCConfig LoadLocalStorageConfig(string basePath)
        {
            var config = new CASCConfig {OnlineMode = false, BasePath = basePath};
            
            string buildInfoPath = Path.Combine(basePath, ".build.info");

            using (Stream buildInfoStream = new FileStream(buildInfoPath, FileMode.Open))
            {
                config._BuildInfo = KeyValueConfig.ReadVerBarConfig(buildInfoStream);
            }

            string buildKey = config._BuildInfo["Build Key"][0];
            string buildCfgPath = Path.Combine(basePath, "Data\\config\\", buildKey.Substring(0, 2), buildKey.Substring(2, 2), buildKey);
            using (Stream stream = new FileStream(buildCfgPath, FileMode.Open))
            {
                config._BuildConfig = KeyValueConfig.ReadKeyValueConfig(stream);
            }

            string cdnKey = config._BuildInfo["CDN Key"][0];
            string cdnCfgPath = Path.Combine(basePath, "Data\\config\\", cdnKey.Substring(0, 2), cdnKey.Substring(2, 2), cdnKey);
            using (Stream stream = new FileStream(cdnCfgPath, FileMode.Open))
            {
                config._CDNConfig = KeyValueConfig.ReadKeyValueConfig(stream);
            }
            
            return config;
        }
예제 #34
0
        public static CASCHandler OpenOnlineStorage(BackgroundWorker worker)
        {
            CASCConfig config = CASCConfig.LoadOnlineStorageConfig();

            return(Open(worker, config));
        }
예제 #35
0
파일: CASCConfig.cs 프로젝트: aeo24/WoWMap
        public static CASCConfig LoadOnlineStorageConfig(string product, string region, bool useCurrentBuild = false)
        {
            var config = new CASCConfig { OnlineMode = true };

            config.Region = region;
            config.Product = product;

            using (var cdnsStream = CDNIndexHandler.OpenFileDirect(string.Format("http://us.patch.battle.net/{0}/cdns", product)))
            {
                config._CDNData = VerBarConfig.ReadVerBarConfig(cdnsStream);
            }

            using (var versionsStream = CDNIndexHandler.OpenFileDirect(string.Format("http://us.patch.battle.net/{0}/versions", product)))
            {
                config._VersionsData = VerBarConfig.ReadVerBarConfig(versionsStream);
            }

            int versionIndex = 0;

            for (int i = 0; i < config._VersionsData.Count; ++i)
            {
                if (config._VersionsData[i]["Region"] == region)
                {
                    versionIndex = i;
                    break;
                }
            }

            config.GameType = CASCGame.DetectOnlineGame(product);

            string cdnKey = config._VersionsData[versionIndex]["CDNConfig"];
            using (Stream stream = CDNIndexHandler.OpenConfigFileDirect(config, cdnKey))
            {
                config._CDNConfig = KeyValueConfig.ReadKeyValueConfig(stream);
            }

            config.ActiveBuild = 0;

            config._Builds = new List<KeyValueConfig>();

            for (int i = 0; i < config._CDNConfig["builds"].Count; i++)
            {
                try
                {
                    using (Stream stream = CDNIndexHandler.OpenConfigFileDirect(config, config._CDNConfig["builds"][i]))
                    {
                        var cfg = KeyValueConfig.ReadKeyValueConfig(stream);
                        config._Builds.Add(cfg);
                    }
                }
                catch
                {

                }
            }

            if (useCurrentBuild)
            {
                string buildKey = config._VersionsData[versionIndex]["BuildConfig"];

                int buildIndex = config._CDNConfig["builds"].IndexOf(buildKey);

                if (buildIndex != -1)
                    config.ActiveBuild = buildIndex;
            }

            return config;
        }
예제 #36
0
 public static CASCHandlerLite OpenStorage(LocaleFlags locale, CASCConfig config, BackgroundWorkerEx worker = null)
 {
     return Open(locale, worker, config);
 }
예제 #37
0
        private CASCHandlerLite(CASCConfig config, LocaleFlags locale, BackgroundWorkerEx worker) : base(config, worker)
        {
            if (config.GameType != CASCGameType.WoW)
                throw new Exception("Unsupported game " + config.BuildUID);

            Logger.WriteLine("CASCHandlerLite: loading encoding data...");

            EncodingHandler EncodingHandler;

            using (var _ = new PerfCounter("new EncodingHandler()"))
            {
                using (var fs = OpenEncodingFile(this))
                    EncodingHandler = new EncodingHandler(fs, worker);
            }

            Logger.WriteLine("CASCHandlerLite: loaded {0} encoding data", EncodingHandler.Count);

            Logger.WriteLine("CASCHandlerLite: loading root data...");

            WowRootHandler RootHandler;

            using (var _ = new PerfCounter("new RootHandler()"))
            {
                using (var fs = OpenRootFile(EncodingHandler, this))
                    RootHandler = new WowRootHandler(fs, worker);
            }

            Logger.WriteLine("CASCHandlerLite: loaded {0} root data", RootHandler.Count);

            RootHandler.SetFlags(locale, ContentFlags.None, false);

            CDNIndexData = new Dictionary<MD5Hash, IndexEntry>(comparer);

            if (LocalIndex != null)
                LocalIndexData = new Dictionary<MD5Hash, IndexEntry>(comparer);

            RootEntry rootEntry;

            foreach (var entry in RootHandler.GetAllEntries())
            {
                rootEntry = entry.Value;

                if ((rootEntry.LocaleFlags == locale || (rootEntry.LocaleFlags & locale) != LocaleFlags.None) && (rootEntry.ContentFlags & ContentFlags.LowViolence) == ContentFlags.None)
                {
                    EncodingEntry enc;

                    if (EncodingHandler.GetEntry(rootEntry.MD5, out enc))
                    {
                        if (!HashToKey.ContainsKey(entry.Key))
                        {
                            HashToKey.Add(entry.Key, enc.Key);
                            FileDataIdToHash.Add(RootHandler.GetFileDataIdByHash(entry.Key), entry.Key);

                            if (LocalIndex != null)
                            {
                                IndexEntry iLocal = LocalIndex.GetIndexInfo(enc.Key);

                                if (iLocal != null && !LocalIndexData.ContainsKey(enc.Key))
                                    LocalIndexData.Add(enc.Key, iLocal);
                            }

                            IndexEntry iCDN = CDNIndex.GetIndexInfo(enc.Key);

                            if (iCDN != null && !CDNIndexData.ContainsKey(enc.Key))
                                CDNIndexData.Add(enc.Key, iCDN);
                        }
                    }
                }
            }

            CDNIndex.Clear();
            //CDNIndex = null;
            LocalIndex?.Clear();
            LocalIndex = null;
            RootHandler.Clear();
            RootHandler = null;
            EncodingHandler.Clear();
            EncodingHandler = null;
            GC.Collect();

            Logger.WriteLine("CASCHandlerLite: loaded {0} files", HashToKey.Count);
        }
예제 #38
0
        public static CASCConfig LoadOnlineStorageConfig(string product, string region, bool useCurrentBuild = false)
        {
            var config = new CASCConfig {
                OnlineMode = true
            };

            config.Region  = region;
            config.Product = product;

            using (var cdnsStream = CDNIndexHandler.OpenFileDirect(string.Format("http://us.patch.battle.net/{0}/cdns", product)))
            {
                config._CDNData = VerBarConfig.ReadVerBarConfig(cdnsStream);
            }

            using (var versionsStream = CDNIndexHandler.OpenFileDirect(string.Format("http://us.patch.battle.net/{0}/versions", product)))
            {
                config._VersionsData = VerBarConfig.ReadVerBarConfig(versionsStream);
            }

            for (int i = 0; i < config._VersionsData.Count; ++i)
            {
                if (config._VersionsData[i]["Region"] == region)
                {
                    config._versionsIndex = i;
                    break;
                }
            }

            config.GameType = CASCGame.DetectOnlineGame(product);

            string cdnKey = config._VersionsData[config._versionsIndex]["CDNConfig"].ToLower();

            using (Stream stream = CDNIndexHandler.OpenConfigFileDirect(config, cdnKey))
            {
                config._CDNConfig = KeyValueConfig.ReadKeyValueConfig(stream);
            }

            config.ActiveBuild = 0;

            config._Builds = new List <KeyValueConfig>();

            if (config._CDNConfig["builds"] != null)
            {
                for (int i = 0; i < config._CDNConfig["builds"].Count; i++)
                {
                    try
                    {
                        using (Stream stream = CDNIndexHandler.OpenConfigFileDirect(config, config._CDNConfig["builds"][i]))
                        {
                            var cfg = KeyValueConfig.ReadKeyValueConfig(stream);
                            config._Builds.Add(cfg);
                        }
                    }
                    catch
                    {
                    }
                }

                if (useCurrentBuild)
                {
                    string curBuildKey = config._VersionsData[config._versionsIndex]["BuildConfig"];

                    int buildIndex = config._CDNConfig["builds"].IndexOf(curBuildKey);

                    if (buildIndex != -1)
                    {
                        config.ActiveBuild = buildIndex;
                    }
                }
            }

            string buildKey = config._VersionsData[config._versionsIndex]["BuildConfig"].ToLower();

            using (Stream stream = CDNIndexHandler.OpenConfigFileDirect(config, buildKey))
            {
                var cfg = KeyValueConfig.ReadKeyValueConfig(stream);
                config._Builds.Add(cfg);
            }

            return(config);
        }