Пример #1
0
        private static bool SaveSet(ICLIFlags flags, string basePath, ulong entityMain, string heroFileName, string skin, ref STUVoiceSetComponent voiceSetComponent, ref Combo.ComboInfo info, STUVoiceSetComponent baseComponent = null, Combo.ComboInfo baseCombo = null, Dictionary <ulong, ulong> replacements = null)
        {
            voiceSetComponent = GetInstance <STUVoiceSetComponent>(Combo.GetReplacement(entityMain, replacements));

            if (voiceSetComponent?.m_voiceDefinition == null)
            {
                Debugger.Log(0, "DataTool.SaveLogic.Unlock.VoiceLine", "[DataTool.SaveLogic.Unlock.VoiceLine]: VoiceSet not found");
                return(false);
            }

            info = new Combo.ComboInfo();
            Combo.Find(info, Combo.GetReplacement(voiceSetComponent.m_voiceDefinition, replacements), replacements);
            if (baseComponent != null && baseCombo != null)
            {
                if (!Combo.RemoveDuplicateVoiceSetEntries(baseCombo, ref info, baseComponent.m_voiceDefinition, Combo.GetReplacement(voiceSetComponent.m_voiceDefinition, replacements)))
                {
                    return(false);
                }
            }

            Log($"\tSaving {skin}");

            var context = new SaveLogic.Combo.SaveContext(info);

            SaveLogic.Combo.SaveVoiceSet(flags, Path.Combine(basePath, Container, heroFileName, skin), context, Combo.GetReplacement(voiceSetComponent.m_voiceDefinition, replacements));
            context.Wait();

            return(true);
        }
Пример #2
0
        public void Parse(ICLIFlags toolFlags)
        {
            string basePath;

            if (toolFlags is ExtractFlags flags)
            {
                basePath = flags.OutputPath;
            }
            else
            {
                throw new Exception("no output path");
            }

            Combo.ComboInfo info = new Combo.ComboInfo();

            foreach (ulong key in TrackedFiles[0x4])
            {
                Combo.Find(info, key);
            }

            Log($"Preparing to save roughly {info.m_textures.Count()} textures.");
            Log($"This will take a long time and take up a lot of space.");
            var saveContext = new SaveLogic.Combo.SaveContext(info);

            SaveLogic.Combo.SaveLooseTextures(flags, Path.Combine(basePath, "004Dump"), saveContext);
            saveContext.Wait();
        }
Пример #3
0
        public static bool SaveSet(ICLIFlags flags, string basePath, ulong entityMain, string heroFileName, string skin, ref STUVoiceSetComponent soundSetComponentContainer, ref Combo.ComboInfo info, STUVoiceSetComponent baseComponent = null, Combo.ComboInfo baseCombo = null, Dictionary <ulong, ulong> replacements = null)
        {
            soundSetComponentContainer = GetInstance <STUVoiceSetComponent>(Combo.GetReplacement(entityMain, replacements));

            if (soundSetComponentContainer?.VoiceSet == null)
            {
                Debugger.Log(0, "DataTool.SaveLogic.Unlock.VoiceLine", "[DataTool.SaveLogic.Unlock.VoiceLine]: VoiceSet not found");
                return(false);
            }

            info = new Combo.ComboInfo();
            Combo.Find(info, Combo.GetReplacement(soundSetComponentContainer.VoiceSet, replacements), replacements);
            if (baseComponent != null && baseCombo != null)
            {
                if (!Combo.RemoveDuplicateVoiceSetEntries(baseCombo, ref info, baseComponent.VoiceSet, Combo.GetReplacement(soundSetComponentContainer.VoiceSet, replacements)))
                {
                    return(false);
                }
            }

            Log("Saving {0}", skin);

            SaveLogic.Combo.SaveVoiceSet(flags, Path.Combine(basePath, Container, heroFileName, skin), info, Combo.GetReplacement(soundSetComponentContainer.VoiceSet, replacements));

            return(true);
        }
Пример #4
0
        public void Parse(ICLIFlags toolFlags)
        {
            string basePath;

            if (toolFlags is ExtractFlags flags)
            {
                basePath = Path.Combine(flags.OutputPath, Container);
            }
            else
            {
                throw new Exception("no output path");
            }

            foreach (var guid in Program.TrackedFiles[0x5F])
            {
                var voiceSet = GetInstance <STUVoiceSet>(guid);
                if (voiceSet == null)
                {
                    continue;
                }

                var npcName = GetValidFilename(GetString(voiceSet.m_269FC4E9));
                if (npcName == null)
                {
                    continue;
                }

                Logger.Log($"Processing NPC {npcName}");
                var info         = new Combo.ComboInfo();
                var ignoreGroups = !WhitelistedNPCs.Contains(npcName);
                ExtractHeroVoiceBetter.SaveVoiceSet(flags, basePath, npcName, guid, ref info, ignoreGroups: ignoreGroups);
            }
        }
Пример #5
0
        public void ExtractNewEntities(ICLIFlags toolFlags)
        {
            string basePath;

            if (toolFlags is ExtractFlags flags)
            {
                basePath = flags.OutputPath;
            }
            else
            {
                throw new Exception("no output path");
            }

            const string ver = "60993";
            //var contentHashes = GetContentHashes($@"D:\ow\resources\verdata\{ver}.cmfhashes");
            var guids = GetGUIDs($@"D:\ow\resources\verdata\{ver}.guids");

            const string container = "DebugNewEntities2";

            Combo.ComboInfo info = new Combo.ComboInfo();
            AddNewByGUID(info, guids, 0x4, 0x7C, 0x3F, 0xB2);

            SaveLogic.Combo.Save(flags, Path.Combine(basePath, container), info);
            SaveLogic.Combo.SaveAllSoundFiles(flags, Path.Combine(basePath, container, "Sounds"), info);
            SaveLogic.Combo.SaveAllVoiceSoundFiles(flags, Path.Combine(basePath, container, "VoiceSounds"), info);
            SaveLogic.Combo.SaveLooseTextures(flags, Path.Combine(basePath, container, "LooseTex"), info);
            SaveLogic.Combo.SaveAllStrings(flags, Path.Combine(basePath, container, "Strings"), info);
        }
Пример #6
0
        public void GetSubtitles()
        {
            Combo.ComboInfo comboInfo = new Combo.ComboInfo();

            HashSet <KeyValuePair <ulong, ulong> > done = new HashSet <KeyValuePair <ulong, ulong> >();

            foreach (ulong key in TrackedFiles[0x5F])
            {
                Combo.Find(comboInfo, key);
                if (!comboInfo.VoiceSets.ContainsKey(key))
                {
                    continue;
                }

                Combo.VoiceSetInfo voiceSetInfo = comboInfo.VoiceSets[key];
                if (voiceSetInfo.VoiceLineInstances == null)
                {
                    continue;
                }
                foreach (KeyValuePair <ulong, HashSet <Combo.VoiceLineInstanceInfo> > lineInstance in voiceSetInfo.VoiceLineInstances)
                {
                    foreach (Combo.VoiceLineInstanceInfo lineInstanceInfo in lineInstance.Value)
                    {
                        if (lineInstanceInfo.Subtitle != 0)
                        {
                            foreach (ulong soundInfoSound in lineInstanceInfo.SoundFiles)
                            {
                                PrintSubtitle(done, key, soundInfoSound, lineInstanceInfo.Subtitle);
                            }
                        }
                    }
                }
            }
        }
Пример #7
0
        public void Parse(ICLIFlags toolFlags)
        {
            string basePath;

            if (toolFlags is ExtractFlags flags)
            {
                basePath = Path.Combine(flags.OutputPath, Container);
            }
            else
            {
                throw new Exception("no output path");
            }

            // Do normal heroes first then NPCs, this is because NPCs have a lot of duplicate sounds and normal heroes (should) have none
            // so any duplicate sounds would only come up while processing NPCs which can be ignored as they (probably) belong to heroes
            var heroes = Program.TrackedFiles[0x75]
                         .Select(x => new Hero(x))
                         .OrderBy(x => !x.IsHero)
                         .ThenBy(x => x.GUID.GUID)
                         .ToArray();

            foreach (var hero in heroes)
            {
                var heroStu = GetInstance <STUHero>(hero.GUID);

                string heroName = GetValidFilename((GetString(heroStu.m_0EDCE350) ?? $"Unknown{teResourceGUID.Index(hero.GUID)}").TrimEnd(' '));
                Logger.Log($"Processing {heroName}");

                Combo.ComboInfo baseInfo         = default;
                var             heroVoiceSetGuid = GetInstance <STUVoiceSetComponent>(heroStu.m_gameplayEntity)?.m_voiceDefinition;

                if (SaveVoiceSet(flags, basePath, heroName, heroVoiceSetGuid, ref baseInfo))
                {
                    var skins = new ProgressionUnlocks(heroStu).GetUnlocksOfType(UnlockType.Skin);
                    foreach (var unlock in skins)
                    {
                        TACTLib.Logger.Debug("Tool", $"Processing skin {unlock.Name}");
                        if (!(unlock.STU is STUUnlock_SkinTheme unlockSkinTheme))
                        {
                            return;
                        }
                        if (unlockSkinTheme.m_0B1BA7C1 != 0)
                        {
                            continue;
                        }

                        Combo.ComboInfo info      = default;
                        var             skinTheme = GetInstance <STUSkinTheme>(unlockSkinTheme.m_skinTheme);
                        if (skinTheme == null)
                        {
                            continue;
                        }

                        SaveVoiceSet(flags, basePath, heroName, heroVoiceSetGuid, ref info, baseInfo, SkinTheme.GetReplacements(skinTheme));
                    }
                }
            }
        }
Пример #8
0
        public void ExtractHeroes(ICLIFlags toolFlags)
        {
            string basePath;

            if (toolFlags is ExtractFlags flags)
            {
                basePath = flags.OutputPath;
            }
            else
            {
                throw new Exception("no output path");
            }

            const string container = "DebugCombo";

            foreach (ulong key in TrackedFiles[0x75])
            {
                // if (GUID.Index(key) != 0xDEADBEEF) continue;

                STUHero hero     = GetInstance <STUHero>(key);
                string  heroName = GetString(hero.Name);

                if (heroName != "Tracer")
                {
                    continue;
                }

                Stopwatch       stopwatch = Stopwatch.StartNew();
                Combo.ComboInfo info      = new Combo.ComboInfo();
                Combo.Find(info, hero.EntityHeroSelect);
                Combo.Find(info, hero.EntityHighlightIntro);
                Combo.Find(info, hero.EntityMain);
                Combo.Find(info, hero.EntityPlayable);
                Combo.Find(info, hero.EntityThirdPerson);
                info.SetEntityName(hero.EntityHeroSelect, $"{heroName}-HeroSelect");
                info.SetEntityName(hero.EntityHighlightIntro, $"{heroName}-HighlightIntro");
                info.SetEntityName(hero.EntityMain, $"{heroName}-Main");
                info.SetEntityName(hero.EntityPlayable, $"{heroName}-Playable");
                info.SetEntityName(hero.EntityThirdPerson, $"{heroName}-Thirdperson");
                stopwatch.Stop();
                long newTime = stopwatch.ElapsedMilliseconds;

                SaveLogic.Combo.Save(flags, Path.Combine(basePath, heroName), info);

                // stopwatch.Reset();
                // stopwatch.Start();
                //
                // HashSet<ModelInfo> models = new HashSet<ModelInfo>();
                // Model.FindModels(models, hero.EntityHeroSelect);
                // Model.FindModels(models, hero.EntityHighlightIntro);
                // Model.FindModels(models, hero.EntityMain);
                // Model.FindModels(models, hero.EntityPlayable);
                // Model.FindModels(models, hero.EntityThirdPerson);
                // stopwatch.Stop();
                // long oldTime = stopwatch.ElapsedMilliseconds;
            }
        }
Пример #9
0
 public void AddNewByGUID(Combo.ComboInfo info, HashSet <ulong> lastVerGuids, ushort type)
 {
     foreach (ulong key in TrackedFiles[type])
     {
         if (lastVerGuids.Contains(key))
         {
             continue;
         }
         Combo.Find(info, key);
     }
 }
Пример #10
0
 public void AddNew(Combo.ComboInfo info, List <ulong> all, ushort type)
 {
     foreach (ulong key in TrackedFiles[type])
     {
         if (all.Contains(key))
         {
             continue;
         }
         Combo.Find(info, key);
     }
 }
Пример #11
0
 public void AddAdded(Combo.ComboInfo info, List <string> added, ushort type)
 {
     foreach (ulong key in TrackedFiles[type])
     {
         string name = GetFileName(key);
         if (!added.Contains(name))
         {
             continue;
         }
         Combo.Find(info, key);
     }
 }
Пример #12
0
        public void ExtractMapImages(ICLIFlags toolFlags)
        {
            string basePath;

            if (toolFlags is ExtractFlags flags)
            {
                basePath = flags.OutputPath;
            }
            else
            {
                throw new Exception("no output path");
            }
            //flags.ConvertTexturesType = "dds";

            const string container = "DebugMapImages";

            foreach (ulong key in TrackedFiles[0x2])
            {
                string          dir  = Path.Combine(basePath, container, GetFileName(key));
                Combo.ComboInfo info = new Combo.ComboInfo();

                using (Stream stream = OpenFile(key)) {
                    using (Stream file = File.OpenWrite(Path.Combine(dir, "data.002"))) {
                        stream.CopyTo(file);
                        stream.Position = 0;
                    }
                    using (BinaryReader reader = new BinaryReader(stream)) {
                        Map map = reader.Read <Map>();

                        Combo.Find(info, map.Texture);
                        info.SetTextureName(map.Texture, nameof(Map.Texture));

                        Combo.Find(info, map.TextureB);
                        info.SetTextureName(map.TextureB, nameof(Map.TextureB));

                        Combo.Find(info, map.TextureC);
                        info.SetTextureName(map.TextureC, nameof(Map.TextureC));

                        Combo.Find(info, map.TextureD);
                        info.SetTextureName(map.TextureD, nameof(Map.TextureD));

                        Combo.Find(info, map.TextureE);
                        info.SetTextureName(map.TextureE, nameof(Map.TextureE));

                        Combo.Find(info, map.TextureF);
                        info.SetTextureName(map.TextureF, nameof(Map.TextureF));
                    }

                    SaveLogic.Combo.SaveLooseTextures(flags, dir, info);
                }
            }
        }
Пример #13
0
        public void SaveTextureDef(ICLIFlags flags, string path, ulong texDef, ImageDefinition imageDefinition)
        {
            string thePath = Path.Combine(path, GetFileName(texDef));

            CreateDirectoryFromFile(thePath + "\\poo");

            Combo.ComboInfo info = new Combo.ComboInfo();
            foreach (ImageLayer layer in imageDefinition.Layers)
            {
                Combo.Find(info, layer.Key);
            }
            SaveLogic.Combo.SaveLooseTextures(flags, thePath, info);
        }
Пример #14
0
        public void GetLootboxes(ICLIFlags toolFlags)
        {
            string basePath;

            if (toolFlags is ExtractFlags flags)
            {
                basePath = flags.OutputPath;
            }
            else
            {
                throw new Exception("no output path");
            }


            foreach (ulong key in TrackedFiles[0xCF])
            {
                STULootBox lootbox = GetInstance <STULootBox>(key);
                if (lootbox == null)
                {
                    continue;
                }

                string name = LootBox.GetName(lootbox.m_lootboxType);

                Combo.ComboInfo info = Combo.Find(null, lootbox.m_baseEntity); // 003
                Combo.Find(info, lootbox.m_chestEntity);                       // 003
                Combo.Find(info, lootbox.m_idleEffect);                        // 00D
                Combo.Find(info, lootbox.m_FEC3ED62);                          // 00D
                Combo.Find(info, lootbox.m_FFE7768F);                          // 00D
                Combo.Find(info, lootbox.m_baseModelLook);                     // 01A
                Combo.Find(info, lootbox.m_modelLook);

                Combo.Find(info, 0x400000000001456); // coin chest, todo
                // 00000000315A.00C in 000000001456.003 (288230376151716950)

                if (lootbox.m_shopCards != null)
                {
                    foreach (STULootBoxShopCard lootboxShopCard in lootbox.m_shopCards)
                    {
                        Combo.Find(info, lootboxShopCard.m_cardTexture); // 004
                    }
                }

                var context = new SaveLogic.Combo.SaveContext(info);
                SaveLogic.Combo.SaveLooseTextures(flags, Path.Combine(basePath, Container, name, "ShopCards"), context);
                SaveLogic.Combo.Save(flags, Path.Combine(basePath, Container, name), context);
                context.Wait();
                SaveScratchDatabase();
            }
        }
Пример #15
0
        public void ExtractNewEntities(ICLIFlags toolFlags)
        {
            string basePath;

            if (toolFlags is ExtractFlags flags)
            {
                basePath = flags.OutputPath;
            }
            else
            {
                throw new Exception("no output path");
            }

            if (flags.Positionals.Length != 4)
            {
                throw new Exception("incorrect params provided");
            }

            var          file      = flags.Positionals[3];
            const string container = "DebugNewEntities2";

            Combo.ComboInfo info  = new Combo.ComboInfo();
            var             types = new ushort[] { 0x4, 0x7C, 0x3F, 0xB2 };

            if (file.EndsWith("guids"))
            {
                var guids = GetGUIDs(file);
                AddNewByGUID(info, guids, types);
            }
            else if (file.EndsWith("cmfhashes"))
            {
                // does this even still work?
                var contentHashes = GetContentHashes(file);
                AddNewByContentHash(info, contentHashes, types);
            }
            else
            {
                throw new Exception("unknown file type");
            }

            var context = new SaveLogic.Combo.SaveContext(info);

            SaveLogic.Combo.Save(flags, Path.Combine(basePath, container), context);
            SaveLogic.Combo.SaveAllSoundFiles(flags, Path.Combine(basePath, container, "Sounds"), context);
            SaveLogic.Combo.SaveAllVoiceSoundFiles(flags, Path.Combine(basePath, container, "VoiceSounds"), context);
            SaveLogic.Combo.SaveLooseTextures(flags, Path.Combine(basePath, container, "LooseTex"), context);
            SaveLogic.Combo.SaveAllStrings(flags, Path.Combine(basePath, container, "Strings"), info);
            context.Wait();
        }
Пример #16
0
        public static void SaveSkin(ICLIFlags flags, ulong skinResource, string basePath, STUHero hero, string heroFileName, string name, STUVoiceSetComponent baseComponent, Combo.ComboInfo baseInfo)
        {
            STUSkinTheme skin = GetInstance <STUSkinTheme>(skinResource);

            if (skin == null)
            {
                return;
            }

            STUVoiceSetComponent component = default;

            Combo.ComboInfo info = default;

            SaveSet(flags, basePath, hero.m_gameplayEntity, heroFileName, GetValidFilename(name), ref component,
                    ref info, baseComponent, baseInfo, SkinTheme.GetReplacements(skin));
        }
Пример #17
0
        public void Extract0EE(ICLIFlags toolFlags)
        {
            string basePath;

            if (toolFlags is ExtractFlags flags)
            {
                basePath = flags.OutputPath;
            }
            else
            {
                throw new Exception("no output path");
            }

            const string container = "Debug0EE";
            string       path      = Path.Combine(basePath, container);

            foreach (ulong key in TrackedFiles[0xEE])
            {
                using (Stream stream = OpenFile(key)) {
                    teStructuredData structuredData = new teStructuredData(stream);

                    STU_E3594B8E inst = structuredData.GetMainInstance <STU_E3594B8E>();

                    if (inst == null)
                    {
                        continue;
                        //inst = structuredData.GetMainInstance<STU_598579A3>();
                    }

                    string name        = $"{GetString(inst.m_name)}_{teResourceGUID.Index(key):X}";
                    string description = GetString(inst.m_description);

                    Combo.ComboInfo info = new Combo.ComboInfo();
                    Combo.Find(info, (ulong)inst.m_21EB3E73);
                    info.SetTextureName((ulong)inst.m_21EB3E73, name);

                    OpenSTUTest(inst.m_7B7CCF55);  // ux1
                    OpenSTUTest(inst.m_E81C5302);  // ux2
                    OpenSTUTest(inst.m_FD9B53F4);  // ux3
                    //{
                    //    teStructuredData uxScreenData = new teStructuredData();
                    //}

                    SaveLogic.Combo.SaveLooseTextures(flags, path, info);
                }
            }
        }
Пример #18
0
        public void ExtractNewEntities(ICLIFlags toolFlags)
        {
            string basePath;

            // sorry if this isn't useful for anyone but me.
            // data.json has a list under the key "added_raw" that contains all of the added files.

            //const string dataPath = "D:\\ow\\OverwatchDataManager\\versions\\1.18.1.2.42076\\data.json";
            const string dataPath = "D:\\ow\\OverwatchDataManager\\versions\\1.20.0.2.43435\\data.json";

            List <string> added = GetAddedFiles(dataPath);

            if (toolFlags is ExtractFlags flags)
            {
                basePath = flags.OutputPath;
            }
            else
            {
                throw new Exception("no output path");
            }

            const string container = "DebugNewEntities";

            Combo.ComboInfo info = new Combo.ComboInfo();

            Combo.Find(info, 288230376151717278);  // 00000000159E.003

            //Combo.Find(info, 0x40000000000146C);  // 00000000146C.003
            //Combo.Find(info, 288230376151716993);  // 000000001481.003
            //Combo.Find(info, 288230376151716994);  // 000000001482.003
            //Combo.Find(info, 288230376151716950);  // 000000001456.003
            //Combo.Find(info, 288230376151716972);  // 00000000146C.003
            //Combo.Find(info, 288230376151716953);  // 000000001459.003
            //Combo.Find(info, 288230376151716948);  // 000000001454.003
            //Combo.Find(info, 288230376151716949);  // 000000001455.003
            //foreach (ulong key in TrackedFiles[0x3]) {
            //    string name = GetFileName(key);
            //    if (!added.Contains(name)) continue;
            //    Combo.Find(info, key);
            //}

            AddAdded(info, added, 0x8F);
            AddAdded(info, added, 0x8E);

            SaveLogic.Combo.Save(flags, Path.Combine(basePath, container), info);
        }
Пример #19
0
        public static void SaveSkin(ICLIFlags flags, ulong skinResource, string basePath, STUHero hero, string heroFileName, string name, STUVoiceSetComponent baseComponent, Combo.ComboInfo baseInfo)
        {
            STUSkinOverride skin = GetInstance <STUSkinOverride>(skinResource);

            if (skin == null)
            {
                return;
            }

            STUVoiceSetComponent component = default(STUVoiceSetComponent);

            Combo.ComboInfo info = default(Combo.ComboInfo);

            if (SaveSet(flags, basePath, hero.EntityMain, heroFileName, GetValidFilename(name), ref component, ref info, baseComponent, baseInfo, skin.ProperReplacements))
            {
                return;
            }
        }
Пример #20
0
        public void GetLootboxes(ICLIFlags toolFlags)
        {
            string basePath;

            if (toolFlags is ExtractFlags flags)
            {
                basePath = flags.OutputPath;
            }
            else
            {
                throw new Exception("no output path");
            }


            foreach (ulong key in TrackedFiles[0xCF])
            {
                STULootbox lootbox = GetInstance <STULootbox>(key);
                if (lootbox == null)
                {
                    continue;
                }

                string name = GetValidFilename(lootbox.Event.ToString()) ?? $"Unknown{GUID.Index(key):X}";

                Combo.ComboInfo info = Combo.Find(null, lootbox.Entity);
                Combo.Find(info, lootbox.Entity2);
                Combo.Find(info, lootbox.Effect1);
                Combo.Find(info, lootbox.Effect2);
                Combo.Find(info, lootbox.Effect3);
                Combo.Find(info, lootbox.ModelLook);
                Combo.Find(info, lootbox.Look2);

                Combo.Find(info, 288230376151716950);  // coin chest, todo
                // 00000000315A.00C in 000000001456.003 (288230376151716950)

                foreach (STULootBoxShopCard lootboxShopCard in lootbox.ShopCards)
                {
                    Combo.Find(info, lootboxShopCard.Texture);
                }
                SaveLogic.Combo.SaveLooseTextures(flags, Path.Combine(basePath, Container, name, "ShopCards"), info);
                SaveLogic.Combo.Save(flags, Path.Combine(basePath, Container, name), info);
            }
        }
Пример #21
0
        public void ExtractVoiceSets(ICLIFlags toolFlags)
        {
            string basePath;

            if (toolFlags is ExtractFlags flags)
            {
                basePath = flags.OutputPath;
            }
            else
            {
                throw new Exception("no output path");
            }

            const string container = "DebugVoiceSet";

            foreach (ulong key in TrackedFiles[0x5F])
            {
                if (teResourceGUID.Index(key) != 0x19F)
                {
                    continue;
                }

                string voiceMaterDir = Path.Combine(basePath, container, GetFileName(key));

                Combo.ComboInfo info    = new Combo.ComboInfo();
                var             context = new SaveLogic.Combo.SaveContext(info);
                Combo.Find(info, key);
                SaveLogic.Combo.SaveVoiceSet(flags, voiceMaterDir, context, key);
                context.Wait();

                // foreach (STUVoiceLineInstance voiceLineInstance in voiceSet.VoiceLineInstances) {
                //     if (voiceLineInstance?.SoundDataContainer == null) continue;
                //
                //     Combo.ComboInfo info = new Combo.ComboInfo();
                //
                //     Combo.Find(info, voiceLineInstance.SoundDataContainer.SoundbankMasterResource);
                //
                //     foreach (ulong soundInfoNew in info.Sounds.Keys) {
                //         SaveLogic.Combo.SaveSound(flags, voiceMaterDir, info, soundInfoNew);
                //     }
                // }
            }
        }
Пример #22
0
        public static void SaveAbilities(ICLIFlags toolFlags)
        {
            string basePath;

            if (toolFlags is ExtractFlags flags)
            {
                basePath = flags.OutputPath;
            }
            else
            {
                throw new Exception("no output path");
            }

            const string folderName = "Abilities";

            foreach (ulong key in TrackedFiles[0x9E])
            {
                STULoadout loadout = GetInstance <STULoadout>(key);
                if (loadout == null)
                {
                    continue;
                }

                string name = GetValidFilename(GetString(loadout.m_name)?.TrimEnd().Replace(".", "_")) ?? $"Unknown{teResourceGUID.Index(key):X}";

                Combo.ComboInfo info = new Combo.ComboInfo();
                Combo.Find(info, loadout.m_texture);

                var context = new SaveLogic.Combo.SaveContext(info);
                SaveLogic.Combo.SaveLooseTextures(flags, Path.Combine(basePath, folderName, name), context);
                context.Wait();

                using (Stream videoStream = OpenFile(loadout.m_infoMovie)) {
                    if (videoStream != null)
                    {
                        videoStream.Position = 128; // wrapped in "MOVI" for some reason
                        WriteFile(videoStream, Path.Combine(basePath, folderName, name, $"{teResourceGUID.LongKey(loadout.m_infoMovie):X12}.bk2"));
                    }
                }
            }
        }
Пример #23
0
        public void ExtractVoiceSets(ICLIFlags toolFlags)
        {
            string basePath;

            if (toolFlags is ExtractFlags flags)
            {
                basePath = flags.OutputPath;
            }
            else
            {
                throw new Exception("no output path");
            }

            const string container = "DebugVoiceSet";

            foreach (ulong key in TrackedFiles[0x5F])
            {
                STUVoiceSet voiceSet = GetInstance <STUVoiceSet>(key);

                string voiceMaterDir = Path.Combine(basePath, container, GetFileName(key));

                foreach (STUVoiceLineInstance voiceLineInstance in voiceSet.VoiceLineInstances)
                {
                    if (voiceLineInstance?.SoundDataContainer == null)
                    {
                        continue;
                    }

                    Combo.ComboInfo info = new Combo.ComboInfo();

                    Combo.Find(info, voiceLineInstance.SoundDataContainer.SoundbankMasterResource);

                    foreach (ulong soundInfoNew in info.Sounds.Keys)
                    {
                        SaveLogic.Combo.SaveSound(flags, voiceMaterDir, info, soundInfoNew);
                    }
                }
            }
        }
Пример #24
0
        public void Parse(ICLIFlags toolFlags)
        {
            string basePath;

            if (toolFlags is ExtractFlags flags)
            {
                basePath = flags.OutputPath;
            }
            else
            {
                throw new Exception("no output path");
            }

            const string container = "GamemodeImages";
            string       path      = Path.Combine(basePath, container);

            foreach (ulong key in TrackedFiles[0xEE])
            {
                var stuE3594B8E = Helper.STUHelper.GetInstance <STU_E3594B8E>(key);

                if (stuE3594B8E == null)
                {
                    continue;
                }

                string name = $"{teResourceGUID.Index(key):X3}_{GetString(stuE3594B8E.m_name)}";

                Combo.ComboInfo info = new Combo.ComboInfo();
                Combo.Find(info, (ulong)stuE3594B8E.m_21EB3E73);
                info.SetTextureName((ulong)stuE3594B8E.m_21EB3E73, name);

                var context = new SaveLogic.Combo.SaveContext(info);
                SaveLogic.Combo.SaveLooseTextures(flags, path, context);
                context.Wait();
            }
        }
Пример #25
0
        public void ExtractNewEntities(ICLIFlags toolFlags)
        {
            string basePath;

            // sorry if this isn't useful for anyone but me.
            // data.json has a list under the key "added_raw" that contains all of the added files.

            //const string dataPath = "D:\\ow\\OverwatchDataManager\\versions\\1.18.1.2.42076\\data.json";
            //const string dataPath = "D:\\ow\\OverwatchDataManager\\versions\\1.20.0.2.43435\\data.json";
            //const string dataPath = "D:\\ow\\OverwatchDataManager\\versions\\1.17.0.3.41713\\data.json";

            //VersionInfo versionInfo = GetVersionInfo(dataPath);
            //VersionInfo versionInfo = GetVersionInfoFake(@"D:\Code\Repos\overtool\OWLib-main\CASCEncDump\bin\Debug\44916.cmfhashes");
            VersionInfo versionInfo = GetVersionInfoFake(@"D:\ow\resources\verdata\49154.cmfhashes");

            if (toolFlags is ExtractFlags flags)
            {
                basePath = flags.OutputPath;
            }
            else
            {
                throw new Exception("no output path");
            }

            const string container = "DebugNewEntities3";

            Combo.ComboInfo info = new Combo.ComboInfo();
            //AddNewHash(info, versionInfo, 0x7C);
            AddNewHash(info, versionInfo, 0x4);

            SaveLogic.Combo.Save(flags, Path.Combine(basePath, container), info);
            SaveLogic.Combo.SaveAllSoundFiles(flags, Path.Combine(basePath, container, "Sounds"), info);
            SaveLogic.Combo.SaveAllVoiceSoundFiles(flags, Path.Combine(basePath, container, "VoiceSounds"), info);
            SaveLogic.Combo.SaveLooseTextures(flags, Path.Combine(basePath, container, "LooseTex"), info);
            SaveLogic.Combo.SaveAllStrings(flags, Path.Combine(basePath, container, "Strings"), info);
        }
Пример #26
0
        public void SaveUnlocksForHeroes(ICLIFlags flags, IEnumerable <STUHero> heroes, string basePath, bool npc = false)
        {
            if (flags.Positionals.Length < 4)
            {
                QueryHelp(QueryTypes);
                return;
            }

            Dictionary <string, Dictionary <string, ParsedArg> > parsedTypes = ParseQuery(flags, QueryTypes, QueryNameOverrides);

            if (parsedTypes == null)
            {
                return;
            }

            foreach (STUHero hero in heroes)
            {
                if (hero == null)
                {
                    continue;
                }
                string heroNameActual = GetString(hero.m_0EDCE350);

                if (heroNameActual == null)
                {
                    continue;
                }

                Dictionary <string, ParsedArg> config = GetQuery(parsedTypes, heroNameActual.ToLowerInvariant(), "*");

                heroNameActual = heroNameActual.TrimEnd(' ');
                string heroFileName = GetValidFilename(heroNameActual);

                if (config.Count == 0)
                {
                    continue;
                }

                string heroPath = Path.Combine(basePath, RootDir, heroFileName);

                VoiceSet           voiceSet           = new VoiceSet(hero);
                ProgressionUnlocks progressionUnlocks = new ProgressionUnlocks(hero);
                if (progressionUnlocks.LevelUnlocks == null && !npc)
                {
                    continue;
                }
                if (progressionUnlocks.LootBoxesUnlocks != null && npc)
                {
                    continue;
                }

                Log($"Processing unlocks for {heroNameActual}");

                {
                    Combo.ComboInfo guiInfo = new Combo.ComboInfo();

                    foreach (STU_1A496D3C tex in hero.m_8203BFE1)
                    {
                        Combo.Find(guiInfo, tex.m_texture);
                        guiInfo.SetTextureName(tex.m_texture, teResourceGUID.AsString(tex.m_id));
                    }

                    SaveLogic.Combo.SaveLooseTextures(flags, Path.Combine(heroPath, "GUI"), guiInfo);
                }

                if (progressionUnlocks.OtherUnlocks != null)   // achievements and stuff
                {
                    Dictionary <string, TagExpectedValue> tags = new Dictionary <string, TagExpectedValue> {
                        { "event", new TagExpectedValue("base") }
                    };
                    SaveUnlocks(flags, progressionUnlocks.OtherUnlocks, heroPath, "Achievement", config, tags, voiceSet, hero);
                }

                if (npc)
                {
                    foreach (var skin in hero.m_skinThemes)
                    {
                        if (!config.ContainsKey("skin") || !config["skin"].ShouldDo(GetFileName(skin.m_5E9665E3)))
                        {
                            continue;
                        }
                        SkinTheme.Save(flags, Path.Combine(heroPath, Unlock.GetTypeName(typeof(STUUnlock_SkinTheme)),
                                                           string.Empty, GetFileName(skin.m_5E9665E3)), skin, hero);
                    }
                    continue;
                }

                if (progressionUnlocks.LevelUnlocks != null)   // default unlocks
                {
                    Dictionary <string, TagExpectedValue> tags = new Dictionary <string, TagExpectedValue> {
                        { "event", new TagExpectedValue("base") }
                    };
                    foreach (LevelUnlocks levelUnlocks in progressionUnlocks.LevelUnlocks)
                    {
                        SaveUnlocks(flags, levelUnlocks.Unlocks, heroPath, "Default", config, tags, voiceSet, hero);
                    }
                }

                if (progressionUnlocks.LootBoxesUnlocks != null)
                {
                    foreach (LootBoxUnlocks lootBoxUnlocks in progressionUnlocks.LootBoxesUnlocks)
                    {
                        if (lootBoxUnlocks.Unlocks == null)
                        {
                            continue;
                        }
                        string lootboxName = LootBox.GetName(lootBoxUnlocks.LootBoxType);

                        var tags = new Dictionary <string, TagExpectedValue> {
                            { "event", new TagExpectedValue(LootBox.GetBasicName(lootBoxUnlocks.LootBoxType)) }
                        };

                        SaveUnlocks(flags, lootBoxUnlocks.Unlocks, heroPath, lootboxName, config, tags, voiceSet, hero);
                    }
                }
            }
        }
Пример #27
0
        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);
            }
        }
Пример #28
0
        public void Parse(ICLIFlags toolFlags)
        {
            string basePath;

            if (toolFlags is BetterVoiceFlags flags)
            {
                basePath = flags.OutputPath;
            }
            else
            {
                throw new Exception("no output path");
            }

            foreach (var key in Program.TrackedFiles[0x75])
            {
                var hero        = GetInstance <STUHero>(key);
                var progression = new ProgressionUnlocks(hero);
                if (progression.LootBoxesUnlocks == null)
                {
                    continue;                                       // no NPCs thanks
                }
                string heroNameActual    = GetValidFilename((GetString(hero.m_0EDCE350) ?? $"Unknown{teResourceGUID.Index(key)}").TrimEnd(' '));
                var    voiceSetComponent = GetInstance <STUVoiceSetComponent>(hero.m_gameplayEntity);
                if (voiceSetComponent?.m_voiceDefinition == null)
                {
                    continue;
                }

                var voiceSetsCombo = new Combo.ComboInfo();
                Combo.Find(voiceSetsCombo, voiceSetComponent.m_voiceDefinition);

                foreach (var voiceSet in voiceSetsCombo.VoiceSets)
                {
                    if (voiceSet.Value.VoiceLineInstances == null)
                    {
                        continue;
                    }

                    foreach (var voicelineInstanceInfo in voiceSet.Value.VoiceLineInstances)
                    {
                        foreach (var voiceLineInstance in voicelineInstanceInfo.Value)
                        {
                            var soundFilesCombo = new Combo.ComboInfo();;
                            var stimulus        = GetInstance <STUVoiceStimulus>(voiceLineInstance.VoiceStimulus);

                            if (stimulus == null)
                            {
                                continue;
                            }

                            var groupName = GetVoiceGroup(voiceLineInstance.VoiceStimulus, stimulus.m_category, stimulus.m_87DCD58E) ?? "Unknown";

                            foreach (var soundFile in voiceLineInstance.SoundFiles)
                            {
                                Combo.Find(soundFilesCombo, soundFile);
                            }

                            var path = flags.GroupByHero && flags.GroupByType
                                ? Path.Combine(basePath, Container, heroNameActual, groupName)
                                : Path.Combine(basePath, Container, flags.GroupByHero ? Path.Combine(groupName, heroNameActual) : groupName);

                            foreach (var soundInfo in soundFilesCombo.VoiceSoundFiles.Values)
                            {
                                var filename = soundInfo.GetName();
                                if (!flags.GroupByHero)
                                {
                                    filename = $"{heroNameActual}-{soundInfo.GetName()}";
                                }

                                SaveLogic.Combo.SaveSoundFile(flags, path, soundFilesCombo, soundInfo.GUID, true, filename);
                            }
                        }
                    }
                }
            }
        }
Пример #29
0
        public void ExtractHeroConvos(ICLIFlags toolFlags)
        {
            string basePath;

            if (toolFlags is ExtractFlags flags)
            {
                basePath = flags.OutputPath;
            }
            else
            {
                throw new Exception("no output path");
            }

            if (flags.Positionals.Length < 4)
            {
                QueryHelp(QueryTypes);
                return;
            }

            string path = Path.Combine(basePath, Container);

            Dictionary <string, Dictionary <string, ParsedArg> > parsedTypes =
                ParseQuery(flags, QueryTypes, QueryNameOverrides);

            if (parsedTypes == null)
            {
                return;
            }

            Dictionary <ulong, VoiceSet> allVoiceSets = new Dictionary <ulong, VoiceSet>();

            foreach (var voiceSetGUID in Program.TrackedFiles[0x5F])
            {
                STUVoiceSet set = GetInstance <STUVoiceSet>(voiceSetGUID);

                if (set?.m_voiceLineInstances == null)
                {
                    continue;
                }
                allVoiceSets[voiceSetGUID] = new VoiceSet(set);
            }

            // Dictionary<uint, string> mapNames = new Dictionary<uint, string>();
            // foreach (ulong mapGuid in Program.TrackedFiles[0x9F]) {
            //     STUMapHeader mapHeader = GetInstance<STUMapHeader>(mapGuid);
            //     if (mapHeader == null) continue;
            //
            //     mapNames[teResourceGUID.Index(mapGuid)] = GetValidFilename(GetString(mapHeader.m_1C706502) ?? GetString(mapHeader.m_displayName));
            // }

            Combo.ComboInfo comboInfo = new Combo.ComboInfo();

            foreach (ulong heroGuid in Program.TrackedFiles[0x75])
            {
                STUHero hero = GetInstance <STUHero>(heroGuid);
                if (hero == null)
                {
                    continue;
                }
                STUVoiceSetComponent voiceSetComponent = GetInstance <STUVoiceSetComponent>(hero.m_gameplayEntity);

                if (voiceSetComponent?.m_voiceDefinition == null || !allVoiceSets.TryGetValue(voiceSetComponent.m_voiceDefinition, out var set))
                {
                    Debugger.Log(0, "DataTool.SaveLogic.Unlock.VoiceLine",
                                 "[DataTool.SaveLogic.Unlock.VoiceLine]: VoiceSet not found\r\n");
                    continue;
                }

                string heroNameActual =
                    (GetString(hero.m_0EDCE350) ?? $"Unknown{teResourceGUID.Index(heroGuid)}").TrimEnd(' ');

                Dictionary <string, ParsedArg> config = GetQuery(parsedTypes, heroNameActual.ToLowerInvariant(), "*");

                if (config.Count == 0)
                {
                    continue;
                }
                Log($"Processing data for {heroNameActual}");
                heroNameActual = GetValidFilename(heroNameActual);

                foreach (VoiceLineInstance lineInstance in set.VoiceLines.Values)
                {
                    // if (lineInstance.STU.m_voiceLineRuntime.m_4FF98D41 != null) {
                    //     var cond = lineInstance.STU.m_voiceLineRuntime.m_4FF98D41;
                    //
                    //     HandleCondition(flags, comboInfo, lineInstance, path, heroNameActual, cond, mapNames);
                    // }

                    if (lineInstance.VoiceConversation == 0)
                    {
                        continue;
                    }
                    STUVoiceConversation conversation =
                        GetInstance <STUVoiceConversation>(lineInstance.VoiceConversation);

                    if (conversation == null)
                    {
                        continue;                       // wtf, blizz pls
                    }
                    string convoDir = Path.Combine(path, heroNameActual, GetFileName(lineInstance.VoiceConversation));
                    foreach (STUVoiceConversationLine line in conversation.m_voiceConversationLine)
                    {
                        string linePath = Path.Combine(convoDir, line.m_B4D405A1.ToString());
                        foreach (VoiceSet voiceSet in allVoiceSets.Values)
                        {
                            if (voiceSet.VoiceLines.ContainsKey(line.m_lineGUID))
                            {
                                VoiceLine.SaveVoiceLine(flags, voiceSet.VoiceLines[line.m_lineGUID], linePath,
                                                        comboInfo);
                            }
                        }
                    }
                }
            }
        }
Пример #30
0
        public void AddNewByContentHash(Combo.ComboInfo info, HashSet <CKey> contentHashes, params ushort[] types)
        {
            foreach (KeyValuePair <ulong, ProductHandler_Tank.Asset> asset in TankHandler.m_assets)
            {
                TankHandler.UnpackAsset(asset.Value, out var package, out var record);

                ushort fileType = teResourceGUID.Type(asset.Key);
                if (fileType == 0x9C)
                {
                    continue;                   // bundle
                }
                if (fileType == 0x77)
                {
                    continue;                   // package
                }
                if (!types.Contains(fileType))
                {
                    continue;
                }

                var cmf = TankHandler.GetContentManifestForAsset(asset.Key);
                if (!cmf.TryGet(record.m_GUID, out var cmfData))
                {
                    //throw new FileNotFoundException();
                    // todo: wtf
                    continue;
                }

                if (contentHashes.Contains(cmfData.ContentKey))
                {
                    continue;
                }

                if (fileType == 0x4)
                {
                    var locale = teResourceGUID.Locale(asset.Key);
                    if (locale == 0xF)
                    {
                        continue;                // ?
                    }
                    if (locale == 0x1F)
                    {
                        continue;                 // ?
                    }
                    if (locale == 0x2F)
                    {
                        continue;                 // ?
                    }
                    if (locale == 0x3F)
                    {
                        continue;                 // ?
                    }
                    if (locale == 0x4F)
                    {
                        continue;                 // ?
                    }
                    if (locale == 0x5F)
                    {
                        continue;                 // ?
                    }
                    if (teResourceGUID.Platform(asset.Key) == 0x8)
                    {
                        continue;                                            // effect images
                    }
                }

                Combo.Find(info, asset.Key);
            }
        }