Exemple #1
0
        /// <summary>
        /// Adds a CASRecord to the EncodingFile generating all required entries. This will overwrite existing entries
        /// </summary>
        /// <param name="record"></param>
        public void AddOrUpdate(CASRecord record)
        {
            // CKeyPageTable - overwrite existing
            var cKeyEntry = new EncodingContentEntry
            {
                CKey             = record.CKey,
                DecompressedSize = record.EBlock.DecompressedSize
            };

            cKeyEntry.EKey            = record.EKey;
            _CKeyEntries[record.CKey] = cKeyEntry;

            // EKeyPageTable - overwrite existing
            // get or add to the ESpecStringTable
            int especIndex = ESpecStringTable.IndexOf(record.ESpec);

            if (especIndex == -1)
            {
                especIndex = ESpecStringTable.Count - 2;
                ESpecStringTable.Insert(especIndex, record.ESpec);
            }

            // create the entry
            var eKeyEntry = new EncodingEncodedEntry()
            {
                CompressedSize = record.EBlock.CompressedSize,
                EKey           = record.EKey,
                ESpecIndex     = (uint)especIndex
            };

            _EKeyEntries[record.EKey] = eKeyEntry;
        }
Exemple #2
0
        /// <summary>
        /// Removes a CASRecord
        /// </summary>
        /// <param name="record"></param>
        public bool Remove(CASRecord record, TACTRepo tactRepo = null)
        {
            if (record == null)
            {
                return(false);
            }

            if (_CKeyEntries.TryGetValue(record.CKey, out var entry))
            {
                _CKeyEntries.Remove(record.CKey);
                _EKeyEntries.Remove(entry.EKey);

                // propagate removal
                if (tactRepo != null)
                {
                    tactRepo.IndexContainer?.Remove(entry.EKey);
                    tactRepo.DownloadFile?.Remove(entry.EKey);
                    tactRepo.DownloadSizeFile?.Remove(entry.EKey);
                }

                return(true);
            }

            return(false);
        }
Exemple #3
0
 /// <summary>
 /// Enqueues a CASRecord to be written to the indicies and archives
 /// </summary>
 /// <param name="record"></param>
 public void Enqueue(CASRecord record)
 {
     if (!string.IsNullOrWhiteSpace(record.BLTEPath))
     {
         lock (QueuedEntries)
             QueuedEntries[record.EKey] = record;
     }
 }
        /// <summary>
        /// Adds a CASRecord, this will overwrite existing entries
        /// </summary>
        /// <param name="record"></param>
        /// <param name="tags"></param>
        public void AddOrUpdate(CASRecord record)
        {
            var entry = new DownloadSizeFileEntry()
            {
                EKey           = record.EKey,
                CompressedSize = record.EBlock.CompressedSize,
            };

            AddOrUpdate(entry, record.Tags);
        }
        /// <summary>
        /// Adds a CASRecord, this will overwrite existing entries
        /// </summary>
        /// <param name="record"></param>
        /// <param name="repo"></param>
        public override void AddOrUpdate(CASRecord record, TACTRepo repo = null)
        {
            var entry = new DownloadSizeFileEntry()
            {
                EKey           = record.EKey,
                CompressedSize = record.EBlock.CompressedSize,
            };

            AddOrUpdate(entry, record.Tags);
        }
Exemple #6
0
 /// <summary>
 /// Removes a CASRecord
 /// </summary>
 /// <param name="record"></param>
 public void Remove(CASRecord record)
 {
     if (_CKeyEntries.TryGetValue(record.CKey, out var cKeyEntry))
     {
         Remove(cKeyEntry);
     }
     if (_EKeyEntries.TryGetValue(record.CKey, out var eKeyEntry))
     {
         Remove(eKeyEntry);
     }
 }
Exemple #7
0
        /// <summary>
        /// Adds a CASRecord to the InstallFile, this will overwrite existing entries
        /// </summary>
        /// <param name="record"></param>
        /// <param name="tactRepo">If provided, will add the entry to all relevant system files</param>
        /// <param name="tags"></param>
        public void AddOrUpdate(CASRecord record, TACTRepo tactRepo = null)
        {
            var entry = new InstallFileEntry()
            {
                FilePath         = record.FileName,
                CKey             = record.CKey,
                DecompressedSize = record.EBlock.DecompressedSize,
            };

            AddOrUpdate(entry, record.Tags);

            // add the record to the Encoding File
            tactRepo?.EncodingFile?.AddOrUpdate(record, tactRepo);
        }
Exemple #8
0
        /// <summary>
        /// Removes a CASRecord
        /// </summary>
        /// <param name="record"></param>
        public bool Remove(CASRecord record)
        {
            if (record == null)
            {
                return(false);
            }

            if (_CKeyEntries.TryGetValue(record.CKey, out var entry))
            {
                _CKeyEntries.Remove(record.CKey);
                _EKeyEntries.Remove(record.EKey);
                return(true);
            }

            return(false);
        }
Exemple #9
0
        /// <summary>
        /// Adds a CASRecord to the archive
        /// </summary>
        /// <param name="record"></param>
        public void Add(CASRecord record)
        {
            var entry = new IndexEntry()
            {
                Key            = IsPatchIndex ? record.CKey : record.EKey,
                CompressedSize = record.EBlock.CompressedSize,
                Offset         = (uint)_currentOffset
            };

            _currentOffset += record.EBlock.CompressedSize;

            _indexEntries[entry.Key] = entry;
            _newEntries[entry.Key]   = record;

            RequiresSave = true;
        }
Exemple #10
0
        /// <summary>
        /// Adds a CASRecord, this will overwrite existing entries
        /// </summary>
        /// <param name="record"></param>
        /// <param name="priority">0 = highest, 2 = lowest, -1 for Install</param>
        /// <param name="tags"></param>
        public void AddOrUpdate(CASRecord record, sbyte priority)
        {
            // prevent overflow for old versions
            if (DownloadHeader.BasePriority + priority < 0)
            {
                priority = 0;
            }

            var entry = new DownloadFileEntry()
            {
                EKey           = record.EKey,
                CompressedSize = record.EBlock.CompressedSize,
                Flags          = new byte[DownloadHeader.FlagSize],
                Priority       = priority,
                Checksum       = 0 // TODO do we know what this is?
            };

            AddOrUpdate(entry, record.Tags);
        }
Exemple #11
0
        /// <summary>
        /// Adds a CASRecord to the InstallFile, this will overwrite existing entries
        /// </summary>
        /// <param name="record"></param>
        /// <param name="tactRepo">If provided, will add the entry to all relevant system files</param>
        /// <param name="tags"></param>
        public void AddOrUpdate(CASRecord record, TACTRepo tactRepo = null)
        {
            var entry = new InstallFileEntry()
            {
                FilePath         = record.FileName,
                CKey             = record.CKey,
                DecompressedSize = record.EBlock.DecompressedSize,
            };

            AddOrUpdate(entry, record.Tags);

            // add the record to all referenced files
            if (tactRepo != null)
            {
                tactRepo.EncodingFile?.AddOrUpdate(record);
                tactRepo.IndexContainer?.Enqueue(record);
                tactRepo.DownloadFile?.AddOrUpdate(record, 2);
                tactRepo.DownloadSizeFile?.AddOrUpdate(record);
            }
        }
Exemple #12
0
        /// <summary>
        /// Adds a CASRecord to the EncodingFile generating all required entries. This will overwrite existing entries
        /// </summary>
        /// <param name="record"></param>
        public void AddOrUpdate(CASRecord record, TACTRepo tactRepo = null)
        {
            // CKeyPageTable
            Remove(record, tactRepo);
            var cKeyEntry = new EncodingContentEntry
            {
                CKey             = record.CKey,
                EKeys            = new List <MD5Hash>(),
                DecompressedSize = record.EBlock.DecompressedSize,
            };

            cKeyEntry.EKeys.Add(record.EKey);
            _CKeyEntries.Add(record.CKey, cKeyEntry);

            // get or add to the ESpecStringTable
            int especIndex = ESpecStringTable.IndexOf(record.ESpec);

            if (especIndex == -1)
            {
                especIndex = ESpecStringTable.Count - 2;
                ESpecStringTable.Insert(especIndex, record.ESpec);
            }

            // EKeyPageTable
            var eKeyEntry = new EncodingEncodedEntry()
            {
                CompressedSize = record.EBlock.CompressedSize,
                EKey           = record.EKey,
                ESpecIndex     = (uint)especIndex
            };

            _EKeyEntries[record.EKey] = eKeyEntry;

            // propogate the new record
            if (tactRepo != null)
            {
                tactRepo.IndexContainer?.Enqueue(record);
                tactRepo.DownloadFile?.AddOrUpdate(record);
                tactRepo.DownloadSizeFile?.AddOrUpdate(record);
            }
        }
Exemple #13
0
        /// <summary>
        /// Adds a CASRecord to the EncodingFile generating all required entries. This will overwrite existing entries
        /// </summary>
        /// <param name="record"></param>
        public void AddOrUpdate(CASRecord record)
        {
            // CKeyPageTable
            if (_CKeyEntries.TryGetValue(record.CKey, out var cKeyEntry))
            {
                _EKeyEntries.Remove(cKeyEntry.EKey);
                cKeyEntry.EKey = record.EKey;
            }
            else
            {
                cKeyEntry = new EncodingContentEntry
                {
                    CKey             = record.CKey,
                    EKey             = record.EKey,
                    DecompressedSize = record.EBlock.DecompressedSize,
                };

                _CKeyEntries.Add(record.CKey, cKeyEntry);
            }

            // get or add to the ESpecStringTable
            int especIndex = ESpecStringTable.IndexOf(record.ESpec);

            if (especIndex == -1)
            {
                especIndex = ESpecStringTable.Count - 2;
                ESpecStringTable.Insert(especIndex, record.ESpec);
            }

            // EKeyPageTable
            var eKeyEntry = new EncodingEncodedEntry()
            {
                CompressedSize = record.EBlock.CompressedSize,
                EKey           = record.EKey,
                ESpecIndex     = (uint)especIndex
            };

            _EKeyEntries[record.EKey] = eKeyEntry;
        }
Exemple #14
0
 /// <summary>
 /// Enqueues a CASRecord to be written to the indicies and archives
 /// </summary>
 /// <param name="record"></param>
 public void Enqueue(CASRecord record)
 {
     lock (QueuedEntries)
         QueuedEntries[record.EKey] = record;
 }
Exemple #15
0
 /// <summary>
 /// Dequeues a CASRecord from being written to the indicies and archives
 /// </summary>
 /// <param name="record"></param>
 /// <returns></returns>
 public bool Dequeue(CASRecord record)
 {
     lock (QueuedEntries)
         return(QueuedEntries.Remove(record.EKey));
 }
Exemple #16
0
        public static string MANIFEST_PATH; // = CdnRootDir + @"\wow";



        static void Main(string[] args)
        {
            string      seetingsDir = Directory.GetCurrentDirectory() + "/AppSettings.json";
            AppSettings settings    = null;

            try
            {
                FileStream f            = new FileStream(seetingsDir, FileMode.Open, FileAccess.Read, FileShare.Read);
                var        streamReader = new StreamReader(f, Encoding.UTF8);
                settings = JsonConvert.DeserializeObject <AppSettings>(streamReader.ReadToEnd());
            }
            catch (Exception e)
            {
                settings = new AppSettings
                {
                    cdnRootDir = "",

                    mysqlUser        = "******",
                    mysqlPassword    = "******",
                    dataFolderPath   = Directory.GetCurrentDirectory() + "\\Data\\",
                    exportFolderPath = Directory.GetCurrentDirectory() + "\\DataExport\\",
                    databaseName     = "tacthost",
                    databaseAdress   = "localhost"
                };

                string json = JsonConvert.SerializeObject(settings, Formatting.Indented);
                File.WriteAllText(seetingsDir, json);
            }

            CDN_DATA_DIR  = settings.cdnRootDir + @"tpr\wow";
            MANIFEST_PATH = settings.cdnRootDir + @"wow";

            var tactRepo = new TACTRepo(CDN_DATA_DIR)
            {
                ManifestContainer = new ManifestContainer("wow", Locale.EU),
                ConfigContainer   = new ConfigContainer()
            };

            tactRepo.ManifestContainer.OpenLocal(MANIFEST_PATH);

            tactRepo.ConfigContainer.OpenLocal(tactRepo.BaseDirectory, tactRepo.ManifestContainer);

            tactRepo.IndexContainer = new Net.Indices.IndexContainer();
            tactRepo.IndexContainer.Open(tactRepo.BaseDirectory);


            tactRepo.EncodingFile = new Net.Encoding.EncodingFile(tactRepo.BaseDirectory, tactRepo.ConfigContainer.EncodingEKey);
            tactRepo.EncodingFile.TryGetCKeyEntry(tactRepo.ConfigContainer.RootCKey, out var rootCEntry);
            tactRepo.RootFile     = new Net.Root.RootFile(tactRepo.BaseDirectory, rootCEntry.EKey);
            tactRepo.InstallFile  = new InstallFile(tactRepo.BaseDirectory, tactRepo.ConfigContainer.InstallEKey);
            tactRepo.DownloadFile = new Net.Download.DownloadFile(tactRepo.BaseDirectory, tactRepo.ConfigContainer.DownloadEKey);
            tactRepo.PatchFile    = new Net.Patch.PatchFile(tactRepo.BaseDirectory, tactRepo.ConfigContainer.PatchEKey);

            tactRepo.RootFile.FileLookup = new ListFileLookup();

            string[] files = Directory.GetFiles(settings.dataFolderPath, "*", SearchOption.AllDirectories);
            for (int i = 0; i < files.Length; i++)
            {
                files[i] = files[i].Replace(settings.dataFolderPath, "");
            }

            Console.WriteLine("Found " + files.Length + " Files to proccess in " + settings.dataFolderPath);



            foreach (string s in files)
            {
                string filename = s.Substring(s.LastIndexOf("\\") + 1);
                string path     = s.Substring(0, s.LastIndexOf("\\") + 1);


                LocaleFlags locale = LocaleFlags.All_WoW;

                if (path.ToLower().Contains("dbfilesclient"))
                {
                    var match        = Regex.Match(path, @"(frFR)|(enUS)|(ptBR)|(ruRU)|(esES)|(esMX)|(itIT)|(deDE)|(enGB)|(ptPT)");
                    var pathSplit    = path.Split("\\");
                    var localeString = "";
                    foreach (var split in pathSplit)
                    {
                        if (split.Contains(match.Value))
                        {
                            locale       = (LocaleFlags)Enum.Parse(typeof(LocaleFlags), split);
                            localeString = split;
                            path         = path.Replace("\\" + localeString, "");
                            break;
                        }
                    }
                }



                CASRecord record = BlockTableEncoder.EncodeAndExport(settings.dataFolderPath + s, settings.exportFolderPath, (path + filename).Replace("\\", "/"));



                uint fId = tactRepo.RootFile.FileLookup.GetOrCreateFileId(record.FileName);

                Console.WriteLine("Added " + filename + " with ID: " + fId);

                tactRepo.RootFile.AddOrUpdate(record, tactRepo, locale);
                tactRepo.InstallFile.AddOrUpdate(record, tactRepo);
            }



            tactRepo.Save(tactRepo.BaseDirectory, settings.cdnRootDir);
        }
 public abstract void AddOrUpdate(CASRecord record, TACTRepo repo = null);
Exemple #18
0
 /// <summary>
 /// Enqueues a CASRecord for storing archiving
 /// </summary>
 /// <param name="record"></param>
 public void Enqueue(CASRecord record)
 {
     _fileQueue.TryAdd(record.EKey, record);
 }
Exemple #19
0
 public void AddOrUpdate(CASRecord record, TACTRepo repo = null)
 {
     throw new NotImplementedException();
 }
Exemple #20
0
        /// <summary>
        /// Finalises and encodes the stream's contents
        /// </summary>
        /// <returns></returns>
        public CASRecord Finalise()
        {
            if (Finalised)
            {
                return(Result);
            }

            // lock the final block
            _blocks[_blocks.Count - 1].Lock();

            MD5Hash EKey, CKey = ComputeCKey();
            EMap    encoding         = _blocks.Count == 1 ? _blocks[0].EncodingMap : new EMap(EType.ZLib, 9);
            uint    decompressedSize = 0;
            string  eSpec;

            using (var md5 = MD5.Create())
                using (var ms = new MemoryStream((int)memStream.Length + 0x100))
                    using (var bw = new BinaryWriter(ms))
                    {
                        // replace the stream contents with the BLTE structure
                        uint headerSize = (uint)(_blocks.Count == 1 ? 0 : 0x18 * _blocks.Count + 0xC);

                        // Header
                        bw.Write(BlockTableStreamReader.BLTE_MAGIC);
                        bw.WriteUInt32BE(headerSize);

                        // Frame
                        if (headerSize > 0)
                        {
                            bw.Write((byte)0xF);                   // flag
                            bw.WriteUInt24BE((uint)_blocks.Count); // chunkCount

                            // EBlock meta
                            foreach (var block in _blocks.Values)
                            {
                                block.Finalise(); // apply encoding byte and any compression
                                block.Position = 0;

                                bw.WriteUInt32BE(block.CompressedSize);
                                bw.WriteUInt32BE(block.DecompressedSize);
                                bw.Write(md5.ComputeHash(block));
                                decompressedSize += block.DecompressedSize;
                            }
                        }
                        else
                        {
                            var block = _blocks[0];
                            block.Finalise(); // apply encoding byte and any compression
                            decompressedSize = block.DecompressedSize;
                        }

                        foreach (var block in _blocks.Values)
                        {
                            block.Position = 0;
                            block.CopyTo(ms);
                        }

                        // calculate the EKey
                        if (headerSize == 0)
                        {
                            ms.Position = 0;
                            EKey        = new MD5Hash(md5.ComputeHash(ms));
                        }
                        else
                        {
                            EKey = ms.HashSlice(md5, 0, headerSize);
                        }

                        // set ESpec
                        eSpec = string.Join(",", _blocks.Values);

                        // merge the streams
                        memStream.Position = 0;
                        memStream.SetLength(ms.Length);
                        memStream.Capacity = (int)ms.Length;
                        ms.WriteTo(memStream);

                        // cleanup
                        _blocks.Clear();
                        Finalised = true;
                    }

            // store for repeat finalisation
            return(Result = new CASRecord()
            {
                CKey = CKey,
                EBlock = new EBlock()
                {
                    DecompressedSize = decompressedSize,
                    CompressedSize = (uint)memStream.Length,
                    EKey = EKey,
                    EncodingMap = encoding
                },
                ESpec = "b:{" + eSpec + "}"
            });
        }