public static bool DirectoryExists(this CASCFolder cascFolder, string folderPath) { CASCFolder currentFolder = cascFolder; foreach (string directory in EnumeratedStringPath(folderPath)) { if ((CASCFolder)currentFolder.GetEntry(directory) == null) { return(false); } } return(true); }
private List <string> GetTextureFiles() { List <string> files = new List <string>(); CASCFolder currentFolder = CASCHotsStorage.CASCFolderRoot.GetDirectory(CASCTexturesPath); foreach (KeyValuePair <string, ICASCEntry> file in currentFolder.Entries) { string filePath = ((CASCFile)file.Value).FullName; if (Path.GetExtension(filePath) == ".dds") { files.Add(filePath); } } return(files); }
protected override void LoadHeroesMapMods() { CASCFolder currentFolder = CASCFolderData.GetDirectory(HeroesMapModsDirectoryPath); // loop through each mapmods folder foreach (KeyValuePair <string, ICASCEntry> mapFolder in currentFolder.Entries) { ICASCEntry baseStormDataFolder = ((CASCFolder)mapFolder.Value).GetEntry(BaseStormDataDirectoryName); ICASCEntry gameDataFolder = ((CASCFolder)baseStormDataFolder).GetEntry(GameDataStringName); if (LoadXmlFilesEnabled) { foreach (KeyValuePair <string, ICASCEntry> dataFiles in ((CASCFolder)gameDataFolder).Entries) { if (Path.GetExtension(dataFiles.Key) == ".xml") { string filePath = ((CASCFile)dataFiles.Value).FullName; if (!CASCHandlerData.FileExists(filePath)) { throw new FileNotFoundException(filePath); } using (Stream data = CASCHandlerData.OpenFile(filePath)) { LoadXmlFile(mapFolder.Value.Name, data, filePath); } } } } if (LoadTextFilesOnlyEnabled) { string filePath = Path.Combine(HeroesMapModsDirectoryPath, mapFolder.Value.Name, GameStringLocalization, LocalizedDataName, GameStringFile); if (CASCHandlerData.FileExists(filePath)) { LoadTextFile(mapFolder.Value.Name, CASCHandlerData.OpenFile(filePath), filePath); } } } }
public static CASCFolder GetDirectory(this CASCFolder cascFolder, string folderPath) { if (cascFolder is null) { throw new ArgumentNullException(nameof(cascFolder)); } if (folderPath is null) { throw new ArgumentNullException(nameof(folderPath)); } CASCFolder currentFolder = cascFolder; foreach (string directory in EnumeratedStringPath(folderPath)) { currentFolder = (CASCFolder)currentFolder.GetEntry(directory); } return(currentFolder); }
private void Explore(CASCFolder folder) { foreach (KeyValuePair <string, ICASCEntry> node in folder.Entries) { ICASCEntry entry = node.Value; if (entry is CASCFolder) { Explore((CASCFolder)entry); } else if (entry is CASCFile) { CASCFile file = (CASCFile)entry; if (file.Name.ToLower().Contains("illidan2")) { new RunnerExtractItem(file).Begin(); return; } } } }
public static bool DirectoryExists(this CASCFolder cascFolder, string folderPath) { if (cascFolder is null) { throw new ArgumentNullException(nameof(cascFolder)); } if (folderPath is null) { throw new ArgumentNullException(nameof(folderPath)); } CASCFolder currentFolder = cascFolder; foreach (string directory in EnumeratedStringPath(folderPath)) { if ((CASCFolder)currentFolder.GetEntry(directory) == null) { return(false); } } return(true); }
/// <summary> /// Contruct the CASCGameData object. /// </summary> /// <param name="cascHandler"></param> /// <param name="cascFolder"></param> /// <param name="hotsBuild">The hots build number.</param> /// <param name="modsFolderPath">The root folder of the heroes data path.</param> public CASCGameData(CASCHandler cascHandler, CASCFolder cascFolder, int?hotsBuild, string modsFolderPath = "mods") : base(modsFolderPath, hotsBuild) { CASCHandlerData = cascHandler; CASCFolderData = cascFolder; }
/// <summary> /// Contruct the CASCGameData object. /// </summary> /// <param name="cascHandler"></param> /// <param name="cascFolder"></param> /// <param name="modsFolderPath">The root folder of the heroes data path.</param> public CASCGameData(CASCHandler cascHandler, CASCFolder cascFolder, string modsFolderPath = "mods") : base(modsFolderPath) { CASCHandlerData = cascHandler; CASCFolderData = cascFolder; }
protected override void LoadHeroesDataStormMod() { if (LoadXmlFilesEnabled) { // load up xml files in gamedata folder CASCFolder currentFolder = CASCFolderData.GetDirectory(Path.Combine(HeroesDataBaseDataDirectoryPath, GameDataStringName)); foreach (KeyValuePair <string, ICASCEntry> file in currentFolder.Entries) { if (Path.GetExtension(file.Key) != ".xml") { continue; } string filePath = ((CASCFile)file.Value).FullName; if (!CASCHandlerData.FileExists(filePath)) { throw new FileNotFoundException(filePath); } using (Stream data = CASCHandlerData.OpenFile(filePath)) { LoadXmlFile(data, filePath); } } // load up files in gamedata.xml file LoadGameDataXmlContents(Path.Combine(HeroesDataBaseDataDirectoryPath, GameDataXmlFile)); } if (LoadTextFilesOnlyEnabled) { // load gamestring file string filePath = Path.Combine(HeroesDataLocalizedDataPath, GameStringFile); LoadTextFile(CASCHandlerData.OpenFile(filePath), filePath); } // load up files in includes.xml file - which are the heroes in the heromods folder using (Stream cascXmlStream = CASCHandlerData.OpenFile(Path.Combine(HeroesDataBaseDataDirectoryPath, IncludesXmlFile))) { if (IsCacheEnabled) { AddXmlCachedFilePath(Path.Combine(HeroesDataBaseDataDirectoryPath, IncludesXmlFile)); } XDocument gameDataXml = XDocument.Load(cascXmlStream); IEnumerable <XElement> pathElements = gameDataXml.Root.Elements("Path"); foreach (XElement pathElement in pathElements) { string valuePath = pathElement.Attribute("value")?.Value; if (!string.IsNullOrEmpty(valuePath)) { valuePath = PathHelper.GetFilePath(valuePath); valuePath = valuePath.Remove(0, 5); // remove 'mods/' if (valuePath.StartsWith(HeroesModsDirectoryName, StringComparison.OrdinalIgnoreCase)) { string gameDataPath = Path.Combine(ModsFolderPath, valuePath, BaseStormDataDirectoryName, GameDataXmlFile); LoadGameDataXmlContents(gameDataPath); if (LoadTextFilesOnlyEnabled) { string filePath = Path.Combine(ModsFolderPath, valuePath, GameStringLocalization, LocalizedDataName, GameStringFile); if (CASCHandlerData.FileExists(filePath)) { LoadTextFile(CASCHandlerData.OpenFile(filePath), filePath); } } } } } } string fontStylesFilePath = Path.Combine(HeroesDataBaseDataDirectoryPath, UIDirectoryStringName, FontStyleFile); LoadStormStyleFile(CASCHandlerData.OpenFile(fontStylesFilePath)); if (IsCacheEnabled) { AddStormStyleCachedFilePath(fontStylesFilePath); } }
static void Main(string[] args) { if (args.Length != 4) { Console.WriteLine("Invalid arguments count!"); Console.WriteLine("Usage: CASCConsole <pattern> <destination> <localeFlags> <contentFlags>"); return; } Console.WriteLine("Settings:"); Console.WriteLine(" WowPath: {0}", Settings.Default.StoragePath); Console.WriteLine(" OnlineMode: {0}", Settings.Default.OnlineMode); Console.WriteLine("Loading..."); BackgroundWorkerEx bgLoader = new BackgroundWorkerEx(); bgLoader.ProgressChanged += BgLoader_ProgressChanged; CASCConfig config = Settings.Default.OnlineMode ? CASCConfig.LoadOnlineStorageConfig(Settings.Default.Product, "us") : CASCConfig.LoadLocalStorageConfig(Settings.Default.StoragePath); CASCHandler cascHandler = CASCHandler.OpenStorage(config, bgLoader); string pattern = args[0]; string dest = args[1]; LocaleFlags locale = (LocaleFlags)Enum.Parse(typeof(LocaleFlags), args[2]); ContentFlags content = (ContentFlags)Enum.Parse(typeof(ContentFlags), args[3]); cascHandler.Root.LoadListFile(Path.Combine(Environment.CurrentDirectory, "listfile.txt"), bgLoader); CASCFolder root = cascHandler.Root.SetFlags(locale, content); Console.WriteLine("Loaded."); Console.WriteLine("Extract params:", pattern, dest, locale); Console.WriteLine(" Pattern: {0}", pattern); Console.WriteLine(" Destination: {0}", dest); Console.WriteLine(" LocaleFlags: {0}", locale); Console.WriteLine(" ContentFlags: {0}", content); Wildcard wildcard = new Wildcard(pattern, true, RegexOptions.IgnoreCase); foreach (var file in root.GetFiles()) { if (wildcard.IsMatch(file.FullName)) { Console.Write("Extracting '{0}'...", file.FullName); try { cascHandler.SaveFileTo(file.FullName, dest); Console.WriteLine(" Ok!"); } catch (Exception exc) { Console.WriteLine(" Error!"); Logger.WriteLine(exc.Message); } } } Console.WriteLine("Extracted."); }
//class Hashes //{ // public string[] install; // public string[] encoding; //} static void Main(string[] args) { //HashSet<string> data = new HashSet<string>(); //HashSet<string> installs = new HashSet<string>(); //using (StreamReader sr = new StreamReader("list.txt")) //{ // string line1; // while((line1 = sr.ReadLine()) != null) // { // data.Add(line1.Substring(19, 32)); // if (line1.Contains("install")) // { // installs.Add(line1.Substring(93, 32)); // } // } //} ////foreach (var cfg in data) ////{ //// string url = string.Format("https://bnet.marlam.in/tpr/wow/config/{0}/{1}/{2}", cfg.Substring(0, 2), cfg.Substring(2, 2), cfg); //// var stream = CDNIndexHandler.OpenFileDirect(url); //// using (var fileStream = File.Create("builds\\" + cfg)) //// { //// stream.CopyTo(fileStream); //// } ////} //Dictionary<string, Hashes> data2 = new Dictionary<string, Hashes>(); //foreach (var file in Directory.GetFiles("builds")) //{ // using(var sr = new StreamReader(file)) // { // string line; // while ((line = sr.ReadLine()) != null) // { // if (string.IsNullOrWhiteSpace(line) || line.StartsWith("#")) // skip empty lines and comments // continue; // string[] tokens = line.Split(new char[] { '=' }, 2, StringSplitOptions.RemoveEmptyEntries); // if (tokens.Length != 2) // throw new Exception("KeyValueConfig: tokens.Length != 2"); // var values = tokens[1].Trim().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // var valuesList = values.ToList(); // if (!data2.ContainsKey(file)) // data2[file] = new Hashes(); // if (values[0] == "install") // { // data2[file].install = values; // } // if (values[0] == "encoding") // { // data2[file].encoding = values; // } // //sr.Data.Add(tokens[0].Trim(), valuesList); // } // } //} //Dictionary<string, string> realInstalls = new Dictionary<string, string>(); //foreach(var kv in data2) //{ // for(int i = 6; i < kv.Value.install.Length; i++) // { // if (installs.Contains(kv.Value.install[i])) // { // //Console.WriteLine("{0} {1}", kv.Value.install[i], kv.Value.encoding[i]); // realInstalls[kv.Value.install[i]] = kv.Value.encoding[i]; // } // } //} //CASCConfig.ValidateData = false; //int buildIndex = 0; //foreach (var kvinstall in realInstalls) //{ // string url1 = string.Format("http://bnet.marlamin.com/tpr/wow/data/{0}/{1}/{2}", kvinstall.Key.Substring(0, 2), kvinstall.Key.Substring(2, 2), kvinstall.Key); // BLTEStream instFile = new BLTEStream(CDNIndexHandler.OpenFileDirect(url1), new MD5Hash()); // InstallHandler install = new InstallHandler(new BinaryReader(instFile), null); // //foreach(var ent in install.GetEntries().Where(e => e.Name.Contains("MacOS"))) // //{ // // Console.WriteLine(ent.Name); // //} // //continue; // string url2 = string.Format("http://bnet.marlamin.com/tpr/wow/data/{0}/{1}/{2}", kvinstall.Value.Substring(0, 2), kvinstall.Value.Substring(2, 2), kvinstall.Value); // BLTEStream encFile = new BLTEStream(CDNIndexHandler.OpenFileDirect(url2), new MD5Hash()); // EncodingHandler encoding = new EncodingHandler(new BinaryReader(encFile), null); // string[] files = new string[] { "WowB.exe", "WowT.exe", "Wow.exe", "WowB-64.exe", "WowT-64.exe", "Wow-64.exe", "RenderService.exe", "RenderService-64.exe", // @"World of Warcraft Public Test.app\Contents\MacOS\World of Warcraft", // @"World of Warcraft Public Test.app\Contents\MacOS\World of Warcraft 64", // @"World of Warcraft Beta.app\Contents\MacOS\World of Warcraft", // @"World of Warcraft Beta.app\Contents\MacOS\World of Warcraft 64", // @"World of Warcraft Retail.app\Contents\MacOS\World of Warcraft", // @"World of Warcraft Retail.app\Contents\MacOS\World of Warcraft 64", // @"World of Warcraft Test.app\Contents\MacOS\World of Warcraft", // @"World of Warcraft.app\Contents\MacOS\World of Warcraft" // }; // string outFolder = "build_" + buildIndex++; // foreach (var file in files) // { // var entries = install.GetEntriesByName(file); // foreach (var entry in entries) // { // bool ok = encoding.GetEntry(entry.MD5, out var encEntry); // if (ok) // { // string chash = encEntry.Key.ToHexString().ToLower(); // Console.WriteLine("http://bnet.marlamin.com/tpr/wow/data/{0}/{1}/{2} {3}", chash.Substring(0, 2), chash.Substring(2, 2), chash, file); // string url = string.Format("http://blzddist1-a.akamaihd.net/tpr/wow/data/{0}/{1}/{2}", chash.Substring(0, 2), chash.Substring(2, 2), chash); // //string url = string.Format("http://bnet.marlamin.com/tpr/wow/data/{0}/{1}/{2}", chash.Substring(0, 2), chash.Substring(2, 2), chash); // try // { // var stream = CDNIndexHandler.OpenFileDirect(url); // BLTEStream blte3 = new BLTEStream(stream, new MD5Hash()); // string outFile = Path.Combine(outFolder, chash + "_" + file); // string outDir = Path.GetDirectoryName(outFile); // if (!Directory.Exists(outDir)) // Directory.CreateDirectory(outDir); // using (var fileStream = File.Create(outFile)) // { // blte3.CopyTo(fileStream); // } // } // catch(Exception exc) // { // Console.WriteLine(exc.Message); // } // } // } // } //} //ArmadilloCrypt crypt = new ArmadilloCrypt("sc1Dev"); //var decr = crypt.DecryptFile(@"c:\Users\TOM_RUS\Downloads\e32f46c7245bfc154e43924555a5cf9f"); //File.WriteAllBytes("test", decr); //byte[] keyBytes = new byte[16]; //ArmadilloCrypt crypt = new ArmadilloCrypt(keyBytes); //string buildconfigfile = "9f6048f8bd01f38ec0be83f4a9fe5a10"; //byte[] data = File.ReadAllBytes(buildconfigfile); //byte[] IV = buildconfigfile.Substring(16).ToByteArray(); //unsafe //{ // fixed (byte* ptr = keyBytes) // { // for (ulong i = 0; i < ulong.MaxValue; i++) // { // for (ulong j = 0; j < ulong.MaxValue; j++) // { // byte[] decrypted = crypt.DecryptFile(IV, data); // if (decrypted[0] == 0x23 && decrypted[1] == 0x20 && decrypted[2] == 0x42 && decrypted[3] == 0x75) // { // Console.WriteLine("key found: {0} {1} ?", i, j); // } // *(ulong*)ptr = j; // if (j % 1000000 == 0) // Console.WriteLine("{0}/{1}", j, ulong.MaxValue); // } // *(ulong*)(ptr + 8) = i; // } // } //} if (args.Length != 5) { Console.WriteLine("Invalid arguments count!"); Console.WriteLine("Usage: CASCConsole <mode> <pattern|listfile> <destination> <localeFlags> <overrideArchive>"); return; } Console.WriteLine("Settings:"); Console.WriteLine(" WowPath: {0}", Settings.Default.StoragePath); Console.WriteLine(" OnlineMode: {0}", Settings.Default.OnlineMode); Console.WriteLine("Loading..."); BackgroundWorkerEx bgLoader = new BackgroundWorkerEx(); bgLoader.ProgressChanged += BgLoader_ProgressChanged; //CASCConfig.LoadFlags |= LoadFlags.Install; CASCConfig config = Settings.Default.OnlineMode ? CASCConfig.LoadOnlineStorageConfig(Settings.Default.Product, "us") : CASCConfig.LoadLocalStorageConfig(Settings.Default.StoragePath, Settings.Default.Product); CASCHandler cascHandler = CASCHandler.OpenStorage(config, bgLoader); string mode = args[0]; string pattern = args[1]; string dest = args[2]; LocaleFlags locale = (LocaleFlags)Enum.Parse(typeof(LocaleFlags), args[3]); bool overrideArchive = bool.Parse(args[4]); cascHandler.Root.LoadListFile(Path.Combine(Environment.CurrentDirectory, "listfile.csv"), bgLoader); CASCFolder root = cascHandler.Root.SetFlags(locale, overrideArchive); //cascHandler.Root.MergeInstall(cascHandler.Install); Console.WriteLine("Loaded."); Console.WriteLine("Extract params:"); Console.WriteLine(" Mode: {0}", mode); Console.WriteLine(" Pattern/Listfile: {0}", pattern); Console.WriteLine(" Destination: {0}", dest); Console.WriteLine(" LocaleFlags: {0}", locale); Console.WriteLine(" OverrideArchive: {0}", overrideArchive); if (mode == "pattern") { Wildcard wildcard = new Wildcard(pattern, true, RegexOptions.IgnoreCase); foreach (var file in CASCFolder.GetFiles(root.Entries.Select(kv => kv.Value))) { if (wildcard.IsMatch(file.FullName)) { ExtractFile(cascHandler, file.Hash, file.FullName, dest); } } } else if (mode == "listfile") { if (cascHandler.Root is WowRootHandler wowRoot) { char[] splitChar = new char[] { ';' }; var names = File.ReadLines(pattern).Select(s => s.Split(splitChar, 2)).Select(s => new { id = int.Parse(s[0]), name = s[1] }); foreach (var file in names) { ExtractFile(cascHandler, wowRoot.GetHashByFileDataId(file.id), file.name, dest); } } else { var names = File.ReadLines(pattern); foreach (var file in names) { ExtractFile(cascHandler, 0, file, dest); } } } Console.WriteLine("Extracted."); }
static void Main(string[] args) { //byte[] keyBytes = new byte[16]; //ArmadilloCrypt crypt = new ArmadilloCrypt(keyBytes); //string buildconfigfile = "9f6048f8bd01f38ec0be83f4a9fe5a10"; //byte[] data = File.ReadAllBytes(buildconfigfile); //byte[] IV = buildconfigfile.Substring(16).ToByteArray(); //unsafe //{ // fixed (byte* ptr = keyBytes) // { // for (ulong i = 0; i < ulong.MaxValue; i++) // { // for (ulong j = 0; j < ulong.MaxValue; j++) // { // byte[] decrypted = crypt.DecryptFile(IV, data); // if (decrypted[0] == 0x23 && decrypted[1] == 0x20 && decrypted[2] == 0x42 && decrypted[3] == 0x75) // { // Console.WriteLine("key found: {0} {1} ?", i, j); // } // *(ulong*)ptr = j; // if (j % 1000000 == 0) // Console.WriteLine("{0}/{1}", j, ulong.MaxValue); // } // *(ulong*)(ptr + 8) = i; // } // } //} if (args.Length != 4) { Console.WriteLine("Invalid arguments count!"); Console.WriteLine("Usage: CASCConsole <pattern> <destination> <localeFlags> <contentFlags>"); return; } Console.WriteLine("Settings:"); Console.WriteLine(" WowPath: {0}", Settings.Default.StoragePath); Console.WriteLine(" OnlineMode: {0}", Settings.Default.OnlineMode); Console.WriteLine("Loading..."); BackgroundWorkerEx bgLoader = new BackgroundWorkerEx(); bgLoader.ProgressChanged += BgLoader_ProgressChanged; //CASCConfig.LoadFlags |= LoadFlags.Install; CASCConfig config = Settings.Default.OnlineMode ? CASCConfig.LoadOnlineStorageConfig(Settings.Default.Product, "us") : CASCConfig.LoadLocalStorageConfig(Settings.Default.StoragePath); CASCHandler cascHandler = CASCHandler.OpenStorage(config, bgLoader); string pattern = args[0]; string dest = args[1]; LocaleFlags locale = (LocaleFlags)Enum.Parse(typeof(LocaleFlags), args[2]); ContentFlags content = (ContentFlags)Enum.Parse(typeof(ContentFlags), args[3]); cascHandler.Root.LoadListFile(Path.Combine(Environment.CurrentDirectory, "listfile.txt"), bgLoader); CASCFolder root = cascHandler.Root.SetFlags(locale, content); //cascHandler.Root.MergeInstall(cascHandler.Install); Console.WriteLine("Loaded."); Console.WriteLine("Extract params:"); Console.WriteLine(" Pattern: {0}", pattern); Console.WriteLine(" Destination: {0}", dest); Console.WriteLine(" LocaleFlags: {0}", locale); Console.WriteLine(" ContentFlags: {0}", content); Wildcard wildcard = new Wildcard(pattern, true, RegexOptions.IgnoreCase); foreach (var file in CASCFolder.GetFiles(root.Entries.Select(kv => kv.Value))) { if (wildcard.IsMatch(file.FullName)) { Console.Write("Extracting '{0}'...", file.FullName); try { cascHandler.SaveFileTo(file.FullName, dest); Console.WriteLine(" Ok!"); } catch (Exception exc) { Console.WriteLine(" Error!"); Logger.WriteLine(exc.Message); } } } Console.WriteLine("Extracted."); }
public static async Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, [Blob("wow")] CloudBlobContainer container, ILogger log) { log.LogInformation("C# HTTP trigger function processed a request."); string localeString = req.Query["locale"]; string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); dynamic data = JsonConvert.DeserializeObject(requestBody); var localeName = localeString ?? "en-US"; CASCConfig config = CASCConfig.LoadLocalStorageConfig(@"C:\Games\World of Warcraft", "wow"); CASCHandler handler = CASCHandler.OpenStorage(config, null); handler.Root.LoadListFile(Path.Combine(Environment.CurrentDirectory, "listfile8x.csv")); var locale = WowLocales.Locales.Single(x => x.Name.Equals(localeName, StringComparison.OrdinalIgnoreCase)); CASCFolder root = handler.Root.SetFlags(locale.Flag); handler.Root.MergeInstall(handler.Install); var dbfiles = (CASCFolder)root.Entries["dbfilesclient"]; await container.CreateIfNotExistsAsync(); // Apply translations to expansion / tiers var tiers = WowExpansion.All; { var entry = dbfiles.GetEntry("journaltier.db2"); await using var stream = handler.OpenFile(entry.Hash); var reader = new WDC3Reader(stream); foreach (var pair in reader) { var tier = tiers.Single(x => x.Value.TierId == pair.Key); tier.Value.Name = pair.Value.GetField <string>(0); } } await container.GetBlockBlobReference("expansions." + localeName + ".json") .UploadTextAsync(JsonConvert.SerializeObject(tiers.Values, serializerSettings)); var instanceTiers = new Dictionary <int, int>(); { var entry = dbfiles.GetEntry("JournalTierXInstance.db2"); await using var stream = handler.OpenFile(entry.Hash); var reader = new WDC3Reader(stream); foreach (var pair in reader) { var tierId = pair.Value.GetField <int>(0); var instanceId = pair.Value.GetField <int>(1); instanceTiers[instanceId] = tierId; } } // Get all instances var instances = new List <Instance>(); { var entry = dbfiles.GetEntry("JournalInstance.db2"); await using var stream = handler.OpenFile(entry.Hash); var reader = new WDC3Reader(stream); foreach (var pair in reader) { if (!instanceTiers.ContainsKey(pair.Key)) { continue; } var tierId = instanceTiers[pair.Key]; var instance = new Instance { Id = pair.Key, Name = pair.Value.GetField <string>(0), Description = pair.Value.GetField <string>(1), MapId = pair.Value.GetField <int>(3), BackgroundImageId = pair.Value.GetField <int>(4), ButtonImageId = pair.Value.GetField <int>(5), ButtonSmallImageId = pair.Value.GetField <int>(6), LoreImageId = pair.Value.GetField <int>(7), Order = pair.Value.GetField <int>(8), Flags = pair.Value.GetField <int>(9), TierId = tierId }; instances.Add(instance); } } // Save the list of all instances await container.GetBlockBlobReference("data/dungeons." + localeName + ".json") .UploadTextAsync(JsonConvert.SerializeObject(instances, serializerSettings)); foreach (var tier in tiers.Values) { var dungeons = new List <Instance>(); // Get details and images for each dungeon foreach (var instance in instances) { // Only encounters for this tier if (instance.TierId != tier.TierId) { continue; } // World instances are flagged with 0x2 if ((instance.Flags & 0x2) == 0x2) { continue; } // Raids have an order number, dungeons have order of 0 and sorted by name if (instance.Order != 0) { continue; } dungeons.Add(instance); var blobPath = "static/img/instance/" + instance.Id + "/"; // Get the dungeon images using var loreStream = handler.OpenFile(instance.LoreImageId); await container.GetBlockBlobReference(blobPath + "lg." + localeName + ".blp").UploadFromStreamAsync(loreStream); using var bg = handler.OpenFile(instance.BackgroundImageId); await container.GetBlockBlobReference(blobPath + "xl." + localeName + ".blp").UploadFromStreamAsync(bg); using var btnLarge = handler.OpenFile(instance.ButtonImageId); await container.GetBlockBlobReference(blobPath + "sm." + localeName + ".blp").UploadFromStreamAsync(btnLarge); using var btnSmall = handler.OpenFile(instance.ButtonImageId); await container.GetBlockBlobReference(blobPath + "xs." + localeName + ".blp").UploadFromStreamAsync(btnSmall); var encounters = new List <Encounter>(); foreach (var encounter in dbfiles.EnumerateTable("JournalEncounter", handler)) { var instanceId = encounter.Value.GetField <int>(3); if (instanceId != instance.Id) { continue; } var journalEncounter = new Encounter { Id = encounter.Key, Name = encounter.Value.GetField <string>(0), Description = encounter.Value.GetField <string>(1), MapX = encounter.Value.GetField <float>(2, 0), MapY = encounter.Value.GetField <float>(2, 1), InstanceId = instanceId, EncounterId = encounter.Value.GetField <int>(4), Order = encounter.Value.GetField <int>(5), FirstSectionId = encounter.Value.GetField <int>(6), UiMapId = encounter.Value.GetField <int>(7), MapDisplayConditionId = encounter.Value.GetField <int>(8), Flags = encounter.Value.GetField <byte>(9), Difficulty = encounter.Value.GetField <byte>(10), Sections = new List <JournalSection>() }; var sections = new Dictionary <int, JournalSection>(); foreach (var encounterSection in dbfiles.EnumerateTable("JournalEncounterSection", handler)) { var section = new JournalSection { Id = encounterSection.Key, Name = encounterSection.Value.GetField <string>(0), Description = encounterSection.Value.GetField <string>(1), JournalEncounterId = encounterSection.Value.GetField <ushort>(2), Order = encounterSection.Value.GetField <byte>(3), ParentSectionId = encounterSection.Value.GetField <ushort>(4), FirstChildSectionId = encounterSection.Value.GetField <ushort>(5), NextSiblingSectionId = encounterSection.Value.GetField <ushort>(6), SectionType = encounterSection.Value.GetField <byte>(7), // 3 = overview, 1 = creature, 2 = spell IconCreatureDisplayId = encounterSection.Value.GetField <uint>(8), UiModelSceneId = encounterSection.Value.GetField <int>(9), SpellId = encounterSection.Value.GetField <int>(10), IconFileDataId = encounterSection.Value.GetField <int>(11), Flags = encounterSection.Value.GetField <ushort>(12), IconFlags = encounterSection.Value.GetField <ushort>(13), // 1=tank, 2=dps, 4=healer, DifficultyMask = encounterSection.Value.GetField <byte>(14), }; if (section.JournalEncounterId != journalEncounter.Id) { continue; } sections[section.Id] = section; } journalEncounter.Sections = BuildSectionTree(sections); encounters.Add(journalEncounter); } await container.GetBlockBlobReference("data/dungeon/" + instance.Id + "/encounters." + localeName + ".json") .UploadTextAsync(JsonConvert.SerializeObject(encounters, serializerSettings)); } // Save the list of dungeons for this tier await container.GetBlockBlobReference("data/" + tier.Id + "/dungeons." + localeName + ".json") .UploadTextAsync(JsonConvert.SerializeObject(dungeons, serializerSettings)); } return(new OkObjectResult(tiers)); }
public void ParseCsv() { StreamReader sr = new StreamReader(csvPath); string data = sr.ReadLine(); int count = 0; // Adding the CASC root as first item in folder list CASCFolder root = new CASCFolder(0, -1, "Root"); CASCMain.CASCFolders.Add(root); while ((data = sr.ReadLine()) != null) { read = data.Split(seperators, StringSplitOptions.None); //read[0] // FileDataID //read[read.Length -1] // Filename.xxx int parentID = -1; for (int i = 1; i < read.Length - 1; i++) { if (i == 1) // First Folder, parent is root { parentID = 0; } /*StringBuilder sb = new StringBuilder(); * sb.Append(parentID.ToString()); * char[] chars = read[i].ToCharArray(); * foreach (char c in chars) { * int cIndex = char.ToUpper(c) - 64; * sb.Append(cIndex); * } */ string sID = parentID.ToString() + read[i]; int uniqueID = sID.GetHashCode(); //IEnumerable<CASCFolder> matchingFolders = CASCMain.CASCFolders.Where(folder => folder.ParentDirectoryID == parentID).ToList(); // Where(folder => folder.Value == value).ToList(); /*bool addNew = false; * foreach (CASCFolder cf in CASCMain.CASCFolders) { * if (cf.DirectoryID == uniqueID) { * addNew = false; * } * else { * addNew = true; * } * }*/ //if (addNew) { // CASCFolder currentFolder = new CASCFolder(uniqueID, parentID, read[i]); // CASCMain.CASCFolders.Add(currentFolder); //} parentID = uniqueID; // Finally set parentID so it will be used next loop /*if (count < 200) { * Debug.Log(sID); * }*/ } count++; } Debug.Log(CASCMain.CASCFolders.Count); }
static async Task ExtractJournal(string localeName = "en-US") { CASCConfig config = CASCConfig.LoadLocalStorageConfig(@"C:\Games\World of Warcraft", "wow"); CASCHandler handler = CASCHandler.OpenStorage(config, null); handler.Root.LoadListFile(Path.Combine(Environment.CurrentDirectory, "listfile8x.csv")); var locale = GetLocale(localeName); CASCFolder root = handler.Root.SetFlags(locale); handler.Root.MergeInstall(handler.Install); var dbfiles = (CASCFolder)root.Entries["dbfilesclient"]; // Apply translations to expansion / tiers var tiers = WowExpansion.All; foreach (var pair in dbfiles.EnumerateTable("JournalTier", handler)) { var tier = tiers.Single(x => x.Value.TierId == pair.Key); tier.Value.Name = pair.Value.GetField <string>(0); } var instanceTiers = new Dictionary <int, int>(); { foreach (var pair in dbfiles.EnumerateTable("JournalTierXInstance", handler)) { var tierId = pair.Value.GetField <int>(0); var instanceId = pair.Value.GetField <int>(1); instanceTiers[instanceId] = tierId; } } // All keystone dungeons Console.WriteLine(); Console.WriteLine("Loading challenge dungeons..."); var keystones = new List <MythicKeystone>(); foreach (var pair in dbfiles.EnumerateTable("MapChallengeMode", handler)) { var keystone = new MythicKeystone(); keystone.Id = pair.Key; keystone.Slug = GetSlug(pair.Value.GetField <string>(0)); keystone.Name = pair.Value.GetField <string>(0); keystone.MapId = pair.Value.GetField <ushort>(2); keystone.Flags = pair.Value.GetField <byte>(3); // keystone.ExpansionId = pair.Value.GetField<uint>(4); keystone.ScenarioId = 0; keystone.BronzeTimer = pair.Value.GetField <ushort>(4, 0); keystone.SilverTimer = pair.Value.GetField <ushort>(4, 1); keystone.GoldTimer = pair.Value.GetField <ushort>(4, 2); keystones.Add(keystone); } // Get all instances Console.WriteLine(); Console.WriteLine("Loading instances..."); var instances = (from pair in dbfiles.EnumerateTable("JournalInstance", handler) where instanceTiers.ContainsKey(pair.Key) select new Instance { Id = pair.Key, Slug = GetSlug(pair.Value.GetField <string>(0)), Name = pair.Value.GetField <string>(0), Description = pair.Value.GetField <string>(1), MapId = pair.Value.GetField <int>(3), BackgroundImageId = pair.Value.GetField <int>(4), ButtonImageId = pair.Value.GetField <int>(5), ButtonSmallImageId = pair.Value.GetField <int>(6), LoreImageId = pair.Value.GetField <int>(7), Order = pair.Value.GetField <int>(8), Flags = pair.Value.GetField <int>(9), TierId = instanceTiers[pair.Key] }).ToList(); // All encounters Console.WriteLine(); Console.WriteLine("Loading encounters..."); var encounters = (from pair in dbfiles.EnumerateTable("JournalEncounter", handler) select new Encounter { Id = pair.Key, Slug = "", Name = pair.Value.GetField <string>(0), Description = pair.Value.GetField <string>(1), MapX = pair.Value.GetField <float>(2, 0), MapY = pair.Value.GetField <float>(2, 1), InstanceId = pair.Value.GetField <int>(3), EncounterId = pair.Value.GetField <int>(4), Order = pair.Value.GetField <int>(5), FirstSectionId = pair.Value.GetField <int>(6), UiMapId = pair.Value.GetField <int>(7), MapDisplayConditionId = pair.Value.GetField <int>(8), Flags = pair.Value.GetField <byte>(9), Difficulty = pair.Value.GetField <byte>(10), Sections = new List <JournalSection>() }).ToList(); // All sections Console.WriteLine(); Console.WriteLine("Loading encounter sections..."); var sections = (from pair in dbfiles.EnumerateTable("JournalEncounterSection", handler) select new JournalSection { Id = pair.Key, Name = pair.Value.GetField <string>(0), Description = pair.Value.GetField <string>(1), JournalEncounterId = pair.Value.GetField <ushort>(2), Order = pair.Value.GetField <byte>(3), ParentSectionId = pair.Value.GetField <ushort>(4), FirstChildSectionId = pair.Value.GetField <ushort>(5), NextSiblingSectionId = pair.Value.GetField <ushort>(6), SectionType = pair.Value.GetField <byte>(7), // 3 = overview, 1 = creature, 2 = spell IconCreatureDisplayId = pair.Value.GetField <uint>(8), UiModelSceneId = pair.Value.GetField <int>(9), SpellId = pair.Value.GetField <int>(10), IconFileDataId = pair.Value.GetField <int>(11), Flags = pair.Value.GetField <ushort>(12), IconFlags = pair.Value.GetField <ushort>(13), // 1=tank, 2=dps, 4=healer, DifficultyMask = pair.Value.GetField <byte>(14), }).ToList(); // Build the tree Console.WriteLine(); Console.WriteLine("Building tree.."); foreach (var instance in instances) { instance.Encounters = new List <Encounter>(); foreach (var encounter in encounters.Where(x => x.InstanceId == instance.Id)) { encounter.Sections = BuildSectionTree(sections.Where(x => x.JournalEncounterId == encounter.Id)); instance.Encounters.Add(encounter); } } Console.WriteLine(); Console.WriteLine("Reading in edits..."); var existingKeystones = await ReadJson <IList <MythicKeystone> >("keystones.json"); var existingInstances = await ReadJson <IList <Instance> >("instances.json"); // Update keystone slugs foreach (var existingKeystone in existingKeystones) { var keystone = keystones.SingleOrDefault(x => x.Id == existingKeystone.Id); if (keystone == null) { continue; } keystone.Slug = existingKeystone.Slug; } // Update instance and encounter slugs foreach (var existingInstance in existingInstances) { var instance = instances.SingleOrDefault(x => x.Id == existingInstance.Id); if (instance == null) { continue; } instance.Slug = existingInstance.Slug; foreach (var existingEncounter in existingInstance.Encounters) { var encounter = instance.Encounters.SingleOrDefault(x => x.Id == existingEncounter.Id); if (encounter == null) { continue; } encounter.Slug = existingEncounter.Slug; } } Console.WriteLine(); Console.WriteLine("Exporting.."); await DumpJson("keystones.json", keystones); await DumpJson("tiers.json", tiers.Values); await DumpJson("instances.json", instances); Console.WriteLine(); Console.WriteLine("Done."); }