Beispiel #1
0
        internal static STUInstance[] GetInstances(ulong guid, CASCHandler handler, Dictionary <ulong, Record> map)
        {
            Stream str = Util.OpenFile(map[guid], handler);
            ISTU   stu = ISTU.NewInstance(str, uint.MaxValue);

            return(stu.Instances.ToArray());
        }
Beispiel #2
0
 // Parse File
 static void DungeonsNDragons(string path, string output)
 {
     string filename = Path.GetFileNameWithoutExtension(path);
     string targetDir = Path.Combine(output, filename);
     Console.Out.WriteLine($"File: {path}; Target: {targetDir}");
     using (Stream stream = File.OpenRead(path))
     {
         try
         {
             ISTU stu = ISTU.NewInstance(stream, uint.MaxValue, null);
             if (!Directory.Exists(targetDir))
             {
                 Directory.CreateDirectory(targetDir);
             }
             for (int i = 0; i < stu.Instances.Count(); ++i)
             {
                 string target = Path.Combine(targetDir, $"{i}_{stu.Instances.ElementAt(i).InstanceChecksum}.json");
                 File.WriteAllText(target, JsonConvert.SerializeObject(stu.Instances.ElementAt(i) as object, Formatting.Indented));
             }
         }
         catch
         {
             // lol jk not a stu-nami
         }
     }
 }
Beispiel #3
0
        public void Parse(Dictionary <ushort, List <ulong> > track, Dictionary <ulong, Record> map, CASCHandler handler, bool quiet, OverToolFlags flags)
        {
            foreach (ulong key in track[0xD9])
            {
                if (!map.ContainsKey(key))
                {
                    continue;
                }
                using (Stream input = Util.OpenFile(map[key], handler)) {
                    if (input == null)
                    {
                        continue;
                    }
                    ISTU stu = ISTU.NewInstance(input, uint.MaxValue);
                    if (stu.Instances == null)
                    {
                        continue;
                    }
                    STUBrawlName bn = stu.Instances.First() as STUBrawlName;

                    // BrawlName bn = stud.Instances[0] as BrawlName;
                    if (bn == null)
                    {
                        continue;
                    }

                    Console.Out.WriteLine($"{key}: {Util.GetString(bn.Name, map, handler)}");
                }
            }
        }
Beispiel #4
0
            public void Parse(Stream input)
            {
                using (BinaryReader reader = new BinaryReader(input)) {
                    Header = reader.Read <ModelSTUHeader>();

                    reader.BaseStream.Position = Header.Offset;

                    MemoryStream stream = new MemoryStream();
                    CopyBytes(input, stream, (int)Header.Size);
                    stream.Position = 0;

                    StructuredData = ISTU.NewInstance(stream, BuildVersion).Instances.FirstOrDefault() as STUModel;
                }
            }
Beispiel #5
0
        public void Parse(Dictionary <ushort, List <ulong> > track, Dictionary <ulong, Record> map, CASCHandler handler, bool quiet, OverToolFlags flags)
        {
            foreach (ulong key in track[0x9E])
            {
                if (!map.ContainsKey(key))
                {
                    continue;
                }

                using (Stream input = Util.OpenFile(map[key], handler)) {
                    if (input == null)
                    {
                        continue;
                    }
                    ISTU stu = ISTU.NewInstance(input, uint.MaxValue);
                    if (stu.Instances == null)
                    {
                        continue;
                    }

                    STULoadout ability = stu.Instances.First() as STULoadout;
                    if (ability == null)
                    {
                        continue;
                    }

                    Console.Out.WriteLine(Util.GetString(ability.Name, map, handler));
                    if (ability.Category == STULib.Types.Enums.LoadoutCategory.Weapon)
                    {
                        Console.Out.WriteLine($"\t{ability.Category}: {ability.WeaponIndex}");
                    }
                    else
                    {
                        Console.Out.WriteLine($"\t{ability.Category}");
                    }
                    Console.Out.WriteLine($"\t{Util.GetString(ability.Description, map, handler)}");

                    // Console.Out.WriteLine($"{Util.GetString(achieve.Name, map, handler)}, {achieve.AbilityType}, {achieve.WeaponIndex}, {achieve.Unknown3}");
                }
            }
        }
Beispiel #6
0
        public Map(Stream input, uint owVersion, bool leaveOpen = false)
        {
            if (input == null)
            {
                return;
            }
            using (BinaryReader reader = new BinaryReader(input, Encoding.Default, leaveOpen)) {
                Header         = reader.Read <MapHeader>();
                input.Position = Header.offset;
                Records        = new IMapFormat[Header.recordCount];
                CommonHeaders  = new MapCommonHeader[Header.recordCount];
                for (uint i = 0; i < Header.recordCount; ++i)
                {
                    try {
                        CommonHeaders[i] = reader.Read <MapCommonHeader>();
                        long before = reader.BaseStream.Position;
                        long nps    = input.Position + CommonHeaders[i].size - 24;
                        if (Manager.InitializeInstance(CommonHeaders[i].type, input, out Records[i]) !=
                            MANAGER_ERROR.E_SUCCESS)
                        {
                            if (Debugger.IsAttached)
                            {
                                Debugger.Log(0, "STULib.Types.Map", $"[STULib.Types.Map.Map]: Error reading Map type {CommonHeaders[i].type:X} (offset: {before})\n");
                            }
                        }
                        input.Position = nps;
                    }
                    catch (OutOfMemoryException) {
                        CommonHeaders = null;
                        Records       = null;
                        return;
                    }
                    catch (ArgumentOutOfRangeException) {
                        CommonHeaders = null;
                        Records       = null;
                        return;
                    }
                }

                if (Records.Length > 0 && Records[0] != null && Records[0].HasSTUD)
                {
                    AlignPosition(input, input.Position);
                    while (true)
                    {
                        if (input.Position >= input.Length)
                        {
                            break;
                        }
                        ISTU tmp;
                        tmp = ISTU.NewInstance(input, owVersion);

                        AlignPositionNew(reader, tmp as Version1);
                        STUInstances = new HashSet <uint>(STUInstances.Concat(tmp.TypeHashes).ToList());
                        STUs.Add(tmp);
                    }
                }

                int stuIndex = 0;
                foreach (IMapFormat record in Records)
                {
                    if (record?.GetType() != typeof(MapEntity))
                    {
                        continue;
                    }

                    MapEntity mapEntity = (MapEntity)record;
                    mapEntity.STUContainers = new List <object>();
                    foreach (MapEntity.MapEntitySTUBinding binding in mapEntity.STUBindings)
                    {
                        mapEntity.STUContainers.Add(STUs[stuIndex]);
                        stuIndex++;
                    }
                }
            }
        }
Beispiel #7
0
        public void Parse(Dictionary <ushort, List <ulong> > track, Dictionary <ulong, Record> map, CASCHandler handler, bool quiet, OverToolFlags flags)
        {
            List <ulong> masters = track[0x9F];

            foreach (ulong key in masters)
            {
                if (!map.ContainsKey(key))
                {
                    continue;
                }
                ISTU stu = ISTU.NewInstance(Util.OpenFile(map[key], handler), uint.MaxValue);
                if (stu.Instances == null)
                {
                    continue;
                }
                STUMap mapSTU = stu.Instances.First() as STUMap;
                if (map == null)
                {
                    continue;
                }
//                Console.Out.WriteLine($"{key}");
//
//                if (mapSTU.StringDescriptionA != null) {
//                    Console.Out.WriteLine($"\tStringDescriptionA: {Util.GetString(mapSTU.StringDescriptionA, map, handler)}");
//                }
//                if (mapSTU.StringStateA != null) {
//                    Console.Out.WriteLine($"\tStringStateA: {Util.GetString(mapSTU.StringStateA, map, handler)}");
//                }
//                if (mapSTU.StringName != null) {
//                    Console.Out.WriteLine($"\tStringName: {Util.GetString(mapSTU.StringName, map, handler)}");
//                }
//                if (mapSTU.StringStateB != null) {
//                    Console.Out.WriteLine($"StringStateB: {Util.GetString(mapSTU.StringStateB, map, handler)}");
//                }
//                if (mapSTU.StringDescriptionB != null) {
//                    Console.Out.WriteLine($"\tStringDescriptionB: {Util.GetString(mapSTU.StringDescriptionB, map, handler)}");
//                }
//                if (mapSTU.StringSubline != null) {
//                    Console.Out.WriteLine($"\tStringSubline: {Util.GetString(mapSTU.StringSubline, map, handler)}");
//                }
//                if (mapSTU.StringNameB != null) {
//                    Console.Out.WriteLine($"\tStringNameB: {Util.GetString(mapSTU.StringNameB, map, handler)}");
//                }

                //string name = Util.GetString(map.Header.name.key, map, handler);
                //if (string.IsNullOrWhiteSpace(name)) {
                //    name = $"Unknown{GUID.Index(masterKey):X}";
                //}
                //Console.Out.WriteLine(name);
                //Console.Out.WriteLine("\tID: {0:X8}", GUID.Index(masterKey));

                //string subline = Util.GetString(map.Header.subline.key, map, handler);
                //if (subline == null) {
                //    subline = "";
                //}
                //if (map.Header.subline.key != map.Header.subline2.key && map.Header.subline2.key != 0) {
                //    subline += " " + Util.GetString(map.Header.subline2.key, map, handler);
                //}
                //subline = subline.Trim();
                //if (subline.Length > 0) {
                //    Console.Out.WriteLine("\tSubline: {0}", subline);
                //}

                //TryString("State", Util.GetString(map.Header.stateA.key, map, handler));
                //TryString("State", Util.GetString(map.Header.stateB.key, map, handler));

                //string description = Util.GetString(map.Header.description1.key, map, handler);
                //if (description == null) {
                //    description = "";
                //}
                //if (map.Header.description1.key != map.Header.description2.key && map.Header.description2.key != 0) {
                //    description += " " + Util.GetString(map.Header.description2.key, map, handler);
                //}
                //description = description.Trim();
                //if (description.Length > 0) {
                //    Console.Out.WriteLine("\tDescription: {0}", description);
                //}
            }
        }
Beispiel #8
0
        static void Main(string[] args)
        {
            Console.OutputEncoding = Encoding.UTF8;
            List <IOvertool> tools = new List <IOvertool>();

            {
                Assembly    asm   = typeof(IOvertool).Assembly;
                Type        t     = typeof(IOvertool);
                List <Type> types = asm.GetTypes().Where(tt => tt != t && t.IsAssignableFrom(tt)).ToList();
                foreach (Type tt in types)
                {
                    if (tt.IsInterface)
                    {
                        continue;
                    }
                    IOvertool toolinst = (IOvertool)Activator.CreateInstance(tt);
                    if (toolinst.Display)
                    {
                        tools.Add(toolinst);
                    }
                }
            }

            OverToolFlags flags = FlagParser.Parse <OverToolFlags>(() => PrintHelp(tools));

            if (flags == null)
            {
                return;
            }

            Logger.EXIT = !flags.GracefulExit;

            bool quiet = flags.Quiet;

            string root = flags.OverwatchDirectory;
            string opt  = flags.Mode;

            IOvertool tool = null;
            Dictionary <ushort, List <ulong> > track = new Dictionary <ushort, List <ulong> > {
                [0x90] = new List <ulong>() // internal requirements
            };

            toolsMap = new Dictionary <string, IOvertool>();
            foreach (IOvertool t in tools)
            {
                if (t.FullOpt == opt || (opt.Length == 1 && t.Opt != (char)0 && t.Opt == opt[0]))
                {
                    tool = t;
                }

                if (t.Track != null)
                {
                    foreach (ushort tr in t.Track)
                    {
                        if (!track.ContainsKey(tr))
                        {
                            track[tr] = new List <ulong>();
                        }
                    }
                }

                if (toolsMap.ContainsKey(t.FullOpt))
                {
                    Console.Out.WriteLine("Duplicate opt! {0} conflicts with {1}", t.Title, toolsMap[t.FullOpt].Title);
                }
                if (t.FullOpt.Length == 1)
                {
                    Console.Out.WriteLine("FullOpt should not be length 1 for {0}", t.Title);
                }
                toolsMap[t.FullOpt] = t;
            }
            if (tool == null || flags.Positionals.Length - 2 < tool.MinimumArgs)
            {
                PrintHelp(tools);
                return;
            }

            Dictionary <ulong, Record> map = new Dictionary <ulong, Record>();

            Console.Out.WriteLine("{0} v{1}", Assembly.GetExecutingAssembly().GetName().Name, OWLib.Util.GetVersion());
            Console.Out.WriteLine("Initializing CASC...");
            Console.Out.WriteLine("Set language to {0}", flags.Language);
            CDNIndexHandler.Cache.Enabled   = flags.UseCache;
            CDNIndexHandler.Cache.CacheData = flags.CacheData;
            CDNIndexHandler.Cache.Validate  = flags.ValidateCache;
            CASCConfig config = null;

            // ngdp:us:pro
            // http:us:pro:us.patch.battle.net:1119
            if (root.ToLowerInvariant().Substring(0, 5) == "ngdp:")
            {
                string   cdn     = root.Substring(5, 4);
                string[] parts   = root.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(root, !flags.SkipKeys, false);
            }
            config.Languages = new HashSet <string>(new string[1] {
                flags.Language
            });

            if (flags.SkipKeys)
            {
                Console.Out.WriteLine("Disabling Key auto-detection...");
            }

            Regex versionRegex = new Regex(@"\d+\.\d+");
            Match versionMatch = versionRegex.Match(config.BuildName);

            if (versionMatch.Success)
            {
                float version = float.Parse(versionMatch.Value);

                if (version > 1.13)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.Out.WriteLine("==========\nWARNING: Overtool only works with Overwatch version 1.13 and below! You are using {0}!", config.BuildName);
                    Console.Out.WriteLine("You must use DataTool for Overwatch 1.14 and above!\n==========");
                    Console.ResetColor();
                }
            }

            Console.Out.WriteLine("Using Overwatch Version {0}", config.BuildName);
            CASCHandler   handler = CASCHandler.OpenStorage(config);
            OwRootHandler ow      = handler.Root as OwRootHandler;

            if (ow == null)
            {
                Console.Error.WriteLine("Not a valid overwatch installation");
                return;
            }

            // Fail when trying to extract data from a specified language with 2 or less files found.
            if (ow.APMFiles.Count() == 0)
            {
                Console.Error.WriteLine("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;
                }
            }

            Console.Out.WriteLine("Mapping...");
            Util.MapCMF(ow, handler, map, track, flags.Language);

            if (!flags.SkipKeys)
            {
                Console.Out.WriteLine("Adding Encryption Keys...");

                foreach (ulong key in track[0x90])
                {
                    if (!map.ContainsKey(key))
                    {
                        continue;
                    }
                    using (Stream stream = Util.OpenFile(map[key], handler)) {
                        if (stream == null)
                        {
                            continue;
                        }
                        ISTU stu = ISTU.NewInstance(stream, UInt32.Parse(config.BuildName.Split('.').Last()));
                        if (!(stu.Instances.FirstOrDefault() is STUEncryptionKey))
                        {
                            continue;
                        }
                        STUEncryptionKey ek = stu.Instances.FirstOrDefault() as STUEncryptionKey;
                        if (ek != null && !KeyService.keys.ContainsKey(ek.LongRevKey))
                        {
                            KeyService.keys.Add(ek.LongRevKey, ek.KeyValue);
                            Console.Out.WriteLine("Added Encryption Key {0}, Value: {1}", ek.KeyNameProper, ek.Key);
                        }
                    }
                }
            }

            Console.Out.WriteLine("Tooling...");

            tool.Parse(track, map, handler, quiet, flags);
            if (System.Diagnostics.Debugger.IsAttached)
            {
                System.Diagnostics.Debugger.Break();
            }
        }
Beispiel #9
0
        public static void ListSTU(Stream file)
        {
            using (BinaryReader reader = new BinaryReader(file)) {
                STUHeader header = reader.Read <STUHeader>();

                Util.DumpStruct(header, "");
                Console.Out.WriteLine("{0} instances", header.InstanceCount);
                file.Position = header.InstanceListOffset;
                long totalSize = 0;
                for (uint i = 0; i < header.InstanceCount; ++i)
                {
                    STUInstanceRecord record = reader.Read <STUInstanceRecord>();
                    Console.Out.WriteLine("\t{0:X8} - {1:X8} - {2} - {3} bytes", record.InstanceChecksum, record.AssignFieldChecksum, record.AssignInstanceIndex, record.InstanceSize - 4);
                    long position = file.Position;
                    file.Position = header.Offset + totalSize;
                    int listIndex = reader.ReadInt32();
                    if (listIndex > -1 && (uint)listIndex >= header.InstanceFieldListCount)
                    {
                        throw new Exception();
                    }
                    Console.Out.WriteLine("\t\tfield list index {0:X}", listIndex);
                    file.Position = position;
                    totalSize    += record.InstanceSize;
                }
                Console.Out.WriteLine("Total: {0} bytes", totalSize);
                if (header.EntryInstanceCount > 0)
                {
                    Console.Out.WriteLine("{0} reference entries", header.EntryInstanceCount);
                    file.Position = header.EntryInstanceListOffset;
                    for (int i = (int)header.EntryInstanceCount; i > 0; --i)
                    {
                        STUInstanceField entry = reader.Read <STUInstanceField>();
                        Console.Out.WriteLine("\t\t{0:X8} - {1} bytes", entry.FieldChecksum, entry.FieldSize);
                    }
                }
                Console.Out.WriteLine("{0} variable lists", header.InstanceFieldListCount);
                file.Position = header.InstanceFieldListOffset;
                for (uint i = 0; i < header.InstanceFieldListCount; ++i)
                {
                    STUInstanceFieldList info = reader.Read <STUInstanceFieldList>();
                    Console.Out.WriteLine("\t{0} variables", info.FieldCount);
                    long tmp = file.Position;
                    file.Position = info.ListOffset;
                    totalSize     = 0;
                    for (uint j = 0; j < info.FieldCount; ++j)
                    {
                        STUInstanceField entry = reader.Read <STUInstanceField>();
                        Console.Out.WriteLine("\t\t{0:X8} - {1} bytes", entry.FieldChecksum, entry.FieldSize);
                        totalSize += entry.FieldSize;
                    }
                    Console.Out.WriteLine("\t\tTotal: {0} bytes", totalSize);
                    file.Position = tmp;
                }

                if (System.Diagnostics.Debugger.IsAttached)
                {
                    file.Position = 0;
                    ISTU stu = ISTU.NewInstance(file, uint.MaxValue);
                    System.Diagnostics.Debugger.Break();
                }
            }
        }
Beispiel #10
0
 public static ISTU OpenSTUSafe(ulong key)
 {
     using (Stream stream = OpenFile(key)) {
         return(stream == null ? null : ISTU.NewInstance(stream, BuildVersion));
     }
 }