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()); }
// 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 } } }
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)}"); } } }
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; } }
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}"); } } }
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++; } } } }
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); //} } }
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(); } }
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(); } } }
public static ISTU OpenSTUSafe(ulong key) { using (Stream stream = OpenFile(key)) { return(stream == null ? null : ISTU.NewInstance(stream, BuildVersion)); } }