public void GetGeneralUnlocks(ICLIFlags toolFlags) { string basePath; if (toolFlags is ExtractFlags flags) { basePath = flags.OutputPath; } else { throw new Exception("no output path"); } foreach (var key in TrackedFiles[0x54]) { STUGlobalInventoryMaster invMaster = GetInstance <STUGlobalInventoryMaster>(key); if (invMaster == null) { continue; } var achivementUnlocks = invMaster.AchievementUnlocks?.Unlocks?.Select(it => GatherUnlock((ulong)it)).ToList(); SprayAndIcon.SaveItems(basePath, null, "General", "Achievements", flags, achivementUnlocks); if (invMaster.EventGeneralUnlocks != null) { foreach (var eventUnlocks in invMaster.EventGeneralUnlocks) { if (eventUnlocks?.Unlocks?.Unlocks == null) { continue; } var eventKey = ItemEvents.GetInstance().EventsNormal[(uint)eventUnlocks.Event]; var unlocks = eventUnlocks.Unlocks.Unlocks.Select(it => GatherUnlock((ulong)it)).ToList(); SprayAndIcon.SaveItems(basePath, null, "General", eventKey, flags, unlocks); } } if (invMaster.LevelUnlocks != null) { var unlocks = new HashSet <ItemInfo>(); foreach (var levelUnlocks in invMaster.LevelUnlocks) { if (levelUnlocks?.Unlocks == null) { continue; } foreach (var unlock in levelUnlocks.Unlocks) { unlocks.Add(GatherUnlock(unlock)); } } SprayAndIcon.SaveItems(basePath, null, "General", "Standard", flags, unlocks.ToList()); Portrait.SaveItems(basePath, null, "General", "Standard", flags, unlocks.ToList()); } } }
public Dictionary <string, HashSet <ItemInfo> > GetUnlocks() { Dictionary <string, HashSet <ItemInfo> > @return = new Dictionary <string, HashSet <ItemInfo> >(); foreach (ulong key in TrackedFiles[0x54]) { STUGlobalInventoryMaster invMaster = GetInstance <STUGlobalInventoryMaster>(key); if (invMaster == null) { continue; } @return["Achievement"] = GatherUnlocks(invMaster.AchievementUnlocks?.Unlocks?.Select(it => (ulong)it)); @return["Standard"] = new HashSet <ItemInfo>(); if (invMaster.LevelUnlocks != null) { foreach (STUAdditionalUnlocks levelUnlocks in invMaster.LevelUnlocks) { if (levelUnlocks?.Unlocks == null) { continue; } foreach (ItemInfo info in GatherUnlocks(levelUnlocks.Unlocks.Select(it => (ulong)it))) { @return["Standard"].Add(info); } } } if (invMaster.EventGeneralUnlocks != null) { foreach (STULootBoxUnlocks eventUnlocks in invMaster.EventGeneralUnlocks) { if (eventUnlocks?.Unlocks?.Unlocks == null) { continue; } string eventKey = $"Event/{ItemEvents.GetInstance().EventsNormal[(uint)eventUnlocks.Event]}"; if ([email protected](eventKey)) { @return[eventKey] = new HashSet <ItemInfo>(); } foreach (ItemInfo info in GatherUnlocks(eventUnlocks.Unlocks.Unlocks.Select(it => (ulong)it))) { @return[eventKey].Add(info); } } } } return(@return); }
public static Dictionary <string, HashSet <ItemInfo> > GetUnlocksForHero(ulong guid) { Dictionary <string, HashSet <ItemInfo> > @return = new Dictionary <string, HashSet <ItemInfo> >(); STUHeroUnlocks unlocks = GetInstance <STUHeroUnlocks>(guid); if (unlocks == null) { return(null); } @return["Default"] = GatherUnlocks(unlocks.SystemUnlocks?.Unlocks?.Select(it => (ulong)it)); if (unlocks.Unlocks != null) { foreach (STUUnlocks defaultUnlocks in unlocks.Unlocks) { if (defaultUnlocks?.Unlocks == null) { continue; } if ([email protected]("Standard")) { @return["Standard"] = new HashSet <ItemInfo>(); } foreach (ItemInfo info in GatherUnlocks(defaultUnlocks.Unlocks.Select(it => (ulong)it))) { @return["Standard"].Add(info); } } } if (unlocks.LootboxUnlocks != null) { foreach (STULootBoxUnlocks eventUnlocks in unlocks.LootboxUnlocks) { if (eventUnlocks?.Unlocks?.Unlocks == null) { continue; } string eventKey = $"Event/{ItemEvents.GetInstance().EventsNormal[(uint)eventUnlocks.Event]}"; if ([email protected](eventKey)) { @return[eventKey] = new HashSet <ItemInfo>(); } foreach (ItemInfo info in GatherUnlocks(eventUnlocks.Unlocks.Unlocks.Select(it => (ulong)it))) { @return[eventKey].Add(info); } } } return(@return); }
public void Parse(Dictionary <ushort, List <ulong> > track, Dictionary <ulong, Record> map, CASCHandler handler, bool quiet, OverToolFlags flags) { List <ulong> masters = track[0x75]; foreach (ulong masterKey in masters) { if (!map.ContainsKey(masterKey)) { continue; } STUD masterStud = new STUD(Util.OpenFile(map[masterKey], handler)); if (masterStud.Instances == null) { continue; } HeroMaster master = (HeroMaster)masterStud.Instances[0]; if (master == null) { continue; } string heroName = Util.GetString(master.Header.name.key, map, handler); if (heroName == null) { continue; } string goodhero = heroName; foreach (var c in Path.GetInvalidFileNameChars()) { goodhero = goodhero.Replace(c, '_'); } if (master.Header.itemMaster.key == 0) // AI { continue; } bool ex = System.Diagnostics.Debugger.IsAttached || flags.Expert; bool hasName = false; if (!map.ContainsKey(master.Header.itemMaster.key)) { Console.Out.WriteLine("Error loading inventory master file..."); continue; } STUD inventoryStud = new STUD(Util.OpenFile(map[master.Header.itemMaster.key], handler)); #if OUTPUT_STUDINVENTORYMASTER Stream studStream = Util.OpenFile(map[master.Header.itemMaster.key], handler); string outFilename = string.Format("./STUDs/ListInventoryMaster/{0}.stud", goodhero); string putPathname = outFilename.Substring(0, outFilename.LastIndexOf('/')); Directory.CreateDirectory(putPathname); Stream OutWriter = File.Create(outFilename); studStream.CopyTo(OutWriter); OutWriter.Close(); studStream.Close(); #endif InventoryMaster inventory = (InventoryMaster)inventoryStud.Instances[0]; if (inventory == null) { Console.Out.WriteLine("Error loading inventory master file..."); continue; } Dictionary <int, string> indexMap = new Dictionary <int, string>(); List <OWRecord> items = new List <OWRecord>(); items.AddRange(inventory.Achievables.ToList()); for (int i = 0; i < inventory.DefaultGroups.Length; ++i) { string name = $"STANDARD_{ItemEvents.GetInstance().GetEvent(inventory.DefaultGroups[i].@event)}"; items.AddRange(inventory.Defaults[i].ToList()); } for (int i = 0; i < inventory.ItemGroups.Length; ++i) { string name = ItemEvents.GetInstance().GetEvent(inventory.ItemGroups[i].@event); items.AddRange(inventory.Items[i].ToList()); } foreach (OWRecord record in items) { STUD item = new STUD(Util.OpenFile(map[record], handler)); if (item.Instances == null) { continue; } WeaponSkinItem skin = item.Instances[0] as WeaponSkinItem; if (skin == null) { continue; } if (!hasName) { if (ex) { Console.Out.WriteLine("Weapons for {0} ({2:X16}) in package {1:X16}", heroName, map[masterKey].package.packageKey, masterKey); } else { Console.Out.WriteLine("Weapons for {0}", heroName); } hasName = true; } Console.Out.WriteLine("\tIndex {0} - {1}", skin.Data.index, Util.GetString(skin.Header.name, map, handler)); } if (hasName) { Console.Out.WriteLine(""); } } }
public void Parse(Dictionary <ushort, List <ulong> > track, Dictionary <ulong, Record> map, CASCHandler handler, bool quiet, OverToolFlags flags) { List <ulong> masters = track[0x75]; foreach (ulong masterKey in masters) { if (!map.ContainsKey(masterKey)) { continue; } STUD masterStud = new STUD(Util.OpenFile(map[masterKey], handler)); if (masterStud.Instances == null) { continue; } HeroMaster master = (HeroMaster)masterStud.Instances[0]; if (master == null) { continue; } string heroName = Util.GetString(master.Header.name.key, map, handler); if (heroName == null) { continue; } string goodhero = heroName; foreach (var c in Path.GetInvalidFileNameChars()) { goodhero = goodhero.Replace(c, '_'); } if (master.Header.itemMaster.key == 0) // AI { continue; } bool ex = System.Diagnostics.Debugger.IsAttached || flags.Expert; if (ex) { Console.Out.WriteLine("Cosmetics for {0} ({1:X16})", heroName, GUID.LongKey(masterKey)); } else { Console.Out.WriteLine("Cosmetics for {0}", heroName); } if (!map.ContainsKey(master.Header.itemMaster.key)) { Console.Out.WriteLine("Error loading inventory master file..."); continue; } STUD inventoryStud = new STUD(Util.OpenFile(map[master.Header.itemMaster.key], handler)); #if OUTPUT_STUDINVENTORYMASTER Stream studStream = Util.OpenFile(map[master.Header.itemMaster.key], handler); string outFilename = string.Format("./STUDs/ListInventoryMaster/{0}.stud", goodhero); string putPathname = outFilename.Substring(0, outFilename.LastIndexOf('/')); Directory.CreateDirectory(putPathname); Stream OutWriter = File.Create(outFilename); studStream.CopyTo(OutWriter); OutWriter.Close(); studStream.Close(); #endif InventoryMaster inventory = (InventoryMaster)inventoryStud.Instances[0]; if (inventory == null) { Console.Out.WriteLine("Error loading inventory master file..."); continue; } Console.Out.WriteLine("\tACHIEVEMENT ({0} items)", inventory.Achievables.Length); foreach (OWRecord record in inventory.Achievables) { GetInventoryName(record.key, ex, map, handler, goodhero); } for (int i = 0; i < inventory.DefaultGroups.Length; ++i) { if (inventory.Defaults[i].Length == 0) { continue; } OWRecord[] records = inventory.Defaults[i]; Console.Out.WriteLine("\tSTANDARD_{0} ({1} items)", ItemEvents.GetInstance().GetEvent(inventory.DefaultGroups[i].@event), records.Length); foreach (OWRecord record in records) { GetInventoryName(record.key, ex, map, handler, goodhero); } } for (int i = 0; i < inventory.ItemGroups.Length; ++i) { if (inventory.Items[i].Length == 0) { continue; } OWRecord[] records = inventory.Items[i]; Console.Out.WriteLine("\t{0} ({1} items)", ItemEvents.GetInstance().GetEvent(inventory.ItemGroups[i].@event), records.Length); foreach (OWRecord record in records) { GetInventoryName(record.key, ex, map, handler, goodhero); } } Console.Out.WriteLine(""); } }
public void SaveUnlocksForHeroes(ICLIFlags flags, IEnumerable <STUHero> heroes, string basePath, bool npc = false) { if (flags.Positionals.Length < 4) { QueryHelp(QueryTypes); return; } Log("Initializing..."); Dictionary <string, Dictionary <string, ParsedArg> > parsedTypes = ParseQuery(flags, QueryTypes, QueryNameOverrides); if (parsedTypes == null) { return; } foreach (STUHero hero in heroes) { string heroNameActual = GetString(hero.Name); string heroFileName = GetValidFilename(heroNameActual); if (heroFileName == null) { continue; // heroFileName = "Unknown"; // heroNameActual = "Unknown"; } heroNameActual = heroNameActual.TrimEnd(' '); heroFileName = heroFileName.TrimEnd(' '); Dictionary <string, ParsedArg> config = new Dictionary <string, ParsedArg>(); foreach (string key in new [] { heroNameActual.ToLowerInvariant(), "*" }) { if (!parsedTypes.ContainsKey(key)) { continue; } foreach (KeyValuePair <string, ParsedArg> parsedArg in parsedTypes[key]) { if (config.ContainsKey(parsedArg.Key)) { config[parsedArg.Key] = config[parsedArg.Key].Combine(parsedArg.Value); } else { config[parsedArg.Key] = parsedArg.Value.Combine(null); // clone for safety } } } if (config.Count == 0) { continue; } var unlocks = GetInstance <STUHeroUnlocks>(hero.LootboxUnlocks); if (unlocks?.Unlocks == null && !npc) { continue; } if (unlocks?.LootboxUnlocks != null && npc) { continue; } Log($"Processing data for {heroNameActual}..."); List <ItemInfo> weaponSkins = ListHeroUnlocks.GetUnlocksForHero(hero.LootboxUnlocks)?.SelectMany(x => x.Value.Where(y => y.Type == "Weapon")).ToList(); // eww? var achievementUnlocks = GatherUnlocks(unlocks?.SystemUnlocks?.Unlocks?.Select(it => (ulong)it)).ToList(); foreach (ItemInfo itemInfo in achievementUnlocks) { if (itemInfo == null) { continue; } Dictionary <string, TagExpectedValue> tags = new Dictionary <string, TagExpectedValue> { { "event", new TagExpectedValue("base") } }; SaveItemInfo(itemInfo, basePath, heroFileName, flags, hero, "Achievement", config, tags, weaponSkins); } if (npc) { foreach (STUHeroSkin skin in hero.Skins) { if (config.ContainsKey("skin") && config["skin"].ShouldDo(GetFileName(skin.SkinOverride))) { Skin.Save(flags, $"{basePath}\\{RootDir}", hero, skin, false); } } continue; } foreach (var defaultUnlocks in unlocks.Unlocks) { var dUnlocks = GatherUnlocks(defaultUnlocks.Unlocks.Select(it => (ulong)it)).ToList(); foreach (ItemInfo itemInfo in dUnlocks) { Dictionary <string, TagExpectedValue> tags = new Dictionary <string, TagExpectedValue> { { "event", new TagExpectedValue("base") } }; SaveItemInfo(itemInfo, basePath, heroFileName, flags, hero, "Standard", config, tags, weaponSkins); } } foreach (var eventUnlocks in unlocks.LootboxUnlocks) { if (eventUnlocks?.Unlocks?.Unlocks == null) { continue; } var eventKey = ItemEvents.GetInstance().EventsNormal[(uint)eventUnlocks.Event]; var eUnlocks = eventUnlocks.Unlocks.Unlocks.Select(it => GatherUnlock(it)).ToList(); foreach (ItemInfo itemInfo in eUnlocks) { if (itemInfo == null) { continue; } Dictionary <string, TagExpectedValue> tags = new Dictionary <string, TagExpectedValue> { { "event", new TagExpectedValue(eventUnlocks.Event.ToString().ToLowerInvariant()) } }; SaveItemInfo(itemInfo, basePath, heroFileName, flags, hero, eventKey, config, tags, weaponSkins); } } Combo.ComboInfo guiInfo = new Combo.ComboInfo(); Combo.Find(guiInfo, hero.ImageResource1); Combo.Find(guiInfo, hero.ImageResource2); Combo.Find(guiInfo, hero.ImageResource3); Combo.Find(guiInfo, hero.ImageResource4); guiInfo.SetTextureName(hero.ImageResource1, "Icon"); guiInfo.SetTextureName(hero.ImageResource2, "Portrait"); guiInfo.SetTextureName(hero.ImageResource4, "Avatar"); guiInfo.SetTextureName(hero.SpectatorIcon, "SpectatorIcon"); SaveLogic.Combo.SaveLooseTextures(flags, Path.Combine(basePath, RootDir, heroFileName, "GUI"), guiInfo); } }
public void Parse(Dictionary <ushort, List <ulong> > track, Dictionary <ulong, Record> map, CASCHandler handler, bool quiet, OverToolFlags flags) { Dictionary <string, Dictionary <string, Dictionary <string, List <JSONPkg> > > > dict = new Dictionary <string, Dictionary <string, Dictionary <string, List <JSONPkg> > > >(); foreach (ulong key in track[0x54]) { if (!map.ContainsKey(key)) { continue; } using (Stream input = Util.OpenFile(map[key], handler)) { if (input == null) { continue; } STUD stud = new STUD(input); if (stud.Instances == null || stud.Instances[0] == null) { continue; } GlobalInventoryMaster master = stud.Instances[0] as GlobalInventoryMaster; if (master == null) { continue; } if (!dict.ContainsKey("ACHIEVEMENT")) { dict["ACHIEVEMENT"] = new Dictionary <string, Dictionary <string, List <JSONPkg> > >(); } if (!dict.ContainsKey("AVAILABLE")) { dict["AVAILABLE"] = new Dictionary <string, Dictionary <string, List <JSONPkg> > >(); } if (!dict.ContainsKey("LOOTBOX_EXCLUSIVE")) { dict["LOOTBOX_EXCLUSIVE"] = new Dictionary <string, Dictionary <string, List <JSONPkg> > >(); } for (int i = 0; i < master.Generic.Length; ++i) { if (master.GenericItems[i].Length == 0) { continue; } string s = ItemEvents.GetInstance().GetEvent(master.Generic[i].@event); if (!dict["ACHIEVEMENT"].ContainsKey(s)) { dict["ACHIEVEMENT"][s] = new Dictionary <string, List <JSONPkg> >(); } for (int j = 0; j < master.GenericItems[i].Length; ++j) { JSONPkg pkg = GenerateJSONPkg(master.GenericItems[i][j].key, map, handler); if (pkg.Name == null) { continue; } pkg.EventId = master.Generic[i].@event; pkg.Event = s; if (!dict["ACHIEVEMENT"][s].ContainsKey(pkg.Type)) { dict["ACHIEVEMENT"][s][pkg.Type] = new List <JSONPkg>(); } dict["ACHIEVEMENT"][s][pkg.Type].Add(pkg); } } for (int i = 0; i < master.Categories.Length; ++i) { if (master.CategoryItems[i].Length == 0) { continue; } string s = ItemEvents.GetInstance().GetEvent(master.Categories[i].@event); if (!dict["AVAILABLE"].ContainsKey(s)) { dict["AVAILABLE"][s] = new Dictionary <string, List <JSONPkg> >(); } for (int j = 0; j < master.CategoryItems[i].Length; ++j) { JSONPkg pkg = GenerateJSONPkg(master.CategoryItems[i][j].key, map, handler); if (pkg.Name == null) { continue; } pkg.EventId = master.Categories[i].@event; pkg.Event = s; if (!dict["AVAILABLE"][s].ContainsKey(pkg.Type)) { dict["AVAILABLE"][s][pkg.Type] = new List <JSONPkg>(); } dict["AVAILABLE"][s][pkg.Type].Add(pkg); } } for (int i = 0; i < master.ExclusiveOffsets.Length; ++i) { if (master.LootboxExclusive[i].Length == 0) { continue; } string s = ItemEvents.GetInstance().GetEvent((ulong)i); if (!dict["LOOTBOX_EXCLUSIVE"].ContainsKey(s)) { dict["LOOTBOX_EXCLUSIVE"][s] = new Dictionary <string, List <JSONPkg> >(); } for (int j = 0; j < master.LootboxExclusive[i].Length; ++j) { JSONPkg pkg = GenerateJSONPkg(master.LootboxExclusive[i][j].item, map, handler); if (pkg.Name == null) { continue; } pkg.EventId = (ulong)i; pkg.Event = s; if (!dict["LOOTBOX_EXCLUSIVE"][s].ContainsKey(pkg.Type)) { dict["LOOTBOX_EXCLUSIVE"][s][pkg.Type] = new List <JSONPkg>(); } dict["LOOTBOX_EXCLUSIVE"][s][pkg.Type].Add(pkg); } } } } if (Path.GetDirectoryName(flags.Positionals[2]).Trim().Length > 0 && !Directory.Exists(Path.GetDirectoryName(flags.Positionals[2]))) { Directory.CreateDirectory(Path.GetDirectoryName(flags.Positionals[2])); } using (Stream file = File.OpenWrite(flags.Positionals[2])) { using (TextWriter writer = new StreamWriter(file)) { writer.Write(JsonConvert.SerializeObject(dict, Formatting.Indented)); } } }
public void Parse(Dictionary <ushort, List <ulong> > track, Dictionary <ulong, Record> map, CASCHandler handler, bool quiet, OverToolFlags flags) { foreach (ulong key in track[0x54]) { if (!map.ContainsKey(key)) { continue; } Dictionary <OWRecord, string> items = new Dictionary <OWRecord, string>(); using (Stream input = Util.OpenFile(map[key], handler)) { if (input == null) { continue; } STUD stud = new STUD(input); if (stud.Instances == null || stud.Instances[0] == null) { continue; } GlobalInventoryMaster master = stud.Instances[0] as GlobalInventoryMaster; if (master == null) { continue; } Console.Out.WriteLine("\tACHIEVEMENT"); foreach (OWRecord record in master.StandardItems) { ListInventory.GetInventoryName(record.key, false, map, handler, "General"); } Dictionary <string, List <OWRecord> > aggreg = new Dictionary <string, List <OWRecord> >(); for (int i = 0; i < master.Generic.Length; ++i) { if (master.GenericItems[i].Length == 0) { continue; } string s = $"\tSTANDARD_{ItemEvents.GetInstance().GetEvent(master.Generic[i].@event)}"; if (!aggreg.ContainsKey(s)) { aggreg[s] = new List <OWRecord>(); } for (int j = 0; j < master.GenericItems[i].Length; ++j) { aggreg[s].Add(master.GenericItems[i][j]); } } foreach (KeyValuePair <string, List <OWRecord> > pair in aggreg) { Console.Out.WriteLine(pair.Key); foreach (OWRecord record in pair.Value) { ListInventory.GetInventoryName(record, false, map, handler, "General"); } } aggreg.Clear(); for (int i = 0; i < master.Categories.Length; ++i) { if (master.CategoryItems[i].Length == 0) { continue; } Console.Out.WriteLine($"\t{ItemEvents.GetInstance().GetEvent(master.Categories[i].@event)}"); for (int j = 0; j < master.CategoryItems[i].Length; ++j) { ListInventory.GetInventoryName(master.CategoryItems[i][j], false, map, handler, "General"); } } for (int i = 0; i < master.ExclusiveOffsets.Length; ++i) { if (master.LootboxExclusive[i].Length == 0) { continue; } Console.Out.WriteLine($"\tLOOTBOX_EXCLUSIVE_{ItemEvents.GetInstance().GetEvent((ulong)i)}"); for (int j = 0; j < master.LootboxExclusive[i].Length; ++j) { ListInventory.GetInventoryName(master.LootboxExclusive[i][j].item, false, map, handler, "General"); } } } } }
public void Parse(Dictionary <ushort, List <ulong> > track, Dictionary <ulong, Record> map, CASCHandler handler, bool quiet, OverToolFlags flags) { string output = flags.Positionals[2]; foreach (ulong key in track[0x54]) { if (!map.ContainsKey(key)) { continue; } Dictionary <OWRecord, string> items = new Dictionary <OWRecord, string>(); using (Stream input = Util.OpenFile(map[key], handler)) { if (input == null) { continue; } STUD stud = new STUD(input); if (stud.Instances == null || stud.Instances[0] == null) { continue; } GlobalInventoryMaster master = stud.Instances[0] as GlobalInventoryMaster; if (master == null) { continue; } foreach (OWRecord record in master.StandardItems) { items[record] = "ACHIEVEMENT"; } for (int i = 0; i < master.Generic.Length; ++i) { string name = $"STANDARD_{ItemEvents.GetInstance().GetEvent(master.Generic[i].@event)}"; for (int j = 0; j < master.GenericItems[i].Length; ++j) { items[master.GenericItems[i][j]] = name; } } for (int i = 0; i < master.Categories.Length; ++i) { string name = ItemEvents.GetInstance().GetEvent(master.Categories[i].@event); for (int j = 0; j < master.CategoryItems[i].Length; ++j) { items[master.CategoryItems[i][j]] = name; } } for (int i = 0; i < master.ExclusiveOffsets.Length; ++i) { string name = $"LOOTBOX_EXCLUSIVE_{i:X}"; for (int j = 0; j < master.LootboxExclusive[i].Length; ++j) { items[master.LootboxExclusive[i][j].item] = name; } } } foreach (KeyValuePair <OWRecord, string> recordname in items) { OWRecord record = recordname.Key; string itemGroup = recordname.Value; if (!map.ContainsKey(record.key)) { continue; } STUD stud = new STUD(Util.OpenFile(map[record.key], handler)); if (stud.Instances == null) { continue; } IInventorySTUDInstance instance = (IInventorySTUDInstance)stud.Instances[0]; string name = Util.GetString(instance.Header.name.key, map, handler); if (name == null) { name = $"{GUID.LongKey(key):X12}"; } switch (instance.Name) { case "Spray": Console.Out.WriteLine("Extracting spray {0}...", name); ExtractLogic.Spray.Extract(stud, output, "Generic", name, itemGroup, track, map, handler, quiet, flags); break; case "Icon": Console.Out.WriteLine("Extracting icon {0}...", name); ExtractLogic.Icon.Extract(stud, output, "Generic", name, itemGroup, track, map, handler, quiet, flags); break; case "Portrait": PortraitItem portrait = instance as PortraitItem; ExtractLogic.Portrait.Extract(stud, output, "Generic", $"Tier {portrait.Data.tier}", itemGroup, track, map, handler, quiet, flags); break; default: continue; } } } }
public void Parse(Dictionary <ushort, List <ulong> > track, Dictionary <ulong, Record> map, CASCHandler handler, bool quiet, OverToolFlags flags) { string output = flags.Positionals[2]; string[] validCommands = new string[] { "skin", "spray", "icon", "victory pose", "emote", "heroic intro" }; bool typeWildcard = true; List <string> types = new List <string>(); if (flags.Positionals.Length > 3) { types.AddRange(flags.Positionals[3].ToLowerInvariant().Split(new char[] { '+' }, StringSplitOptions.RemoveEmptyEntries)); typeWildcard = types.Contains("*"); types = types.FindAll((string it) => validCommands.Contains(it)).ToList(); } if (!typeWildcard && types.Count == 0) { string cmdlist = ""; for (int i = 0; i < validCommands.Length; i++) { if (i != 0) { cmdlist += ", "; if (i == validCommands.Length - 1) { cmdlist += "or "; } } cmdlist += validCommands[i].ToString().ToLower(); } Console.Out.WriteLine("The output type was not a valid option. ({0})", cmdlist); return; } Dictionary <string, List <string> > heroTypes = new Dictionary <string, List <string> >(); Dictionary <string, bool> heroWildcard = new Dictionary <string, bool>(); Dictionary <string, Dictionary <string, List <ulong> > > heroIgnore = new Dictionary <string, Dictionary <string, List <ulong> > >(); bool heroAllWildcard = false; if (flags.Positionals.Length > 4 && flags.Positionals[4] != "*") { foreach (string pair in flags.Positionals[4].ToLowerInvariant().Split(new char[] { '+' }, StringSplitOptions.RemoveEmptyEntries)) { List <string> data = new List <string>(pair.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries)); string name = data[0]; data.RemoveAt(0); if (!heroTypes.ContainsKey(name)) { heroTypes[name] = new List <string>(); heroIgnore[name] = new Dictionary <string, List <ulong> >(); heroWildcard[name] = false; } if (data.Count > 0) { foreach (string d in data) { List <string> subdata = new List <string>(d.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries)); string subn = subdata[0]; subdata.RemoveAt(0); heroTypes[name].Add(subn); heroIgnore[name][subn] = new List <ulong>(); if (subdata.Count > 0) { foreach (string sd in subdata) { try { heroIgnore[name][subn].Add(ulong.Parse(sd, System.Globalization.NumberStyles.HexNumber)); } catch { } } } } } if (data.Count == 0 || data.Contains("*")) { heroWildcard[name] = true; } } } else { heroAllWildcard = true; } int replacementIndex = flags.WeaponSkinIndex; List <ulong> masters = track[0x75]; foreach (ulong masterKey in masters) { if (!map.ContainsKey(masterKey)) { continue; } STUD masterStud = new STUD(Util.OpenFile(map[masterKey], handler)); if (masterStud.Instances == null) { continue; } HeroMaster master = (HeroMaster)masterStud.Instances[0]; if (master == null) { continue; } if (master.Header.itemMaster.key == 0) { continue; } string heroName = Util.GetString(master.Header.name.key, map, handler); if (heroName == null) { continue; } if (heroAllWildcard) { if (!heroTypes.ContainsKey(heroName.ToLowerInvariant())) { heroTypes.Add(heroName.ToLowerInvariant(), new List <string>()); } if (!heroWildcard.ContainsKey(heroName.ToLowerInvariant())) { heroWildcard.Add(heroName.ToLowerInvariant(), true); } } if (!heroTypes.ContainsKey(heroName.ToLowerInvariant())) { continue; } InventoryMaster inventory = OpenInventoryMaster(master, map, handler); if (inventory == null) { continue; } Dictionary <OWRecord, string> items = new Dictionary <OWRecord, string>(); foreach (OWRecord record in inventory.Achievables) { items[record] = "ACHIEVEMENT"; } for (int i = 0; i < inventory.DefaultGroups.Length; ++i) { string name = $"STANDARD_{ItemEvents.GetInstance().GetEvent(inventory.DefaultGroups[i].@event)}"; for (int j = 0; j < inventory.Defaults[i].Length; ++j) { items[inventory.Defaults[i][j]] = name; } } for (int i = 0; i < inventory.ItemGroups.Length; ++i) { string name = ItemEvents.GetInstance().GetEvent(inventory.ItemGroups[i].@event); for (int j = 0; j < inventory.Items[i].Length; ++j) { items[inventory.Items[i][j]] = name; } } foreach (KeyValuePair <OWRecord, string> recordname in items) { OWRecord record = recordname.Key; string itemGroup = recordname.Value; if (!map.ContainsKey(record.key)) { continue; } STUD stud = new STUD(Util.OpenFile(map[record.key], handler)); if (stud.Instances == null) { continue; } IInventorySTUDInstance instance = (IInventorySTUDInstance)stud.Instances[0]; if (!typeWildcard && !types.Contains(instance.Name.ToLowerInvariant())) { continue; } string name = Util.GetString(instance.Header.name.key, map, handler); if (name == null) { name = $"Untitled-{GUID.LongKey(instance.Header.name.key):X12}"; continue; } if (!heroWildcard[heroName.ToLowerInvariant()] && !heroTypes[heroName.ToLowerInvariant()].Contains(name.ToLowerInvariant())) { continue; } switch (instance.Name) { case "Spray": Console.Out.WriteLine("Extracting spray {0} for {1}...", name, heroName); ExtractLogic.Spray.Extract(stud, output, heroName, name, itemGroup, track, map, handler, quiet, flags); break; case "Skin": List <ulong> ignoreList = new List <ulong>(); try { ignoreList = heroIgnore[heroName.ToLowerInvariant()][name.ToLowerInvariant()]; } catch { } Console.Out.WriteLine("Extracting {0} models and textures for {1}", name, heroName); ExtractLogic.Skin.Extract(master, stud, output, heroName, name, itemGroup, ignoreList, track, map, handler, quiet, flags, masterKey, replacementIndex); break; case "Icon": Console.Out.WriteLine("Extracting icon {0} for {1}...", name, heroName); ExtractLogic.Icon.Extract(stud, output, heroName, name, itemGroup, track, map, handler, quiet, flags); break; case "Emote": case "Victory Pose": case "Heroic Intro": Console.Out.WriteLine("Extracting {2} {0} for {1}...", name, heroName, instance.Name); ExtractLogic.ItemAnimation.Extract(record.key, stud, output, heroName, name, itemGroup, track, map, handler, quiet, flags); break; case "Voice Line": //Console.Out.WriteLine("Extracting voice line {0} for {1}...", name, heroName); //ExtractLogic.VoiceLine.Extract(master, stud, output, heroName, name, track, map, handler); break; } } } }
public void Parse(Dictionary <ushort, List <ulong> > track, Dictionary <ulong, Record> map, CASCHandler handler, bool quiet, OverToolFlags flags) { string output = flags.Positionals[2]; HashSet <string> heroes = new HashSet <string>(); HashSet <string> heroBlank = new HashSet <string>(); Dictionary <string, HashSet <string> > heroSkin = new Dictionary <string, HashSet <string> >(); bool heroAllWildcard = false; if (flags.Positionals.Length > 3 && flags.Positionals[1] != "*") { foreach (string name in flags.Positionals[3].ToLowerInvariant().Split(new char[] { '+' }, StringSplitOptions.RemoveEmptyEntries)) { string[] data = name.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries); string realname = data[0]; heroes.Add(realname); data = data.Skip(1).ToArray(); if (data.Length == 0) { heroBlank.Add(realname); continue; } heroSkin[realname] = new HashSet <string>(); foreach (string skin in data) { heroSkin[realname].Add(skin); } } } else { heroAllWildcard = true; } List <ulong> masters = track[0x75]; foreach (ulong masterKey in masters) { if (!map.ContainsKey(masterKey)) { continue; } STUD masterStud = new STUD(Util.OpenFile(map[masterKey], handler)); if (masterStud.Instances == null) { continue; } HeroMaster master = (HeroMaster)masterStud.Instances[0]; if (master == null) { continue; } if (master.Header.itemMaster.key == 0) { continue; } string heroName = Util.GetString(master.Header.name.key, map, handler); if (heroName == null) { continue; } if (heroAllWildcard) { heroes.Add(heroName.ToLowerInvariant()); heroBlank.Add(heroName.ToLowerInvariant()); } if (!heroes.Contains(heroName.ToLowerInvariant())) { continue; } InventoryMaster inventory = OpenInventoryMaster(master, map, handler); if (inventory == null) { continue; } Dictionary <OWRecord, string> items = new Dictionary <OWRecord, string>(); foreach (OWRecord record in inventory.Achievables) { items[record] = "ACHIEVEMENT"; } for (int i = 0; i < inventory.DefaultGroups.Length; ++i) { string name = $"STANDARD_{ItemEvents.GetInstance().GetEvent(inventory.DefaultGroups[i].@event)}"; for (int j = 0; j < inventory.Defaults[i].Length; ++j) { items[inventory.Defaults[i][j]] = name; } } for (int i = 0; i < inventory.ItemGroups.Length; ++i) { string name = ItemEvents.GetInstance().GetEvent(inventory.ItemGroups[i].@event); for (int j = 0; j < inventory.Items[i].Length; ++j) { items[inventory.Items[i][j]] = name; } } Dictionary <string, WeaponSkinItem> weaponskins = new Dictionary <string, WeaponSkinItem>(); Console.Out.WriteLine("Finding weapon skins for {0}", heroName); foreach (KeyValuePair <OWRecord, string> recordname in items) { OWRecord record = recordname.Key; string itemGroup = recordname.Value; if (!map.ContainsKey(record.key)) { continue; } STUD stud = new STUD(Util.OpenFile(map[record.key], handler)); if (stud.Instances == null) { continue; } IInventorySTUDInstance instance = (IInventorySTUDInstance)stud.Instances[0]; WeaponSkinItem weapon = instance as WeaponSkinItem; if (weapon == null) { continue; } if (weapon.Data.index == 0) { continue; } string name = Util.GetString(instance.Header.name.key, map, handler); if (name == null) { name = $"Untitled-{GUID.LongKey(instance.Header.name.key):X12}"; continue; } weaponskins[name] = weapon; Console.Out.WriteLine("Found data for weapon skin {0}", name); } foreach (KeyValuePair <OWRecord, string> recordname in items) { OWRecord record = recordname.Key; string itemGroup = recordname.Value; if (!map.ContainsKey(record.key)) { continue; } STUD stud = new STUD(Util.OpenFile(map[record.key], handler)); if (stud.Instances == null) { continue; } IInventorySTUDInstance instance = (IInventorySTUDInstance)stud.Instances[0]; SkinItem skin = instance as SkinItem; if (skin == null) { continue; } string name = Util.GetString(instance.Header.name.key, map, handler); if (name == null) { name = $"Untitled-{GUID.LongKey(instance.Header.name.key):X12}"; continue; } if (heroBlank.Contains(heroName.ToLowerInvariant()) || heroSkin[heroName.ToLowerInvariant()].Contains(name.ToLowerInvariant())) { Console.Out.WriteLine("Saving textures for skin {0}", name); foreach (KeyValuePair <string, WeaponSkinItem> pair in weaponskins) { string output_real = string.Format("{0}{1}{4}{1}Weapon Skin{1}{2}{1}{3}{1}", output, System.IO.Path.DirectorySeparatorChar, Util.SanitizePath(pair.Key), Util.SanitizePath(name), Util.SanitizePath(heroName)); Dictionary <ulong, ulong> replace = new Dictionary <ulong, ulong>(); ExtractLogic.Skin.FindReplacements(skin.Data.skin.key, (int)pair.Value.Data.index, replace, new HashSet <ulong>(), map, handler, master, skin, true); Dictionary <ulong, ulong> replace_blank = new Dictionary <ulong, ulong>(); ExtractLogic.Skin.FindReplacements(skin.Data.skin.key, -1, replace_blank, new HashSet <ulong>(), map, handler, master, skin, false); if (replace.Values.Count == 0) { continue; } Dictionary <ulong, List <ImageLayer> > layers = new Dictionary <ulong, List <ImageLayer> >(); Dictionary <ulong, List <ImageLayer> > layers_orig = new Dictionary <ulong, List <ImageLayer> >(); foreach (KeyValuePair <ulong, ulong> texture_pair in replace) { ushort type = GUID.Type(texture_pair.Key); switch (type) { case 0x1A: ExtractLogic.Skin.FindTextures(texture_pair.Value, layers, replace, new HashSet <ulong>(), map, handler); if (replace_blank.ContainsKey(texture_pair.Key)) { ExtractLogic.Skin.FindTextures(replace_blank[texture_pair.Key], layers_orig, replace_blank, new HashSet <ulong>(), map, handler); } else { ExtractLogic.Skin.FindTextures(texture_pair.Key, layers_orig, replace_blank, new HashSet <ulong>(), map, handler); } break; } } Dictionary <ulong, HashSet <ulong> > origTextures = new Dictionary <ulong, HashSet <ulong> >(); foreach (KeyValuePair <ulong, List <ImageLayer> > kv in layers_orig) { ulong materialId = kv.Key; List <ImageLayer> sublayers = kv.Value; HashSet <ulong> materialParsed = new HashSet <ulong>(); if (!origTextures.ContainsKey(materialId)) { origTextures[materialId] = new HashSet <ulong>(); } foreach (ImageLayer layer in sublayers) { origTextures[materialId].Add(layer.key); } } foreach (KeyValuePair <ulong, List <ImageLayer> > kv in layers) { ulong materialId = kv.Key; List <ImageLayer> sublayers = kv.Value; HashSet <ulong> materialParsed = new HashSet <ulong>(); foreach (ImageLayer layer in sublayers) { if (!materialParsed.Add(layer.key)) { continue; } if (origTextures.ContainsKey(materialId) && origTextures[materialId].Contains(layer.key)) { continue; } ExtractLogic.Skin.SaveTexture(layer.key, materialId, map, handler, output_real, quiet, ""); } } } } } } }
public void Parse(Dictionary <ushort, List <ulong> > track, Dictionary <ulong, Record> map, CASCHandler handler, bool quiet, OverToolFlags flags) { Dictionary <string, Dictionary <string, Dictionary <string, Dictionary <string, List <JSONPkg> > > > > dict_upper = new Dictionary <string, Dictionary <string, Dictionary <string, Dictionary <string, List <JSONPkg> > > > >(); foreach (ulong key in track[0x75]) { if (!map.ContainsKey(key)) { continue; } using (Stream input = Util.OpenFile(map[key], handler)) { if (input == null) { continue; } STUD stud = new STUD(input); if (stud.Instances == null || stud.Instances[0] == null) { continue; } HeroMaster hero = stud.Instances[0] as HeroMaster; if (hero == null) { continue; } Dictionary <string, Dictionary <string, Dictionary <string, List <JSONPkg> > > > dict = new Dictionary <string, Dictionary <string, Dictionary <string, List <JSONPkg> > > >(); string heroName = Util.GetString(hero.Header.name.key, map, handler); if (heroName == null) { continue; } if (hero.Header.itemMaster.key == 0) // AI { continue; } if (!map.ContainsKey(hero.Header.itemMaster.key)) { continue; } STUD inventoryStud = new STUD(Util.OpenFile(map[hero.Header.itemMaster.key], handler)); InventoryMaster master = (InventoryMaster)inventoryStud.Instances[0]; if (master == null) { continue; } if (!dict.ContainsKey("ACHIEVEMENT")) { dict["ACHIEVEMENT"] = new Dictionary <string, Dictionary <string, List <JSONPkg> > >(); } if (!dict.ContainsKey("STANDARD")) { dict["STANDARD"] = new Dictionary <string, Dictionary <string, List <JSONPkg> > >(); } if (!dict.ContainsKey("AVAILABLE")) { dict["AVAILABLE"] = new Dictionary <string, Dictionary <string, List <JSONPkg> > >(); } string s = ItemEvents.GetInstance().GetEvent(0); if (!dict["ACHIEVEMENT"].ContainsKey(s)) { dict["ACHIEVEMENT"][s] = new Dictionary <string, List <JSONPkg> >(); } for (int i = 0; i < master.Achievables.Length; ++i) { JSONPkg pkg = JSONGeneral.GenerateJSONPkg(master.Achievables[i], map, handler); if (pkg.Name == null) { continue; } pkg.EventId = 0; pkg.Event = s; if (!dict["ACHIEVEMENT"][s].ContainsKey(pkg.Type)) { dict["ACHIEVEMENT"][s][pkg.Type] = new List <JSONPkg>(); } dict["ACHIEVEMENT"][s][pkg.Type].Add(pkg); } for (int i = 0; i < master.DefaultGroups.Length; ++i) { if (master.Defaults[i].Length == 0) { continue; } s = ItemEvents.GetInstance().GetEvent(master.DefaultGroups[i].@event); if (!dict["STANDARD"].ContainsKey(s)) { dict["STANDARD"][s] = new Dictionary <string, List <JSONPkg> >(); } for (int j = 0; j < master.Defaults[i].Length; ++j) { JSONPkg pkg = GenerateJSONPkg(master.Defaults[i][j].key, map, handler); if (pkg.Name == null) { continue; } pkg.EventId = master.DefaultGroups[i].@event; pkg.Event = s; if (!dict["STANDARD"][s].ContainsKey(pkg.Type)) { dict["STANDARD"][s][pkg.Type] = new List <JSONPkg>(); } dict["STANDARD"][s][pkg.Type].Add(pkg); } } for (int i = 0; i < master.ItemGroups.Length; ++i) { if (master.Items[i].Length == 0) { continue; } s = ItemEvents.GetInstance().GetEvent(master.ItemGroups[i].@event); if (!dict["AVAILABLE"].ContainsKey(s)) { dict["AVAILABLE"][s] = new Dictionary <string, List <JSONPkg> >(); } for (int j = 0; j < master.Items[i].Length; ++j) { JSONPkg pkg = GenerateJSONPkg(master.Items[i][j].key, map, handler); if (pkg.Name == null) { continue; } pkg.EventId = master.ItemGroups[i].@event; pkg.Event = s; if (!dict["AVAILABLE"][s].ContainsKey(pkg.Type)) { dict["AVAILABLE"][s][pkg.Type] = new List <JSONPkg>(); } dict["AVAILABLE"][s][pkg.Type].Add(pkg); } } dict_upper[heroName] = dict; } } if (Path.GetDirectoryName(flags.Positionals[2]).Trim().Length > 0 && !Directory.Exists(Path.GetDirectoryName(flags.Positionals[2]))) { Directory.CreateDirectory(Path.GetDirectoryName(flags.Positionals[2])); } using (Stream file = File.OpenWrite(flags.Positionals[2])) { using (TextWriter writer = new StreamWriter(file)) { writer.Write(JsonConvert.SerializeObject(dict_upper, Formatting.Indented)); } } }