示例#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 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();
            }
        }
示例#4
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();
        }
示例#5
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);
                //     }
                // }
            }
        }
示例#6
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"));
                    }
                }
            }
        }
        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();
            }
        }
示例#8
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();
            var             comboSaveContext = new SaveLogic.Combo.SaveContext(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(), "*", teResourceGUID.Index(heroGuid).ToString("X"));

                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, comboSaveContext);
                            }
                        }
                    }
                }
            }
            comboSaveContext.Wait();
        }
示例#9
0
        public static bool SaveVoiceSet(ExtractFlags flags, string basePath, string heroName, ulong?voiceSetGuid, ref Combo.ComboInfo info, Combo.ComboInfo baseCombo = null, Dictionary <ulong, ulong> replacements = null, bool ignoreGroups = false)
        {
            if (voiceSetGuid == null)
            {
                return(false);
            }

            info = new Combo.ComboInfo();
            Combo.Find(info, voiceSetGuid.Value, replacements);

            // if we're processing a skin, baseCombo is the combo from the hero, this remove duplicate check removes any sounds that belong to the base hero
            // this ensures you only get sounds unique to the skin when processing a skin
            if (baseCombo != null)
            {
                if (!Combo.RemoveDuplicateVoiceSetEntries(baseCombo, ref info, voiceSetGuid.Value, Combo.GetReplacement(voiceSetGuid.Value, replacements)))
                {
                    return(false);
                }
            }

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

                foreach (var voicelineInstanceInfo in voiceSet.Value.VoiceLineInstances)
                {
                    foreach (var voiceLineInstance in voicelineInstanceInfo.Value)
                    {
                        var stimulus = GetInstance <STUVoiceStimulus>(voiceLineInstance.VoiceStimulus);
                        if (stimulus == null)
                        {
                            continue;
                        }

                        var groupName = GetVoiceGroup(voiceLineInstance.VoiceStimulus, stimulus.m_category, stimulus.m_87DCD58E);
                        if (groupName == null)
                        {
                            groupName = $"Unknown\\{teResourceGUID.Index(voiceLineInstance.VoiceStimulus):X}.{teResourceGUID.Type(voiceLineInstance.VoiceStimulus):X3}";
                        }

                        var soundFilesCombo   = new Combo.ComboInfo();
                        var soundFilesContext = new SaveLogic.Combo.SaveContext(soundFilesCombo);

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

                        var path = flags.VoiceGroupByHero && flags.VoiceGroupByType
                                       ? Path.Combine(basePath, heroName, groupName)
                                       : Path.Combine(basePath, flags.VoiceGroupByHero ? Path.Combine(groupName, heroName) : groupName);

                        if (ignoreGroups)
                        {
                            path = Path.Combine(basePath, heroName);
                        }

                        foreach (var soundInfo in soundFilesCombo.m_voiceSoundFiles.Values)
                        {
                            var filename = soundInfo.GetName();
                            if (!flags.VoiceGroupByHero && !ignoreGroups)
                            {
                                filename = $"{heroName}-{soundInfo.GetName()}";
                            }

                            if (SoundIdCache.Contains(soundInfo.m_GUID))
                            {
                                TACTLib.Logger.Debug("Tool", "Duplicate sound detected, ignoring.");
                                continue;
                            }

                            SoundIdCache.Add(soundInfo.m_GUID);
                            SaveLogic.Combo.SaveSoundFile(flags, path, soundFilesContext, soundInfo.m_GUID, true, filename);
                        }

                        soundFilesContext.Wait();
                    }
                }
            }

            return(true);
        }
示例#10
0
        private static bool SaveSet(ExtractFlags flags, string basePath, ulong entityMain, string heroNameActual, 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)
            {
                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);
                }
            }

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

                foreach (var voicelineInstanceInfo in voiceSet.Value.VoiceLineInstances)
                {
                    foreach (var voiceLineInstance in voicelineInstanceInfo.Value)
                    {
                        var stimulus = GetInstance <STUVoiceStimulus>(voiceLineInstance.VoiceStimulus);
                        if (stimulus == null)
                        {
                            continue;
                        }

                        var groupName = GetVoiceGroup(voiceLineInstance.VoiceStimulus, stimulus.m_category, stimulus.m_87DCD58E);
                        if (groupName == null)
                        {
                            groupName = $"Unknown\\{teResourceGUID.Index(voiceLineInstance.VoiceStimulus):X}.{teResourceGUID.Type(voiceLineInstance.VoiceStimulus):X3}";
                        }

                        var soundFilesCombo   = new Combo.ComboInfo();
                        var soundFilesContext = new SaveLogic.Combo.SaveContext(soundFilesCombo);

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

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

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

                            if (SoundIdCache.Contains(soundInfo.m_GUID))
                            {
                                TACTLib.Logger.Debug("Tool", "Duplicate sound detected, ignoring.");
                                continue;
                            }

                            SoundIdCache.Add(soundInfo.m_GUID);
                            SaveLogic.Combo.SaveSoundFile(flags, path, soundFilesContext, soundInfo.m_GUID, true, filename);
                        }

                        soundFilesContext.Wait();
                    }
                }
            }

            return(true);
        }
示例#11
0
        public void SaveUnlocksForHeroes(ICLIFlags flags, IEnumerable <KeyValuePair <ulong, 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 (KeyValuePair <ulong, STUHero> heroPair in heroes)
            {
                var    hero           = heroPair.Value;
                string heroNameActual = Hero.GetCleanName(hero);

                if (heroNameActual == null)
                {
                    continue;
                }

                Dictionary <string, ParsedArg> config = GetQuery(parsedTypes, heroNameActual.ToLowerInvariant(), "*", teResourceGUID.Index(heroPair.Key).ToString("X"));

                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));
                    }

                    var guiContext = new SaveLogic.Combo.SaveContext(guiInfo);
                    SaveLogic.Combo.SaveLooseTextures(flags, Path.Combine(heroPath, "GUI"), guiContext);
                    guiContext.Wait();
                }

                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, UnlockType.Skin.ToString(), 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);
                    }
                }

                SaveScratchDatabase();
            }
        }