示例#1
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);
        }
示例#2
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;
        }
示例#3
0
        public void ExtractFile(byte[] key, string path, string name)
        {
            try
            {
                if (OnlineMode)
                {
                    throw new Exception();
                }

                var idxInfo = GetLocalIndexInfo(key);

                if (idxInfo == null)
                {
                    throw new Exception("local index missing");
                }

                var stream = GetDataStream(idxInfo.Index);

                stream.Position = idxInfo.Offset;

                stream.Position += 30;
                //byte[] unkHash = reader.ReadBytes(16);
                //int __size = reader.ReadInt32();
                //byte[] unkData1 = reader.ReadBytes(2);
                //byte[] unkData2 = reader.ReadBytes(8);

                using (BLTEHandler blte = new BLTEHandler(stream, idxInfo.Size - 30))
                    blte.ExtractToFile(path, name);
            }
            catch
            {
                if (key.EqualsTo(CASCConfig.EncodingKey))
                {
                    using (Stream s = CDNHandler.OpenDataFileDirect(key, out int len))
                        using (BLTEHandler blte = new BLTEHandler(s, len))
                            blte.ExtractToFile(path, name);
                }
                else
                {
                    var idxInfo = CDNHandler.GetCDNIndexInfo(key);

                    if (idxInfo == null)
                    {
                        throw new Exception("CDN index missing");
                    }

                    using (Stream s = CDNHandler.OpenDataFile(key))
                        using (BLTEHandler blte = new BLTEHandler(s, idxInfo.Size))
                            blte.ExtractToFile(path, name);
                }
            }
        }
示例#4
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;
        }
示例#5
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);
        }
示例#6
0
        public static void Load(bool online)
        {
            string wowPath = Properties.Settings.Default.WowPath;

            if (online)
            {
                using (var cdnsStream = CDNHandler.OpenFileDirect("http://us.patch.battle.net/wow_beta/cdns"))
                    _CDNData = new VerBarConfig(cdnsStream);

                using (var versionsStream = CDNHandler.OpenFileDirect("http://us.patch.battle.net/wow_beta/versions"))
                    _VersionsData = new VerBarConfig(versionsStream);

                string buildKey = _VersionsData["BuildConfig"][0];
                using (Stream buildConfigStream = CDNHandler.OpenConfigFileDirect(buildKey))
                    _BuildConfig = new KeyValueConfig(buildConfigStream);

                string cdnKey = _VersionsData["CDNConfig"][0];
                using (Stream CDNConfigStream = CDNHandler.OpenConfigFileDirect(cdnKey))
                    _CDNConfig = new KeyValueConfig(CDNConfigStream);
            }
            else
            {
                string buildInfoPath = Path.Combine(wowPath, ".build.info");

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

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

                string cdnKey     = _BuildInfo["CDN Key"][0];
                string cdnCfgPath = Path.Combine(wowPath, "Data\\config\\", cdnKey.Substring(0, 2), cdnKey.Substring(2, 2), cdnKey);
                using (Stream CDNConfigStream = new FileStream(cdnCfgPath, FileMode.Open))
                    _CDNConfig = new KeyValueConfig(CDNConfigStream);
            }
        }
示例#7
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);
        }
示例#8
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);
            }
        }
示例#9
0
        private static CASCHandler Open(BackgroundWorker worker, CASCConfig config)
        {
            var cdn = CDNHandler.Initialize(config);

            return(new CASCHandler(config, cdn, worker));
        }