Esempio n. 1
0
        public static void Save(ICLIFlags flags, string directory, STUSkinBase skin, STUHero hero)
        {
            Dictionary <ulong, ulong> replacements = GetReplacements(skin);

            LoudLog("\t\tFinding");

            FindLogic.Combo.ComboInfo info = new FindLogic.Combo.ComboInfo();
            var saveContext = new Combo.SaveContext(info);

            FindLogic.Combo.Find(info, hero.m_gameplayEntity, replacements);
            info.SetEntityName(hero.m_gameplayEntity, "Gameplay3P");

            FindLogic.Combo.Find(info, hero.m_previewEmoteEntity, replacements);
            info.SetEntityName(hero.m_previewEmoteEntity, "PreviewEmote");

            FindLogic.Combo.Find(info, hero.m_322C521A, replacements);
            info.SetEntityName(hero.m_322C521A, "Showcase");

            FindLogic.Combo.Find(info, hero.m_26D71549, replacements);
            info.SetEntityName(hero.m_26D71549, "HeroGallery");

            FindLogic.Combo.Find(info, hero.m_8125713E, replacements);
            info.SetEntityName(hero.m_8125713E, "HighlightIntro");

            if (skin is STUSkinTheme skinTheme)
            {
                info.m_processExistingEntities = true;
                List <Dictionary <ulong, ulong> > weaponReplacementStack = new List <Dictionary <ulong, ulong> >();
                for (var index = 0; index < skinTheme.m_heroWeapons.Length; index++)
                {
                    var           weaponOverrideGUID = skinTheme.m_heroWeapons[index];
                    STUHeroWeapon heroWeapon         = GetInstance <STUHeroWeapon>(weaponOverrideGUID);
                    if (heroWeapon == null)
                    {
                        continue;
                    }

                    Dictionary <ulong, ulong> weaponReplacements = GetReplacements(heroWeapon);

                    SetPreviewWeaponNames(info, weaponReplacements, hero.m_previewWeaponEntities, index);
                    SetPreviewWeaponNames(info, weaponReplacements, hero.m_C2FE396F, index);

                    weaponReplacementStack.Add(weaponReplacements == null ? new Dictionary <ulong, ulong>() : weaponReplacements.Where(x => teResourceGUID.Type(x.Key) == 0x1A).ToDictionary(x => x.Key, x => x.Value));
                }

                for (var index = 0; index < weaponReplacementStack.Count; index++)
                {
                    foreach (var pair in weaponReplacementStack[index].Where(pair => pair.Key != pair.Value && info.m_modelLooks.ContainsKey(pair.Value) && info.m_modelLooks[pair.Value].m_name == null))
                    {
                        info.SetModelLookName(pair.Value, $"{(STUWeaponType) index:G}-{teResourceGUID.Index(pair.Value):X}");
                    }
                }

                info.m_processExistingEntities = false;
            }

            foreach (STU_1A496D3C tex in hero.m_8203BFE1)   // find GUI
            {
                FindLogic.Combo.Find(info, tex.m_texture, replacements);
                info.SetTextureName(tex.m_texture, teResourceGUID.AsString(tex.m_id));
            }

            if (replacements != null)
            {
                string soundDirectory = Path.Combine(directory, "Sound");

                FindLogic.Combo.ComboInfo diffInfoBefore = new FindLogic.Combo.ComboInfo();
                FindLogic.Combo.ComboInfo diffInfoAfter  = new FindLogic.Combo.ComboInfo();
                var diffInfoAfterContext = new Combo.SaveContext(diffInfoAfter); // todo: remove

                foreach (KeyValuePair <ulong, ulong> replacement in replacements)
                {
                    uint diffReplacementType = teResourceGUID.Type(replacement.Value);
                    if (diffReplacementType != 0x2C && diffReplacementType != 0x3F &&
                        diffReplacementType != 0xB2)
                    {
                        continue;                              // no voice sets, use extract-hero-voice
                    }
                    FindLogic.Combo.Find(diffInfoAfter, replacement.Value);
                    FindLogic.Combo.Find(diffInfoBefore, replacement.Key);
                }

                foreach (KeyValuePair <ulong, FindLogic.Combo.VoiceSetAsset> voiceSet in diffInfoAfter.m_voiceSets)
                {
                    if (diffInfoBefore.m_voiceSets.ContainsKey(voiceSet.Key))
                    {
                        continue;
                    }
                    Combo.SaveVoiceSet(flags, soundDirectory, diffInfoAfterContext, voiceSet.Key);
                }

                foreach (KeyValuePair <ulong, FindLogic.Combo.SoundFileAsset> soundFile in diffInfoAfter.m_soundFiles)
                {
                    if (diffInfoBefore.m_soundFiles.ContainsKey(soundFile.Key))
                    {
                        continue;
                    }
                    Combo.SaveSoundFile(flags, soundDirectory, diffInfoAfterContext, soundFile.Key, false);
                }

                foreach (KeyValuePair <ulong, FindLogic.Combo.SoundFileAsset> soundFile in diffInfoAfter.m_voiceSoundFiles)
                {
                    if (diffInfoBefore.m_voiceSoundFiles.ContainsKey(soundFile.Key))
                    {
                        continue;
                    }
                    Combo.SaveSoundFile(flags, soundDirectory, diffInfoAfterContext, soundFile.Key, true);
                }

                diffInfoAfterContext.Wait();
            }

            LoudLog("\t\tSaving");
            Combo.SaveLooseTextures(flags, Path.Combine(directory, "GUI"), saveContext);
            Combo.Save(flags, directory, saveContext);
            saveContext.Wait();
            LoudLog("\t\tDone");
        }
Esempio n. 2
0
 public void Parse(ICLIFlags toolFlags)
 {
     SaveAbilities(toolFlags);
 }
Esempio n. 3
0
        protected Dictionary <string, Dictionary <string, ParsedArg> > ParseQuery(ICLIFlags flags,
                                                                                  List <QueryType> queryTypes, Dictionary <string, string> queryNameOverrides)
        {
            string[] result = new string[flags.Positionals.Length - 3];
            Array.Copy(flags.Positionals, 3, result, 0, flags.Positionals.Length - 3);

            Dictionary <string, Dictionary <string, ParsedArg> > parsedTypes =
                new Dictionary <string, Dictionary <string, ParsedArg> >();

            if (result.Length == 0)
            {
                return(null);
            }

            foreach (string opt in result)
            {
                if (opt.StartsWith("--"))
                {
                    continue;                       // ok so this is a flag
                }
                string[] split = opt.Split('|');

                string hero = split[0].ToLowerInvariant();
                if (queryNameOverrides != null && queryNameOverrides.ContainsKey(hero))
                {
                    hero = queryNameOverrides[hero];
                }

                string[] afterOpts = new string[split.Length - 1];
                Array.Copy(split, 1, afterOpts, 0, split.Length - 1);

                parsedTypes[hero] = new Dictionary <string, ParsedArg>();

                if (afterOpts.Length == 0)
                {
                    foreach (QueryType type in queryTypes)
                    {
                        parsedTypes[hero][type.Name] = new ParsedArg {
                            Type    = type.Name,
                            Allowed = new List <string> {
                                "*"
                            },
                            Disallowed = new List <string>(),
                            Tags       = new Dictionary <string, TagValue>()
                        };

                        if (type.Tags != null)
                        {
                            foreach (QueryTag tagObj in type.Tags.Where(x => x.Default != null))
                            {
                                string tagName = tagObj.Name.ToLowerInvariant();
                                if (parsedTypes[hero][type.Name].Tags.ContainsKey(tagName))
                                {
                                    continue;
                                }
                                TagValue valueObject = (TagValue)Activator.CreateInstance(tagObj.ValueType);
                                valueObject.Value = tagObj.Default;

                                parsedTypes[hero][type.Name].Tags[tagName] = valueObject;
                            }
                        }
                    }

                    // everything for this hero
                }
                else
                {
                    foreach (string afterHeroOpt in afterOpts)
                    {
                        string[] afterSplit = afterHeroOpt.Split('=');

                        string type = afterSplit[0].ToLowerInvariant();

                        List <QueryType> types = new List <QueryType>();
                        if (type == "*")
                        {
                            types = queryTypes;
                        }
                        else
                        {
                            types.Add(queryTypes.FirstOrDefault(x => x.Name.ToLowerInvariant() == type));
                        }


                        foreach (QueryType typeObj in types)
                        {
                            if (typeObj == null)
                            {
                                Log($"\r\nUnknown type: {type}\r\n");
                                QueryHelp(queryTypes);
                                return(null);
                            }

                            parsedTypes[hero][typeObj.Name] = new ParsedArg {
                                Type       = typeObj.Name,
                                Allowed    = new List <string>(),
                                Disallowed = new List <string>(),
                                Tags       = new Dictionary <string, TagValue>()
                            };

                            string[] items = new string[afterSplit.Length - 1];
                            Array.Copy(afterSplit, 1, items, 0, afterSplit.Length - 1);
                            items = string.Join("=", items).Split(',');
                            bool isBracket = false;
                            foreach (string item in items)
                            {
                                string realItem       = item.ToLowerInvariant();
                                bool   nextNotBracket = false;

                                if (item.StartsWith("(") && item.EndsWith(")"))
                                {
                                    realItem       = item.Remove(0, 1);
                                    realItem       = realItem.Remove(realItem.Length - 1);
                                    isBracket      = true;
                                    nextNotBracket = true;
                                }
                                else if (item.StartsWith("("))
                                {
                                    isBracket = true;
                                    realItem  = item.Remove(0, 1);
                                }
                                else if (item.EndsWith(")"))
                                {
                                    nextNotBracket = true;
                                    realItem       = item.Remove(item.Length - 1);
                                }

                                if (!isBracket)
                                {
                                    if (!realItem.StartsWith("!"))
                                    {
                                        parsedTypes[hero][typeObj.Name].Allowed.Add(realItem);
                                    }
                                    else
                                    {
                                        parsedTypes[hero][typeObj.Name].Disallowed.Add(realItem.Remove(0, 1));
                                    }
                                }
                                else
                                {
                                    string[] kv       = realItem.Split('=');
                                    string   tagName  = kv[0].ToLowerInvariant();
                                    string   tagValue = kv[1].ToLowerInvariant();
                                    QueryTag tagObj   =
                                        typeObj.Tags.FirstOrDefault(x => x.Name.ToLowerInvariant() == tagName);
                                    if (tagObj == null)
                                    {
                                        Log($"\r\nUnknown tag: {tagName}\r\n");
                                        QueryHelp(queryTypes);
                                        return(null);
                                    }

                                    TagValue valueObject = (TagValue)Activator.CreateInstance(tagObj.ValueType);
                                    valueObject.Value = tagValue;

                                    parsedTypes[hero][typeObj.Name].Tags[tagName] = valueObject;
                                }

                                if (nextNotBracket)
                                {
                                    isBracket = false;
                                }
                            }

                            foreach (QueryTag tagObj in typeObj.Tags.Where(x => x.Default != null))
                            {
                                string tagName = tagObj.Name.ToLowerInvariant();
                                if (parsedTypes[hero][typeObj.Name].Tags.ContainsKey(tagName))
                                {
                                    continue;
                                }
                                TagValue valueObject = (TagValue)Activator.CreateInstance(tagObj.ValueType);
                                valueObject.Value = tagObj.Default;

                                parsedTypes[hero][typeObj.Name].Tags[tagName] = valueObject;
                            }

                            if (parsedTypes[hero][typeObj.Name].Allowed.Count == 0 &&
                                parsedTypes[hero][typeObj.Name].Tags.Count > 0)
                            {
                                parsedTypes[hero][typeObj.Name].Allowed = new List <string> {
                                    "*"
                                };
                            }
                        }
                    }
                }
            }

            return(parsedTypes);
        }
Esempio n. 4
0
        public static void SaveUnlock(ICLIFlags flags, Unlock unlock, string path, string eventKey,
                                      Dictionary <string, ParsedArg> config,
                                      Dictionary <string, TagExpectedValue> tags, VoiceSet voiceSet, STUHero hero)
        {
            string rarity;

            if (tags != null)
            {
                if (unlock.STU.m_0B1BA7C1 == null)
                {
                    rarity             = unlock.Rarity.ToString();
                    tags["leagueTeam"] = new TagExpectedValue("none");
                }
                else
                {
                    TeamDefinition teamDef = new TeamDefinition(unlock.STU.m_0B1BA7C1);
                    tags["leagueTeam"] = new TagExpectedValue(teamDef.Abbreviation, // NY
                                                              teamDef.Location,     // New York
                                                              teamDef.Name,         // Excelsior
                                                              teamDef.FullName,     // New York Excelsior
                                                              (teamDef.Division == Enum_5A789F71.None && teamDef.Location == null) ? "none" : "*",
                                                              "*");                 // all

                    // nice file structure
                    rarity   = "";
                    eventKey = "League";
                }
                tags["rarity"] = new TagExpectedValue(unlock.Rarity.ToString());

                tags["special"] = new TagExpectedValue(unlock.Tag ?? "none");
            }
            else
            {
                rarity = ""; // for general unlocks
            }

            var eventMap = GetEventConfig();

            if (unlock.STU.m_BEE9BCDA != null)
            {
                var formalEventKey = unlock.STU.m_BEE9BCDA.FirstOrDefault(x => eventMap.ContainsKey(x));
                if (eventMap.ContainsKey(formalEventKey))
                {
                    eventKey = eventMap[formalEventKey];
                }
            }

            string thisPath = Path.Combine(path, unlock.GetTypeNameEnum(), eventKey, rarity, GetValidFilename(unlock.GetName()));

            if (ShouldDo(unlock, config, tags, typeof(STUUnlock_SprayPaint)))
            {
                SprayAndIcon.Save(flags, thisPath, unlock);
            }
            if (ShouldDo(unlock, config, tags, typeof(STUUnlock_AvatarPortrait)))
            {
                SprayAndIcon.Save(flags, thisPath, unlock);
            }

            if (ShouldDo(unlock, config, tags, typeof(STUUnlock_POTGAnimation)))
            {
                AnimationItem.Save(flags, thisPath, unlock);
            }
            if (ShouldDo(unlock, config, tags, typeof(STUUnlock_Emote)))
            {
                AnimationItem.Save(flags, thisPath, unlock);
            }
            if (ShouldDo(unlock, config, tags, typeof(STUUnlock_Pose)))
            {
                AnimationItem.Save(flags, thisPath, unlock);
            }

            if (ShouldDo(unlock, config, tags, typeof(STUUnlock_VoiceLine)))
            {
                VoiceLine.Save(flags, thisPath, unlock, voiceSet);
            }

            if (ShouldDo(unlock, config, tags, typeof(STUUnlock_SkinTheme)))
            {
                SkinTheme.Save(flags, thisPath, unlock, hero);
            }

            if (ShouldDo(unlock, config, tags, typeof(STUUnlock_PortraitFrame)))
            {
                thisPath = Path.Combine(path, unlock.Type);
                PortraitFrame.Save(flags, thisPath, unlock);
            }
        }
Esempio n. 5
0
 public void Parse(ICLIFlags toolFlags)
 {
     GetGeneralUnlocks(toolFlags);
 }
Esempio n. 6
0
        public static void SaveModel(ICLIFlags flags, string path, FindLogic.Combo.ComboInfo info, ulong model)
        {
            bool convertModels = true;
            bool doRefpose     = false;

            if (flags is ExtractFlags extractFlags)
            {
                convertModels = extractFlags.ConvertModels && !extractFlags.Raw;
                doRefpose     = extractFlags.ExtractRefpose;
                if (extractFlags.SkipModels)
                {
                    return;
                }
            }

            FindLogic.Combo.ModelInfoNew modelInfo = info.Models[model];
            string modelDirectory = Path.Combine(path, "Models", modelInfo.GetName());
            string refposePath    = "";

            if (doRefpose)
            {
                refposePath = Path.Combine(modelDirectory, modelInfo.GetNameIndex() + ".smd");
            }

            if (convertModels)
            {
                Model.OWModelWriter14 modelWriter = new Model.OWModelWriter14();

                string modelPath = Path.Combine(modelDirectory, $"{modelInfo.GetNameIndex()}{modelWriter.Format}");
                CreateDirectoryFromFile(modelPath);

                Stream modelStream = OpenFile(modelInfo.GUID);

                if (info.SaveRuntimeData.Threads)
                {
                    info.SaveRuntimeData.Tasks.Add(Task.Run(() => {
                        SaveOWModelFile(flags, modelPath, modelWriter, info, modelInfo, modelStream, doRefpose, refposePath);
                    }));
                }
                else
                {
                    SaveOWModelFile(flags, modelPath, modelWriter, info, modelInfo, modelStream, doRefpose, refposePath);
                }

                if (doRefpose)
                {
                }
            }
            else
            {
                using (Stream modelStream = OpenFile(modelInfo.GUID)) {
                    WriteFile(modelStream, Path.Combine(modelDirectory, modelInfo.GetNameIndex() + ".00C"));
                }
            }

            foreach (ulong modelModelLook in modelInfo.ModelLooks)
            {
                SaveModelLook(flags, modelDirectory, info, modelModelLook);
            }

            foreach (ulong looseMaterial in modelInfo.LooseMaterials)
            {
                SaveMaterial(flags, modelDirectory, info, looseMaterial);
            }

            foreach (ulong modelAnimation in modelInfo.Animations)
            {
                SaveAnimation(flags, modelDirectory, info, modelAnimation, model);
            }
        }
Esempio n. 7
0
        public void Parse(ICLIFlags toolFlags)
        {
            Dictionary <teResourceGUID, MapHeader> maps = GetMaps();

            if (toolFlags is ListFlags flags)
            {
                if (flags.JSON)
                {
                    OutputJSON(maps, flags);
                    return;
                }
            }

            var iD = new IndentHelper();

            foreach (var map in maps)
            {
                var data = map.Value;
                if ((toolFlags as ListFlags).Simplify)
                {
                    Log(data.GetUniqueName());
                }
                else
                {
                    Log($"{iD}{data.GetUniqueName()} ({data.MapGUID:X8})");

                    if (!string.IsNullOrEmpty(data.Name))
                    {
                        Log($"{iD + 1}Name: {data.Name}");
                    }
                    if (!string.IsNullOrEmpty(data.VariantName))
                    {
                        Log($"{iD + 1}VariantName: {data.VariantName}");
                    }
                    if (!string.IsNullOrEmpty(data.Description))
                    {
                        Log($"{iD + 1}Desc1: {data.Description}");
                    }
                    if (!string.IsNullOrEmpty(data.Description2))
                    {
                        Log($"{iD + 1}Desc2: {data.Description2}");
                    }
                    Log($"{iD + 1}Status: {data.State}");
                    Log($"{iD + 1}Type: {data.MapType}");

                    if (data.StateA != null || data.StateB != null)
                    {
                        Log($"{iD + 1}States:");
                        Log($"{iD + 2}{data.StateA ?? "N/A"}");
                        Log($"{iD + 2}{data.StateB ?? "N/A"}");
                    }

                    if (data.GameModes != null)
                    {
                        Log($"{iD + 1}GameModes:");

                        foreach (var gameModeLight in data.GameModes)
                        {
                            Console.Out.WriteLine($"{iD + 2}{gameModeLight.Name ?? "N/A"} ({teResourceGUID.AsString(gameModeLight.GUID)})");
                        }
                    }

                    Log();
                }
            }
        }
Esempio n. 8
0
        public static void Save(ICLIFlags flags, string directory, STUSkinBase skin, STUHero hero)
        {
            Dictionary <ulong, ulong> replacements = GetReplacements(skin);

            LoudLog("\t\tFinding");

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

            FindLogic.Combo.Find(info, hero.m_gameplayEntity, replacements);
            info.SetEntityName(hero.m_gameplayEntity, "Gameplay3P");

            FindLogic.Combo.Find(info, hero.m_previewEmoteEntity, replacements);
            info.SetEntityName(hero.m_previewEmoteEntity, "PreviewEmote");

            FindLogic.Combo.Find(info, hero.m_322C521A, replacements);
            info.SetEntityName(hero.m_322C521A, "Showcase");

            FindLogic.Combo.Find(info, hero.m_26D71549, replacements);
            info.SetEntityName(hero.m_26D71549, "HeroGallery");

            FindLogic.Combo.Find(info, hero.m_8125713E, replacements);
            info.SetEntityName(hero.m_8125713E, "HighlightIntro");

            if (skin is STUSkinTheme skinTheme)
            {
                info.Config.DoExistingEntities = true;
                foreach (var weaponOverrideGUID in skinTheme.m_heroWeapons)
                {
                    STUHeroWeapon heroWeapon = GetInstance <STUHeroWeapon>(weaponOverrideGUID);
                    if (heroWeapon == null)
                    {
                        continue;
                    }

                    Dictionary <ulong, ulong> weaponReplacements = GetReplacements(heroWeapon);

                    SavePreviewWeapons(info, weaponReplacements, hero.m_previewWeaponEntities);
                    SavePreviewWeapons(info, weaponReplacements, hero.m_C2FE396F);
                }
                info.Config.DoExistingEntities = false;
            }

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

            Combo.SaveLooseTextures(flags, Path.Combine(directory, "GUI"), info);

            if (replacements != null)
            {
                string soundDirectory = Path.Combine(directory, "Sound");

                FindLogic.Combo.ComboInfo diffInfoBefore = new FindLogic.Combo.ComboInfo();
                FindLogic.Combo.ComboInfo diffInfoAfter  = new FindLogic.Combo.ComboInfo();

                foreach (KeyValuePair <ulong, ulong> replacement in replacements)
                {
                    uint diffReplacementType = teResourceGUID.Type(replacement.Value);
                    if (diffReplacementType != 0x2C && diffReplacementType != 0x3F &&
                        diffReplacementType != 0xB2)
                    {
                        continue;                              // no voice sets, use extract-hero-voice
                    }
                    FindLogic.Combo.Find(diffInfoAfter, replacement.Value);
                    FindLogic.Combo.Find(diffInfoBefore, replacement.Key);
                }

                foreach (KeyValuePair <ulong, FindLogic.Combo.VoiceSetInfo> voiceSet in diffInfoAfter.VoiceSets)
                {
                    if (diffInfoBefore.VoiceSets.ContainsKey(voiceSet.Key))
                    {
                        continue;
                    }
                    Combo.SaveVoiceSet(flags, soundDirectory, diffInfoAfter, voiceSet.Key);
                }

                foreach (KeyValuePair <ulong, FindLogic.Combo.SoundFileInfo> soundFile in diffInfoAfter.SoundFiles)
                {
                    if (diffInfoBefore.SoundFiles.ContainsKey(soundFile.Key))
                    {
                        continue;
                    }
                    Combo.SaveSoundFile(flags, soundDirectory, diffInfoAfter, soundFile.Key, false);
                }

                foreach (KeyValuePair <ulong, FindLogic.Combo.SoundFileInfo> soundFile in diffInfoAfter.VoiceSoundFiles)
                {
                    if (diffInfoBefore.VoiceSoundFiles.ContainsKey(soundFile.Key))
                    {
                        continue;
                    }
                    Combo.SaveSoundFile(flags, soundDirectory, diffInfoAfter, soundFile.Key, true);
                }
            }

            LoudLog("\t\tSaving");
            Combo.Save(flags, directory, info);
            LoudLog("\t\tDone");
        }
Esempio n. 9
0
        private static void Main()
        {
            Console.OutputEncoding = Encoding.UTF8;

            Files        = new Dictionary <ulong, MD5Hash>();
            TrackedFiles = new Dictionary <ushort, HashSet <ulong> >();

            #region Tool Detection
            HashSet <Type> tools = new HashSet <Type>();
            {
                Assembly    asm   = typeof(ITool).Assembly;
                Type        t     = typeof(ITool);
                List <Type> types = asm.GetTypes().Where(tt => tt != t && t.IsAssignableFrom(tt)).ToList();
                foreach (Type tt in types)
                {
                    ToolAttribute attrib = tt.GetCustomAttribute <ToolAttribute>();
                    if (tt.IsInterface || attrib == null)
                    {
                        continue;
                    }
                    tools.Add(tt);

                    if (attrib.TrackTypes == null)
                    {
                        continue;
                    }
                    foreach (ushort type in attrib.TrackTypes)
                    {
                        if (!TrackedFiles.ContainsKey(type))
                        {
                            TrackedFiles[type] = new HashSet <ulong>();
                        }
                    }
                }
            }
            #endregion

            Flags = FlagParser.Parse <ToolFlags>(() => PrintHelp(tools));
            if (Flags == null)
            {
                return;
            }

            Logger.EXIT = !Flags.GracefulExit;

            ITool     targetTool      = null;
            ICLIFlags targetToolFlags = null;

            #region Tool Activation

            foreach (Type type in tools)
            {
                ToolAttribute attrib = type.GetCustomAttribute <ToolAttribute>();

                if (!string.Equals(attrib.Keyword, Flags.Mode, StringComparison.InvariantCultureIgnoreCase))
                {
                    continue;
                }
                targetTool = Activator.CreateInstance(type) as ITool;

                if (attrib.CustomFlags != null)
                {
                    Type flags = attrib.CustomFlags;
                    if (typeof(ICLIFlags).IsAssignableFrom(flags))
                    {
                        targetToolFlags = typeof(FlagParser).GetMethod("Parse", new Type[] { }).MakeGenericMethod(flags).Invoke(null, null) as ICLIFlags;
                    }
                }
                break;
            }

            #endregion

            if (targetTool == null)
            {
                FlagParser.Help <ToolFlags>(false);
                PrintHelp(tools);
                if (Debugger.IsAttached)
                {
                    Debugger.Break();
                }
                return;
            }

            #region Initialize CASC
            Log("{0} v{1}", Assembly.GetExecutingAssembly().GetName().Name, Util.GetVersion());
            Log("Initializing CASC...");
            Log("Set language to {0}", Flags.Language);
            CDNIndexHandler.Cache.Enabled   = Flags.UseCache;
            CDNIndexHandler.Cache.CacheData = Flags.CacheData;
            CDNIndexHandler.Cache.Validate  = Flags.ValidateCache;
            // ngdp:us:pro
            // http:us:pro:us.patch.battle.net:1119
            if (Flags.OverwatchDirectory.ToLowerInvariant().Substring(0, 5) == "ngdp:")
            {
                string   cdn     = Flags.OverwatchDirectory.Substring(5, 4);
                string[] parts   = Flags.OverwatchDirectory.Substring(5).Split(':');
                string   region  = "us";
                string   product = "pro";
                if (parts.Length > 1)
                {
                    region = parts[1];
                }
                if (parts.Length > 2)
                {
                    product = parts[2];
                }
                if (cdn == "bnet")
                {
                    Config = CASCConfig.LoadOnlineStorageConfig(product, region);
                }
                else
                {
                    if (cdn == "http")
                    {
                        string host = string.Join(":", parts.Skip(3));
                        Config = CASCConfig.LoadOnlineStorageConfig(host, product, region, true, true, true);
                    }
                }
            }
            else
            {
                Config = CASCConfig.LoadLocalStorageConfig(Flags.OverwatchDirectory, !Flags.SkipKeys, false);
            }
            Config.Languages = new HashSet <string>(new[] { Flags.Language });
            #endregion

            foreach (Dictionary <string, string> build in Config.BuildInfo)
            {
                if (!build.ContainsKey("Tags"))
                {
                    continue;
                }
                if (build["Tags"].Contains("XX?"))
                {
                    IsPTR = true;
                }
                // us ptr region is known as XX, so just look for it in the tags.
                // this should work... untested for Asia
            }

            BuildVersion = uint.Parse(Config.BuildName.Split('.').Last());

            if (Flags.SkipKeys)
            {
                Log("Disabling Key auto-detection...");
            }

            Log("Using Overwatch Version {0}", Config.BuildName);
            CASC = CASCHandler.OpenStorage(Config);
            Root = CASC.Root as OwRootHandler;
            if (Root == null)
            {
                ErrorLog("Not a valid overwatch installation");
                return;
            }

            // Fail when trying to extract data from a specified language with 2 or less files found.
            if (!Root.APMFiles.Any())
            {
                ErrorLog("Could not find the files for language {0}. Please confirm that you have that language installed, and are using the names from the target language.", Flags.Language);
                if (!Flags.GracefulExit)
                {
                    return;
                }
            }

            Log("Mapping...");
            TrackedFiles[0x90] = new HashSet <ulong>();
            IO.MapCMF();
            IO.LoadGUIDTable();
            Sound.WwiseBank.GetReady();

            #region Key Detection
            if (!Flags.SkipKeys)
            {
                Log("Adding Encryption Keys...");

                foreach (ulong key in TrackedFiles[0x90])
                {
                    if (!ValidKey(key))
                    {
                        continue;
                    }
                    using (Stream stream = IO.OpenFile(Files[key])) {
                        if (stream == null)
                        {
                            continue;
                        }

                        STUEncryptionKey encryptionKey = GetInstance <STUEncryptionKey>(key);
                        if (encryptionKey != null && !KeyService.keys.ContainsKey(encryptionKey.LongRevKey))
                        {
                            KeyService.keys.Add(encryptionKey.LongRevKey, encryptionKey.KeyValue);
                            Log("Added Encryption Key {0}, Value: {1}", encryptionKey.KeyNameProper, encryptionKey.Key);
                        }
                    }
                }
            }
            #endregion

            Log("Tooling...");
            targetTool.Parse(targetToolFlags);
            if (Debugger.IsAttached)
            {
                Debugger.Break();
            }
        }
Esempio n. 10
0
        public static void Save(ICLIFlags flags, MapHeader mapInfo, STUMapHeader mapHeader, ulong key, string basePath)
        {
            var name = mapInfo.GetName();

            LoudLog($"Extracting map {name}/{teResourceGUID.Index(key):X}");

            // TODO: MAP11 HAS CHANGED
            // TODO: MAP10 TOO?

            name = GetValidFilename(name);
            string mapPath = Path.Combine(basePath, "Maps", name, teResourceGUID.Index(key).ToString("X")) + Path.DirectorySeparatorChar;

            CreateDirectoryFromFile(mapPath);

            FindLogic.Combo.ComboInfo info = new FindLogic.Combo.ComboInfo();
            LoudLog("\tFinding");
            FindLogic.Combo.Find(info, mapHeader.m_map);

            //for (ushort i = 0; i < 255; i++) {
            //    using (Stream mapChunkStream = OpenFile(mapHeader.GetChunkKey((byte)i))) {
            //        if (mapChunkStream == null) continue;
            //        WriteFile(mapChunkStream, Path.Combine(mapPath, $"{(Enums.teMAP_PLACEABLE_TYPE)i}.0BC"));
            //    }
            //}
            //return;

            teMapPlaceableData placeableModelGroups  = GetPlaceableData(mapHeader, Enums.teMAP_PLACEABLE_TYPE.MODEL_GROUP);
            teMapPlaceableData placeableSingleModels = GetPlaceableData(mapHeader, Enums.teMAP_PLACEABLE_TYPE.SINGLE_MODEL);
            teMapPlaceableData placeableModel        = GetPlaceableData(mapHeader, Enums.teMAP_PLACEABLE_TYPE.MODEL);
            teMapPlaceableData placeableLights       = GetPlaceableData(mapHeader, Enums.teMAP_PLACEABLE_TYPE.LIGHT);
            teMapPlaceableData placeableEntities     = GetPlaceableData(mapHeader, Enums.teMAP_PLACEABLE_TYPE.ENTITY);
            teMapPlaceableData placeableSounds       = GetPlaceableData(mapHeader, Enums.teMAP_PLACEABLE_TYPE.SOUND);
            teMapPlaceableData placeableEffects      = GetPlaceableData(mapHeader, Enums.teMAP_PLACEABLE_TYPE.EFFECT);

            OverwatchMap exportMap = new OverwatchMap(name, info, placeableSingleModels, placeableModelGroups, placeableModel, placeableEntities, placeableLights, placeableSounds, placeableEffects);

            using (Stream outputStream = File.OpenWrite(Path.Combine(mapPath, $"{name}.{exportMap.Extension}"))) {
                exportMap.Write(outputStream);
            }

            {
                FindLogic.Combo.Find(info, mapHeader.m_86C1CFAB);
                FindLogic.Combo.Find(info, mapHeader.m_9386E669);
                FindLogic.Combo.Find(info, mapHeader.m_C6599DEB);

                if (mapHeader.m_D608E9F3 != null)
                {
                    foreach (teResourceGUID gamemodeGUID in mapHeader.m_D608E9F3)
                    {
                        STUGameMode gameMode = GetInstance <STUGameMode>(gamemodeGUID);
                        if (gameMode == null)
                        {
                            continue;
                        }

                        FindLogic.Combo.Find(info, gameMode.m_6EB38130); // 004
                        FindLogic.Combo.Find(info, gameMode.m_CF63B633); // 01B
                        FindLogic.Combo.Find(info, gameMode.m_7F5B54B2); // game mode voice set

                        foreach (STUGameModeTeam team in gameMode.m_teams)
                        {
                            FindLogic.Combo.Find(info, team.m_bodyScript);       // 01B
                            FindLogic.Combo.Find(info, team.m_controllerScript); // 01B
                        }
                    }
                }
            }

            FindLogic.Combo.Find(info, mapHeader.m_announcerWelcome);
            info.SetEffectName(mapHeader.m_announcerWelcome, "AnnouncerWelcome");
            FindLogic.Combo.Find(info, mapHeader.m_musicTease);
            info.SetEffectName(mapHeader.m_musicTease, "MusicTease");

            ulong announcerVoiceSet = 0;

            using (Stream stream = OpenFile(mapHeader.m_map)) {
                if (stream != null)
                {
                    using (BinaryReader reader = new BinaryReader(stream)) {
                        teMap map = reader.Read <teMap>();

                        STUVoiceSetComponent voiceSetComponent =
                            GetInstance <STUVoiceSetComponent>(map.EntityDefinition);
                        announcerVoiceSet = voiceSetComponent?.m_voiceDefinition;
                        FindLogic.Combo.Find(info, announcerVoiceSet);

                        info.SetEffectVoiceSet(mapHeader.m_announcerWelcome, announcerVoiceSet);
                    }
                }
            }

            LoudLog("\tSaving");
            var context = new Combo.SaveContext(info);

            Combo.Save(flags, mapPath, context);
            Combo.SaveLooseTextures(flags, Path.Combine(mapPath, "Textures"), context);
            context.Wait();

            if (mapHeader.m_7F5B54B2 != 0)   // map voice set. not announcer
            {
                FindLogic.Combo.Find(info, mapHeader.m_7F5B54B2);
            }

            if (announcerVoiceSet != 0)   // whole thing in env mode, not here
            {
                info.m_voiceSets.Remove(announcerVoiceSet);
            }

            Combo.SaveAllVoiceSets(flags, Path.Combine(mapPath, "VoiceSets"), context);
            Combo.SaveAllSoundFiles(flags, Path.Combine(mapPath, "Sound"), context);
            context.Wait();

            LoudLog("\tDone");
        }
Esempio n. 11
0
 public void Parse(ICLIFlags toolFlags)
 {
     RAMTest(toolFlags);
 }
Esempio n. 12
0
 public void Parse(ICLIFlags toolFlags)
 {
     GetLootboxes(toolFlags);
 }
Esempio n. 13
0
 public void Parse(ICLIFlags toolFlags)
 {
     ExtractMOVI(toolFlags);
 }
Esempio n. 14
0
 public void Parse(ICLIFlags toolFlags)
 {
     SpecialHelper(toolFlags);
 }
Esempio n. 15
0
        public void SaveMaps(ICLIFlags toolFlags)
        {
            string basePath;

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

            basePath = Path.Combine(basePath, "Environments");

            if (!Directory.Exists(basePath))
            {
                Directory.CreateDirectory(basePath);
            }

            if (!flags.SkipMapEnvironmentLUT && File.Exists(Path.Combine(basePath, "SPILUT", "config.ocio")))
            {
                File.Delete(Path.Combine(basePath, "SPILUT", "config.ocio"));
            }

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

            foreach (ulong metaKey in TrackedFiles[0x9F])
            {
                STUMapHeader map = GetInstance <STUMapHeader>(metaKey);
                if (map == null)
                {
                    continue;
                }

                MapHeader mapInfo = GetMap(metaKey);

                ulong dataKey = map.m_map;

                //if (teResourceGUID.Index(dataKey) != 0x7A4) continue;

                var    mapName = GetValidFilename($"{mapInfo.GetName()}_{teResourceGUID.Index(mapInfo.MapGUID):X}");
                string fname   = $"ow_map_{mapName}";

                var reflectionData = Map.GetPlaceableData(map, Enums.teMAP_PLACEABLE_TYPE.REFLECTIONPOINT);
                if (reflectionData != null)
                {
                    foreach (var placeable in reflectionData.Placeables ?? Array.Empty <IMapPlaceable>())
                    {
                        if (!(placeable is teMapPlaceableReflectionPoint reflectionPoint))
                        {
                            continue;
                        }
                        if (done.Add(new KeyValuePair <ulong, string>(reflectionPoint.Header.Texture1, mapInfo.Name + "cube")))
                        {
                            SaveTex(flags, basePath, Path.Combine("Cubemap", fname), reflectionPoint.Header.Texture1.ToString(), reflectionPoint.Header.Texture1);
                        }

                        if (done.Add(new KeyValuePair <ulong, string>(reflectionPoint.Header.Texture2, mapInfo.Name + "cube")))
                        {
                            SaveTex(flags, basePath, Path.Combine("Cubemap", fname), reflectionPoint.Header.Texture2.ToString(), reflectionPoint.Header.Texture2);
                        }
                    }
                }

                using (Stream data = OpenFile(dataKey)) {
                    if (data != null)
                    {
                        using (BinaryReader dataReader = new BinaryReader(data)) {
                            teMap env = dataReader.Read <teMap>();

                            // using (Stream lightingStream = OpenFile(env.BakedLighting)) {
                            //    teLightingManifest lightingManifest = new teLightingManifest(lightingStream);
                            //}

                            if (!flags.SkipMapEnvironmentSound && done.Add(new KeyValuePair <ulong, string>(env.MapEnvironmentSound, mapInfo.Name)))
                            {
                                SaveSound(flags, basePath, Path.Combine("Sound", mapName), env.MapEnvironmentSound);
                            }
                            if (!flags.SkipMapEnvironmentLUT && done.Add(new KeyValuePair <ulong, string>(env.LUT, mapInfo.Name)))
                            {
                                SaveTex(flags, basePath, "LUT", fname + env.LUT, env.LUT);
                                SaveLUT(flags, basePath, "SPILUT", fname + env.LUT, env.LUT, Path.Combine(basePath, "SPILUT", "config.ocio"), mapInfo);
                            }

                            if (!flags.SkipMapEnvironmentBlendCubemap && done.Add(new KeyValuePair <ulong, string>(env.BlendEnvironmentCubemap, mapInfo.Name)))
                            {
                                SaveTex(flags, basePath, "BlendCubemap", fname + env.BlendEnvironmentCubemap, env.BlendEnvironmentCubemap);
                            }
                            if (!flags.SkipMapEnvironmentGroundCubemap && done.Add(new KeyValuePair <ulong, string>(env.GroundEnvironmentCubemap, mapInfo.Name)))
                            {
                                SaveTex(flags, basePath, "GroundCubemap", fname + env.GroundEnvironmentCubemap, env.GroundEnvironmentCubemap);
                            }
                            if (!flags.SkipMapEnvironmentSkyCubemap && done.Add(new KeyValuePair <ulong, string>(env.SkyEnvironmentCubemap, mapInfo.Name)))
                            {
                                SaveTex(flags, basePath, "SkyCubemap", fname + env.SkyEnvironmentCubemap, env.SkyEnvironmentCubemap);
                            }
                            if (!flags.SkipMapEnvironmentSkybox && done.Add(new KeyValuePair <ulong, string>(env.SkyboxModel + env.SkyboxModelLook, mapInfo.Name)))
                            {
                                SaveMdl(flags, basePath, Path.Combine("Skybox", mapName), env.SkyboxModel, env.SkyboxModelLook);
                            }
                            if (!flags.SkipMapEnvironmentEntity && done.Add(new KeyValuePair <ulong, string>(env.EntityDefinition, mapInfo.Name)))
                            {
                                SaveEntity(flags, basePath, Path.Combine("Entity", mapName), env.EntityDefinition);
                            }
                        }
                    }
                }

                InfoLog("Saved Environment data for {0}", mapInfo.GetUniqueName());
                SaveScratchDatabase();
            }
        }
Esempio n. 16
0
        public void GetSoundbanks(ICLIFlags toolFlags)
        {
            const string container = "ShaderCode";
            //const ulong materialGUID = 0xE00000000005860;  // 000000005860.008: Sombra - League - NYXL - Main
            //const string matName = "Sombra - League - NYXL - Main";

            //const ulong materialGUID = 0xE00000000006086;
            //const string matName = "Orisa - Nature - Leaves";

            //const ulong materialGUID = 0xE00000000002381;
            //const string matName = "Maps - Tall bush";

            //const ulong materialGUID = 0xE000000000008B2;
            //const string matName = "Widow - Odette - Arm tassels";


            // orisa owl
            //const ulong materialGUID = 0xE00000000005809;  // 000000005809.008: Orisa - League - NYXL - Team Decals
            //const string matName = "Orisa - League - NYXL - Team Decals";

            //const ulong materialGUID = 0xE00000000005840;
            //const string matName = "Orisa - League - NYXL - Main";

            //const ulong materialGUID = 0xE000000000051CC;
            //const string matName = "Orisa - League - NYXL - 51CC";

            string basePath;

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

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

            //TestModelLook(0x98000000000682F); // Chateau - Lake

            //SaveMaterial(path, 0xE00000000004F46, "Chateau - Tower - Body");
            //SaveMaterial(path, 0xE00000000004F45, "Chateau - Tower - Borders");
            //SaveMaterial(path, 0xE00000000004D4B, "Chateau - Tower - Windows");
            //SaveMaterial(path, 0xE00000000004F44, "Chateau - Tower - Tip");
            //SaveMaterial(path, 0xE000000000003A5, "Rein - Shield - Main");
            //SaveMaterial(path, 0xE00000000005840, "Orisa - League - NYXL - Main");
            //SaveMaterial(path, 0xE00000000005809, "Orisa - League - NYXL - Team Decals");
            //SaveMaterial(path, 0xE00000000005C70, "Moira - Blackwatch - Decals");
            //SaveMaterial(path, 0xE0000000000562D, "Moira - Blackwatch - Face");
            //SaveCompute(path);

            // string allPath = Path.Combine(path, "All");
            // foreach (ulong inst in TrackedFiles[0x86]) {
            //     SaveShaderInstance(allPath, inst, teResourceGUID.AsString(inst));
            // }
            // return;

            SaveMaterial(path, 0xE00000000002381, "Chateau - Tall bush");
            SaveMaterial(path, 0xE00000000004D29, "Chateau - Lake");
            //SaveMaterial(path, 0xE00000000004F0B, "Chateau - Background - Road");
            //SaveMaterial(path, 0xE00000000004EFF, "Chateau - Background - House");
            SaveMaterial(path, 0xE00000000004F46, "Chateau - Tower - Body");
            SaveMaterial(path, 0xE000000000040C0, "Orisa - Classic - Main");
            SaveMaterial(path, 0xE00000000000171, "Reaper - Classic - Main");
            SaveMaterial(path, 0xE00000000005BBB, "Brigitte - Classic - Hair");

            //SavePostFX(path);
            //SaveScreenQuad(path);
            Save088(path);
        }
Esempio n. 17
0
        public static void SaveAnimation(ICLIFlags flags, string path, FindLogic.Combo.ComboInfo info, ulong animation,
                                         ulong model)
        {
            bool convertAnims = false;

            if (flags is ExtractFlags extractFlags)
            {
                convertAnims = extractFlags.ConvertAnimations && !extractFlags.Raw;
                if (extractFlags.SkipAnimations)
                {
                    return;
                }
            }

            SEAnimWriter animWriter = new SEAnimWriter();

            FindLogic.Combo.AnimationInfoNew animationInfo = info.Animations[animation];

            using (Stream animStream = OpenFile(animation)) {
                if (animStream == null)
                {
                    return;
                }
                MemoryStream animMemStream = new MemoryStream();
                animStream.CopyTo(animMemStream);

                if (info.SaveRuntimeData.Threads)
                {
                    info.SaveRuntimeData.Tasks.Add(Task.Run(() => {
                        ConvertAnimation(animMemStream, path, convertAnims, animWriter, animationInfo);
                    }));
                }
                else
                {
                    ConvertAnimation(animMemStream, path, convertAnims, animWriter, animationInfo);
                }
            }

            if (!info.SaveConfig.SaveAnimationEffects)
            {
                return;
            }
            FindLogic.Combo.EffectInfoCombo animationEffect;


            // just create a fake effect if it doesn't exist
            if (animationInfo.Effect == 0)
            {
                animationEffect = new FindLogic.Combo.EffectInfoCombo(0)
                {
                    Effect = new EffectParser.EffectInfo()
                };
                animationEffect.Effect.SetupEffect();
            }
            else if (info.Effects.ContainsKey(animationInfo.Effect))
            {
                // wot, why
                animationEffect = info.Effects[animationInfo.Effect];
            }
            else
            {
                animationEffect = info.AnimationEffects[animationInfo.Effect];
            }

            Effect.OWAnimWriter owAnimWriter = new Effect.OWAnimWriter();
            string animationEffectDir        = Path.Combine(path, Model.AnimationEffectDir, animationInfo.GetNameIndex());
            string animationEffectFile       =
                Path.Combine(animationEffectDir, $"{animationInfo.GetNameIndex()}{owAnimWriter.Format}");
            Dictionary <ulong, HashSet <FindLogic.Combo.VoiceLineInstanceInfo> > svceLines = new Dictionary <ulong, HashSet <FindLogic.Combo.VoiceLineInstanceInfo> >();

            if (animationEffect.GUID != 0)
            {
                SaveEffectExtras(flags, animationEffectDir, info, animationEffect.Effect, out svceLines);
            }
            if (info.SaveRuntimeData.Threads)
            {
                info.SaveRuntimeData.Tasks.Add(Task.Run(() => {
                    SaveOWAnimFile(animationEffectFile, animationEffect, animationInfo, info, owAnimWriter, model, svceLines);
                }));
            }
            else
            {
                SaveOWAnimFile(animationEffectFile, animationEffect, animationInfo, info, owAnimWriter, model, svceLines);
            }
        }
Esempio n. 18
0
 public void Parse(ICLIFlags toolFlags)
 {
     ExtractOWL(toolFlags);
 }
Esempio n. 19
0
        public static void SaveTexture(ICLIFlags flags, string path, FindLogic.Combo.ComboInfo info, ulong texture)
        {
            bool   convertTextures = true;
            bool   lossless        = false;
            string convertType     = "dds";

            if (flags is ExtractFlags extractFlags)
            {
                convertTextures = extractFlags.ConvertTextures && !extractFlags.Raw;
                convertType     = extractFlags.ConvertTexturesType.ToLowerInvariant();
                lossless        = extractFlags.ConvertTexturesLossless;
                if (extractFlags.SkipTextures)
                {
                    return;
                }
            }
            path += Path.DirectorySeparatorChar;

            FindLogic.Combo.TextureInfoNew textureInfo = info.Textures[texture];
            string filePath = Path.Combine(path, $"{textureInfo.GetNameIndex()}");

            if (!convertTextures)
            {
                CreateDirectoryFromFile(path);
                using (Stream textureStream = OpenFile(textureInfo.GUID))
                    WriteFile(textureStream, $"{filePath}.{GUID.Type(textureInfo.GUID):X3}");

                if (!textureInfo.UseData)
                {
                    return;
                }
                using (Stream textureStream = OpenFile(textureInfo.DataGUID))
                    WriteFile(textureStream, $"{filePath}.04D");
            }
            else
            {
                Stream headerStream = OpenFile(textureInfo.GUID);
                Stream dataStream   = null;
                if (headerStream == null)
                {
                    return;
                }
                if (textureInfo.UseData)
                {
                    dataStream = OpenFile(textureInfo.DataGUID);
                    if (dataStream == null)
                    {
                        return;
                    }
                }

                if (info.SaveRuntimeData.Threads)
                {
                    info.SaveRuntimeData.Tasks.Add(Task.Run(() => {
                        ConvertTexture(convertType, lossless, filePath, path, headerStream, dataStream);
                    }));
                }
                else
                {
                    ConvertTexture(convertType, lossless, filePath, path, headerStream, dataStream);
                }
            }
        }
Esempio n. 20
0
        public void ExtractOWL(ICLIFlags toolFlags)
        {
            string basePath;

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

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

            // foreach (ulong key in TrackedFiles[0xB3]) {
            //     string p = Path.Combine(path, "MatDatas");
            //     if (GUID.Index(key) != 0x8EE9) continue;
            //     ImageDefinition def = new ImageDefinition(OpenFile(key));
            //     SaveTextureDef(flags, p, key, def);
            //     // if (def.Layers != null) {
            //     //     foreach (ImageLayer layer in def.Layers) {
            //     //         if (GUID.Index(layer.Key) == 0x120E2) {  // sf shock normal
            //     //             // Debugger.Break();
            //     //             SaveTextureDef(flags, p, key, def);
            //     //             // found 346777171307564171
            //     //         }
            //     //
            //     //         if (GUID.Index(layer.Key) == 0x11C3F) {  // sym normal
            //     //             // Debugger.Break();
            //     //             SaveTextureDef(flags, p, key, def);
            //     //             // found 346777171307564777
            //     //             // found 346777171307565869
            //     //         }
            //     //
            //     //         if (GUID.Index(layer.Key) == 0x11D56) {  // widow sss
            //     //             // Debugger.Break();
            //     //             SaveTextureDef(flags, p, key, def);
            //     //             //346777171307565850 / 00000000931A.0B3
            //     //         }
            //     //     }
            //     // }
            // }

            List <string> added = ExtractDebugNewEntities.GetAddedFiles("D:\\ow\\OverwatchDataManager\\versions\\1.20.0.2.43435\\data.json");

            Combo.ComboInfo imgInfo = new Combo.ComboInfo();
            // Combo.Find(imgInfo, 864691265894168957ul);
            //foreach (ulong key in TrackedFiles[0xA5]) {
            //    string name = GetFileName(key);
            //    if (!added.Contains(name)) continue;
            //    Skin skin = GetInstance<Skin>(key);
            //    if (skin == null) continue;
            //}

            foreach (ulong key in TrackedFiles[0x4])
            {
                string name = GetFileName(key);
                if (name[3] == 'F')
                {
                    continue;                  // :thonk:
                }
                if (!added.Contains(name))
                {
                    continue;
                }
                Combo.Find(imgInfo, key);
            }
            Console.Out.WriteLine("ok i do save");
            SaveLogic.Combo.SaveLooseTextures(flags, Path.Combine(path, "Tex"), imgInfo);

            return;


            foreach (ulong key in TrackedFiles[0xA6])
            {
                STUSkinOverride @override = GetInstance <STUSkinOverride>(key);
                string          name      = GetFileName(key);
                if (!added.Contains(name))
                {
                    continue;
                }

                Combo.ComboInfo info  = new Combo.ComboInfo();
                Combo.ComboInfo info2 = new Combo.ComboInfo();
                foreach (KeyValuePair <ulong, ulong> overrideReplacement in @override.ProperReplacements)
                {
                    Combo.Find(info, overrideReplacement.Key);
                    Combo.Find(info2, overrideReplacement.Value);
                }

                string p = Path.Combine(path, "SkinOverrides", GetFileName(key));

                SaveLogic.Combo.Save(flags, Path.Combine(p, "Before"), info);
                // SaveLogic.Combo.SaveAllMaterials(flags, Path.Combine(p, "Before"), info);
                SaveLogic.Combo.SaveAllModelLooks(flags, Path.Combine(p, "Before"), info);
                SaveLogic.Combo.Save(flags, Path.Combine(p, "After"), info2);
                // SaveLogic.Combo.SaveAllMaterials(flags, Path.Combine(p, "After"), info2);
                SaveLogic.Combo.SaveAllModelLooks(flags, Path.Combine(p, "After"), info2);
            }

            // foreach (ulong key in TrackedFiles[0x8]) {
            //     Material material = new Material(OpenFile(key), 0);
            //     if (GUID.Index(material.Header.ImageDefinition) == 0x931A) {
            //         Debugger.Break();
            //     }
            // }
        }
Esempio n. 21
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);
                    }
                }
            }
        }
Esempio n. 22
0
 public void Parse(ICLIFlags toolFlags)
 {
     GetFewParticles();
 }
Esempio n. 23
0
 public void Parse(ICLIFlags toolFlags)
 {
     ExtractType(toolFlags);
 }
Esempio n. 24
0
 public void Parse(ICLIFlags toolFlags)
 {
     GetSoundbanks();
 }
Esempio n. 25
0
        public void Parse(ICLIFlags toolFlags)
        {
            List <HighlightJSON> highlights = new List <HighlightJSON>();

            DirectoryInfo overwatchAppdataFolder = new DirectoryInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Blizzard Entertainment/Overwatch"));

            foreach (DirectoryInfo userFolder in overwatchAppdataFolder.GetDirectories())
            {
                DirectoryInfo highlightsFolder = new DirectoryInfo(Path.Combine(userFolder.FullName,
                                                                                $"{(Program.IsPTR ? "PTR\\" : "")}Highlights"));
                if (!highlightsFolder.Exists)
                {
                    continue;
                }
                highlights.AddRange(highlightsFolder.GetFiles().Select(item => GetHighlight(item.FullName)));
            }

            if (toolFlags is ListFlags flags)
            {
                if (flags.JSON)
                {
                    ParseJSON(highlights, flags);
                    return;
                }
            }

            // todo: timestamp
            IndentHelper indent = new IndentHelper();
            uint         count  = 0;

            foreach (HighlightJSON highlight in highlights)
            {
                if (count != 0)
                {
                    Log($"{Environment.NewLine}");
                }
                Log($"{indent}{highlight.UUID}:");
                Log($"{indent+1}Map: {highlight.Map}");
                Log($"{indent+1}Gamemode: {highlight.Gamemode}");
                Log($"{indent+1}HighlightInfo:");
                for (int i = 0; i < highlight.HighlightInfo.Count; i++)
                {
                    Log($"{indent+2}[{i}] {{");
                    PrintHighlightInfoJSON(highlight.HighlightInfo[i], indent + 3);
                    Log($"{indent+2}}}");
                }
                Log($"{indent+1}Heroes:");
                for (int i = 0; i < highlight.HeroInfo.Count; i++)
                {
                    Log($"{indent+2}[{i}] {{");
                    Log($"{indent+3}Hero: {highlight.HeroInfo[i].Hero}");
                    Log($"{indent+3}Skin: {highlight.HeroInfo[i].Skin}");
                    Log($"{indent+3}HiglightIntro: {highlight.HeroInfo[i].HighlightIntro}");

                    Log($"{indent+3}Sprays:");
                    foreach (string spray in highlight.HeroInfo[i].Sprays)
                    {
                        Log($"{indent+4}{spray}");
                    }

                    Log($"{indent+3}Emotes:");
                    foreach (string emote in highlight.HeroInfo[i].Emotes)
                    {
                        Log($"{indent+4}{emote}");
                    }

                    Log($"{indent+3}VoiceLines:");
                    foreach (string voiceLine in highlight.HeroInfo[i].VoiceLines)
                    {
                        Log($"{indent+4}{voiceLine}");
                    }

                    Log($"{indent+2}}}");
                }
                Log($"{indent+1}Replay: {{");
                Log($"{indent+2}Map: {highlight.Replay.Map}");
                Log($"{indent+2}Gamemode: {highlight.Replay.Gamemode}");
                Log($"{indent+2}HighlightInfo:");
                PrintHighlightInfoJSON(highlight.Replay.HighlightInfo, indent + 3);
                Log($"{indent+1}}}");
                count++;
            }
        }
Esempio n. 26
0
        private static void Main()
        {
            InitTankSettings();

            HookConsole();

            var tools = GetTools();

        #if DEBUG
            FlagParser.CheckCollisions(typeof(ToolFlags), (flag, duplicate) => {
                Logger.Error("Flag", $"The flag \"{flag}\" from {duplicate} is a duplicate!");
            });
        #endif

            FlagParser.LoadArgs();

            Logger.Info("Core", $"{Assembly.GetExecutingAssembly().GetName().Name} v{Util.GetVersion(typeof(Program).Assembly)}");

            Logger.Info("Core", $"CommandLine: [{string.Join(", ", FlagParser.AppArgs.Select(x => $"\"{x}\""))}]");

            Flags = FlagParser.Parse <ToolFlags>(full => PrintHelp(full, tools));
            if (Flags == null)
            {
                return;
            }

            Logger.Info("Core", $"CommandLineFile: {FlagParser.ArgFilePath}");

            if (Flags.SaveArgs)
            {
                FlagParser.AppArgs = FlagParser.AppArgs.Where(x => !x.StartsWith("--arg")).ToArray();
                FlagParser.SaveArgs(Flags.OverwatchDirectory);
            }
            else if (Flags.ResetArgs || Flags.DeleteArgs)
            {
                FlagParser.ResetArgs();

                if (Flags.DeleteArgs)
                {
                    FlagParser.DeleteArgs();
                }

                Logger.Info("Core", $"CommandLineNew: [{string.Join(", ", FlagParser.AppArgs.Select(x => $"\"{x}\""))}]");
                Flags = FlagParser.Parse <ToolFlags>(full => PrintHelp(full, tools));
                if (Flags == null)
                {
                    return;
                }
            }

            if (string.IsNullOrWhiteSpace(Flags.OverwatchDirectory) || string.IsNullOrWhiteSpace(Flags.Mode) || Flags.Help)
            {
                PrintHelp(false, tools);
                return;
            }

            ITool         targetTool           = null;
            ICLIFlags     targetToolFlags      = null;
            ToolAttribute targetToolAttributes = null;

            #region Tool Activation

            foreach (var type in tools)
            {
                var attribute = type.GetCustomAttribute <ToolAttribute>();

                if (!string.Equals(attribute.Keyword, Flags.Mode, StringComparison.InvariantCultureIgnoreCase))
                {
                    continue;
                }
                targetTool           = Activator.CreateInstance(type) as ITool;
                targetToolAttributes = attribute;

                if (attribute.CustomFlags != null)
                {
                    var flags = attribute.CustomFlags;
                    if (typeof(ICLIFlags).IsAssignableFrom(flags))
                    {
                        targetToolFlags = typeof(FlagParser).GetMethod(nameof(FlagParser.Parse), new Type[] { })
                                          ?.MakeGenericMethod(flags)
                                          .Invoke(null, null) as ICLIFlags;
                    }
                }

                break;
            }

            if (targetToolFlags == null && targetTool != null)
            {
                return;
            }

            if (targetTool == null)
            {
                FlagParser.Help <ToolFlags>(false, new Dictionary <string, string>());
                PrintHelp(false, tools);
                return;
            }

            #endregion

            if (!targetToolAttributes.UtilNoArchiveNeeded)
            {
                try {
                    InitStorage(Flags.Online);
                } catch {
                    Logger.Log24Bit(ConsoleSwatch.XTermColor.OrangeRed, true, Console.Error, "CASC",
                                    "=================\nError initializing CASC!\n" +
                                    "Please Scan & Repair your game, launch it for a minute, and try the tools again before reporting a bug!\n" +
                                    "========================");
                    throw;
                }

                //foreach (KeyValuePair<ushort, HashSet<ulong>> type in TrackedFiles.OrderBy(x => x.Key)) {
                //    //Console.Out.WriteLine($"Found type: {type.Key:X4} ({type.Value.Count} files)");
                //    Console.Out.WriteLine($"Found type: {type.Key:X4}");
                //}

                InitKeys();
                InitMisc();
            }

            var stopwatch = new Stopwatch();
            Logger.Info("Core", "Tooling...");
            stopwatch.Start();
            targetTool.Parse(targetToolFlags);
            stopwatch.Stop();

            Logger.Success("Core", $"Execution finished in {stopwatch.Elapsed} seconds");

            ShutdownMisc();
        }
Esempio n. 27
0
 public void Parse(ICLIFlags toolFlags)
 {
     ExtractVoiceSets(toolFlags);
 }
Esempio n. 28
0
 public void Parse(ICLIFlags toolFlags)
 {
     SaveMaps(toolFlags);
 }
Esempio n. 29
0
 public void Parse(ICLIFlags toolFlags)
 {
 }
Esempio n. 30
0
        public static void SaveTexture(ICLIFlags flags, string path, FindLogic.Combo.ComboInfo info, ulong textureGUID)
        {
            bool   convertTextures         = true;
            string convertType             = "tif";
            string multiSurfaceConvertType = "tif";
            bool   createMultiSurfaceSheet = false;
            bool   lossless = false;
            int    maxMips  = 1;

            if (flags is ExtractFlags extractFlags)
            {
                if (extractFlags.SkipTextures)
                {
                    return;
                }
                createMultiSurfaceSheet = extractFlags.SheetMultiSurface;
                convertTextures         = !extractFlags.RawTextures && !extractFlags.Raw;
                convertType             = extractFlags.ConvertTexturesType.ToLowerInvariant();
                lossless = extractFlags.ConvertTexturesLossless;

                multiSurfaceConvertType = convertType;
                if (extractFlags.ForceDDSMultiSurface)
                {
                    multiSurfaceConvertType = "dds";
                }

                if (convertType == "dds" && extractFlags.SaveMips)
                {
                    maxMips = 0xF;
                }
            }
            path += Path.DirectorySeparatorChar;

            FindLogic.Combo.TextureInfoNew textureInfo = info.Textures[textureGUID];
            string filePath = Path.Combine(path, $"{textureInfo.GetNameIndex()}");

            if (teResourceGUID.Type(textureGUID) != 0x4)
            {
                filePath += $".{teResourceGUID.Type(textureGUID):X3}";
            }

            if (Program.Flags.Deduplicate)
            {
                if (ScratchDBInstance.HasRecord(textureGUID))
                {
                    return;
                }
                ScratchDBInstance[textureGUID] = new ScratchDB.ScratchPath($"{filePath}.{convertType}");
            }

            CreateDirectoryFromFile(path);
            if (!convertTextures)
            {
                using (Stream textureStream = OpenFile(textureGUID)) {
                    teTexture texture = new teTexture(textureStream, true);
                    textureStream.Position = 0;
                    WriteFile(textureStream, $"{filePath}.004");

                    if (!texture.PayloadRequired)
                    {
                        return;
                    }
                    for (int i = 0; i < texture.Payloads.Length; ++i)
                    {
                        using (Stream texturePayloadStream = OpenFile(texture.GetPayloadGUID(textureGUID, i)))
                            WriteFile(texturePayloadStream, $"{filePath}_{i}.04D");
                    }
                }
            }
            else
            {
                using (Stream textureStream = OpenFile(textureGUID)) {
                    if (textureStream == null)
                    {
                        return;
                    }
                    teTexture texture = new teTexture(textureStream);

                    //if (texture.Header.Flags.HasFlag(teTexture.Flags.CUBEMAP)) return;
                    // for diffing when they add/regen loads of cubemaps

                    if (texture.PayloadRequired)
                    {
                        for (int i = 0; i < texture.Payloads.Length; ++i)
                        {
                            texture.LoadPayload(OpenFile(texture.GetPayloadGUID(textureGUID, i)), i);
                            if (maxMips == 1)
                            {
                                break;
                            }
                        }
                    }

                    uint?width    = null;
                    uint?height   = null;
                    uint?surfaces = null;
                    if (texture.Header.IsCubemap || texture.Header.IsArray || texture.HasMultipleSurfaces)
                    {
                        if (createMultiSurfaceSheet)
                        {
                            TankLib.Helpers.Logger.Debug("Combo", $"Saving {Path.GetFileName(filePath)} as a sheet because it has more than one surface");
                            height               = (uint)(texture.Header.Height * texture.Header.Surfaces);
                            surfaces             = 1;
                            texture.Header.Flags = 0;
                        }
                        else
                        {
                            TankLib.Helpers.Logger.Debug("Combo", $"Saving {Path.GetFileName(filePath)} as {multiSurfaceConvertType} because it has more than one surface");
                            convertType = multiSurfaceConvertType;
                        }
                    }

                    using (Stream convertedStream = texture.SaveToDDS(maxMips == 1 ? 1 : texture.Header.MipCount, width, height, surfaces)) {
                        convertedStream.Position = 0;
                        if (convertType == "dds" || convertedStream.Length == 0)
                        {
                            WriteFile(convertedStream, $"{filePath}.dds");
                            return;
                        }

                        bool isBcffValid = teTexture.DXGI_BC4.Contains(texture.Header.Format) ||
                                           teTexture.DXGI_BC5.Contains(texture.Header.Format) ||
                                           teTexture.ATI2.Contains(texture.Header.GetTextureType());

                        ImageFormat imageFormat = null;
                        if (convertType == "tif")
                        {
                            imageFormat = ImageFormat.Tiff;
                        }
                        if (convertType == "png")
                        {
                            imageFormat = ImageFormat.Png;
                        }
                        if (convertType == "jpg")
                        {
                            imageFormat = ImageFormat.Jpeg;
                        }
                        // if (convertType == "tga") imageFormat = Im.... oh
                        // so there is no TGA image format.
                        // guess the TGA users are stuck with the DirectXTex stuff for now.

                        if (isBcffValid && imageFormat != null && !(texture.Header.IsCubemap || texture.Header.IsArray || texture.HasMultipleSurfaces))
                        {
                            BlockDecompressor decompressor = new BlockDecompressor(convertedStream);
                            decompressor.CreateImage();
                            decompressor.Image.Save($"{filePath}.{convertType}", imageFormat);
                            return;
                        }

                        string losslessFlag = lossless ? "-wiclossless" : string.Empty;

                        Process pProcess = new Process {
                            StartInfo =
                            {
                                FileName               = "Third Party\\texconv.exe",
                                UseShellExecute        = false,
                                RedirectStandardOutput = true,
                                RedirectStandardInput  = true,
                                RedirectStandardError  = true,
                                CreateNoWindow         = true,
                                Arguments              =
                                    $"-- \"{Path.GetFileName(filePath)}.dds\" -y -wicmulti {losslessFlag} -nologo -m 1 -ft {convertType} -f R8G8B8A8_UNORM -o \"{(path.EndsWith(@"/") || path.EndsWith("\\") ? path.Substring(0, path.Length - 1) : path)}"
                            },
                            EnableRaisingEvents = true
                        };

                        pProcess.Start();
                        convertedStream.Position = 0;
                        convertedStream.CopyTo(pProcess.StandardInput.BaseStream);
                        pProcess.StandardInput.BaseStream.Flush();
                        pProcess.StandardInput.BaseStream.Close();
                        pProcess.WaitForExit();
                        // when texconv writes with to the console -nologo is has done/failed conversion
                        string line = pProcess.StandardOutput.ReadToEnd();
                        if (line.Contains("FAILED"))
                        {
                            convertedStream.Position = 0;
                            TankLib.Helpers.Logger.Debug("Combo", $"Saving {Path.GetFileName(filePath)} as dds because texconv failed.");
                            WriteFile(convertedStream, $"{filePath}.dds");
                        }
                    }
                }
            }
        }