public static HashSet <string> GetGUIDs(ISTU stu) { HashSet <string> guids = new HashSet <string>(); IEnumerable <Common.STUInstance> instances = stu.Instances; if (stu.GetType() == typeof(Version2)) { instances = instances.Concat(((Version2)stu).HiddenInstances); } foreach (Common.STUInstance instance in instances) { // this means all instances, we don't need to recurse if (instance == null) { continue; } FieldInfo[] fields = GetFields(instance.GetType(), true); foreach (FieldInfo field in fields) { object fieldValue = field.GetValue(instance); if (fieldValue == null) { continue; } if (field.FieldType == typeof(Common.STUGUID[])) { foreach (Common.STUGUID guid in (Common.STUGUID[])fieldValue) { guids.Add(IO.GetFileName(guid)); } } if (field.FieldType == typeof(Common.STUGUID)) { guids.Add(IO.GetFileName(fieldValue as Common.STUGUID)); } // tbh I haven't seen any ulong that isn't a guid yet if (field.FieldType == typeof(ulong)) { if (GUID.Type((ulong)fieldValue) > 1) { guids.Add(IO.GetFileName(new Common.STUGUID((ulong)fieldValue))); } } if (field.FieldType == typeof(ulong[])) { foreach (ulong guid in (ulong[])fieldValue) { if (GUID.Type(guid) > 1) { guids.Add(IO.GetFileName(new Common.STUGUID(guid))); } } } } } return(guids); }
public void DumpSTU(ISTU stu, string instanceWildcard) { IndentHelper indentHelper = new IndentHelper(); int index = 0; Console.Out.WriteLine($"Instances: [array] Count={stu.Instances.Count()}"); foreach (STUInstance instance in stu.Instances) { if (instance == null) { index++; continue; } if (instance.Usage != InstanceUsage.Root) { index++; continue; } string[] instanceChecksums = instance.GetType().GetCustomAttributes <STUAttribute>().Select(x => Convert.ToString(x.Checksum, 16)).ToArray(); if (instanceWildcard != null && !instanceChecksums.Any(x => string.Equals(x, instanceWildcard.TrimStart('0'), StringComparison.InvariantCultureIgnoreCase))) { continue; } Console.Out.WriteLine($"{indentHelper + 1}[{index}]: [{instance.GetType().Name}]"); Console.Out.WriteLine(DumpInstance(instance, indentHelper + 2, new List <object>())); index++; } }
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()); }
public static void Main(string[] args) { InputDirectory = args[0]; OutputDirectory = args[1]; CreateDirectory(OutputDirectory); CleanDirectory(OutputDirectory); Dictionary <uint, STUInstanceJSON> instanceJson = STUHashTool.Program.LoadInstanceJson("RegisteredSTUTypes.json"); STUHashTool.Program.LoadHashCSV("KnownFields.csv", out FieldNames); STUHashTool.Program.LoadHashCSV("KnownTypes.csv", out InstanceNames); STUHashTool.Program.LoadHashCSV("KnownEnums.csv", out EnumNames); Version2Comparer.InstanceJSON = instanceJson; ISTU.LoadInstanceTypes(); InvalidTypes = STUHashTool.Program.LoadInvalidTypes("IgnoredBrokenSTUs.txt"); // fix existing classes FixClasses(); // add any classes that don't exist AddNewClasses(instanceJson); }
// 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 static T[] GetAllInstances <T>(ulong key) where T : STUInstance { ISTU stu = OpenSTUSafe(key); Version2 ver2 = stu as Version2; if (ver2 == null) { return(null); } return(stu?.Instances.Concat(ver2.HiddenInstances).OfType <T>().ToArray() ?? new T[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; } }
public object Deserialize(object instace, ISTU stu, FieldInfo field, BinaryReader reader, BinaryReader metadataReader) { int offset = reader.ReadInt32(); if (offset == -1) { return(null); } metadataReader.BaseStream.Position = offset; STUHashMapData data = metadataReader.Read <STUHashMapData>(); if (data.Unknown2Size == 0) { return(null); } metadataReader.BaseStream.Position = data.Unknown2Offset; List <uint> unknown2 = new List <uint>(data.Unknown2Size); for (int i = 0; i != data.Unknown2Size; ++i) { unknown2.Add(metadataReader.ReadUInt32()); } metadataReader.BaseStream.Position = data.DataOffset; uint mapSize = unknown2.Last(); for (int i = 0; i != mapSize; ++i) { ulong key = metadataReader.ReadUInt64(); // Last 4 bytes are padding for in-place deserialization. int value = (int)metadataReader.ReadUInt64(); if (value == -1) { Add(key, null); } else { // get instance later stu.HashmapRequests.Add(new KeyValuePair <KeyValuePair <Type, object>, KeyValuePair <uint, ulong> >(new KeyValuePair <Type, object>(typeof(T), this), new KeyValuePair <uint, ulong>((uint)value, key))); } } return(this); }
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 void Write(Stream output, STULib.Types.Map.Map map, STULib.Types.Map.Map detail1, STULib.Types.Map.Map detail2, STULib.Types.Map.Map entities, STULib.Types.Map.Map lights, string name, IDataWriter modelFormat, FindLogic.Combo.ComboInfo info) { if (modelFormat == null) { modelFormat = new OWMDLWriter(); } using (BinaryWriter writer = new BinaryWriter(output)) { writer.Write((ushort)1); // version major writer.Write((ushort)1); // version minor if (name.Length == 0) { writer.Write((byte)0); } else { writer.Write(name); } uint size = 0; foreach (IMapFormat t in map.Records) { if (t != null && t.GetType() != typeof(Map01)) { continue; } size++; } writer.Write(size); // nr objects size = 1; foreach (IMapFormat t in detail1.Records) { if (t != null && t.GetType() != typeof(Map02)) { continue; } size++; } foreach (IMapFormat t in detail2.Records) { if (t != null && t.GetType() != typeof(Map08)) { continue; } size++; } foreach (IMapFormat t in entities.Records) { if (t != null && t.GetType() != typeof(MapEntity)) { continue; } if (((MapEntity)t).Model == 0) { continue; } size++; } writer.Write(size); // nr details // Extension 1.1 - Lights size = 0; foreach (IMapFormat t in lights.Records) { if (t != null && t.GetType() != typeof(Map09)) { continue; } size++; } writer.Write(size); // nr Lights foreach (IMapFormat t in map.Records) { if (t != null && t.GetType() != typeof(Map01)) { continue; } Map01 obj = (Map01)t; FindLogic.Combo.Find(info, obj.Header.Model); FindLogic.Combo.ModelInfoNew modelInfo = info.Models[obj.Header.Model]; string modelFn = $"Models\\{modelInfo.GetName()}\\{modelInfo.GetNameIndex()}{modelFormat.Format}"; writer.Write(modelFn); writer.Write(obj.Header.groupCount); for (int j = 0; j < obj.Header.groupCount; ++j) { Map01.Map01Group group = obj.Groups[j]; FindLogic.Combo.Find(info, group.ModelLook, null, new FindLogic.Combo.ComboContext { Model = obj.Header.Model }); string materialFn; if (!info.ModelLooks.ContainsKey(group.ModelLook)) { materialFn = ""; // encrypted } else { FindLogic.Combo.ModelLookInfo modelLookInfo = info.ModelLooks[group.ModelLook]; materialFn = $"Models\\{modelInfo.GetName()}\\ModelLooks\\{modelLookInfo.GetNameIndex()}.owmat"; } writer.Write(materialFn); writer.Write(group.recordCount); for (int k = 0; k < group.recordCount; ++k) { Map01.Map01GroupRecord record = obj.Records[j][k]; writer.Write(record.position.x); writer.Write(record.position.y); writer.Write(record.position.z); writer.Write(record.scale.x); writer.Write(record.scale.y); writer.Write(record.scale.z); writer.Write(record.rotation.x); writer.Write(record.rotation.y); writer.Write(record.rotation.z); writer.Write(record.rotation.w); } } } // todo: broken? writer.Write($"Models\\physics\\physics.{modelFormat.Format}"); writer.Write((byte)0); writer.Write(0.0f); writer.Write(0.0f); writer.Write(0.0f); writer.Write(1.0f); writer.Write(1.0f); writer.Write(1.0f); writer.Write(0.0f); writer.Write(0.0f); writer.Write(0.0f); writer.Write(1.0f); foreach (IMapFormat t in detail1.Records) { if (t != null && t.GetType() != typeof(Map02)) { continue; } Map02 obj = (Map02)t; FindLogic.Combo.Find(info, obj.Header.Model); FindLogic.Combo.Find(info, obj.Header.ModelLook, null, new FindLogic.Combo.ComboContext { Model = obj.Header.Model }); FindLogic.Combo.ModelInfoNew modelInfo = info.Models[obj.Header.Model]; FindLogic.Combo.ModelLookInfo modelLookInfo = info.ModelLooks[obj.Header.ModelLook]; string modelFn = $"Models\\{modelInfo.GetName()}\\{modelInfo.GetNameIndex()}{modelFormat.Format}"; string matFn = $"Models\\{modelInfo.GetName()}\\ModelLooks\\{modelLookInfo.GetNameIndex()}.owmat"; writer.Write(modelFn); writer.Write(matFn); writer.Write(obj.Header.position.x); writer.Write(obj.Header.position.y); writer.Write(obj.Header.position.z); writer.Write(obj.Header.scale.x); writer.Write(obj.Header.scale.y); writer.Write(obj.Header.scale.z); writer.Write(obj.Header.rotation.x); writer.Write(obj.Header.rotation.y); writer.Write(obj.Header.rotation.z); writer.Write(obj.Header.rotation.w); } foreach (IMapFormat t in detail2.Records) { if (t != null && t.GetType() != typeof(Map08)) { continue; } Map08 obj = (Map08)t; FindLogic.Combo.Find(info, obj.Header.Model); FindLogic.Combo.Find(info, obj.Header.ModelLook, null, new FindLogic.Combo.ComboContext { Model = obj.Header.Model }); FindLogic.Combo.ModelInfoNew modelInfo = info.Models[obj.Header.Model]; FindLogic.Combo.ModelLookInfo modelLookInfo = info.ModelLooks[obj.Header.ModelLook]; string modelFn = $"Models\\{modelInfo.GetName()}\\{modelInfo.GetNameIndex()}{modelFormat.Format}"; string matFn = $"Models\\{modelInfo.GetName()}\\ModelLooks\\{modelLookInfo.GetNameIndex()}.owmat"; writer.Write(modelFn); writer.Write(matFn); writer.Write(obj.Header.position.x); writer.Write(obj.Header.position.y); writer.Write(obj.Header.position.z); writer.Write(obj.Header.scale.x); writer.Write(obj.Header.scale.y); writer.Write(obj.Header.scale.z); writer.Write(obj.Header.rotation.x); writer.Write(obj.Header.rotation.y); writer.Write(obj.Header.rotation.z); writer.Write(obj.Header.rotation.w); } foreach (IMapFormat t in entities.Records) { if (t != null && t.GetType() != typeof(MapEntity)) { continue; } MapEntity mapEntity = (MapEntity)t; if (mapEntity.Model == 0) { continue; } ulong modelLook = mapEntity.ModelLook; foreach (object container in mapEntity.STUContainers) { ISTU realContainer = (ISTU)container; foreach (Common.STUInstance instance in realContainer.Instances) { if (instance is STUModelComponentInstanceData modelComponentInstanceData) { if (modelComponentInstanceData.Look != 0) { modelLook = modelComponentInstanceData.Look; } } } } FindLogic.Combo.Find(info, mapEntity.Model); FindLogic.Combo.Find(info, modelLook, null, new FindLogic.Combo.ComboContext { Model = mapEntity.Model }); FindLogic.Combo.ModelInfoNew modelInfo = info.Models[mapEntity.Model]; string matFn = ""; if (info.ModelLooks.ContainsKey(modelLook)) { FindLogic.Combo.ModelLookInfo modelLookInfo = info.ModelLooks[modelLook]; matFn = $"Models\\{modelInfo.GetName()}\\ModelLooks\\{modelLookInfo.GetNameIndex()}.owmat"; } string modelFn = $"Models\\{modelInfo.GetName()}\\{modelInfo.GetNameIndex()}{modelFormat.Format}"; writer.Write(modelFn); writer.Write(matFn); writer.Write(mapEntity.Header.Position.x); writer.Write(mapEntity.Header.Position.y); writer.Write(mapEntity.Header.Position.z); writer.Write(mapEntity.Header.Scale.x); writer.Write(mapEntity.Header.Scale.y); writer.Write(mapEntity.Header.Scale.z); writer.Write(mapEntity.Header.Rotation.x); writer.Write(mapEntity.Header.Rotation.y); writer.Write(mapEntity.Header.Rotation.z); writer.Write(mapEntity.Header.Rotation.w); } // Extension 1.1 - Lights foreach (IMapFormat t in lights.Records) { if (t != null && t.GetType() != typeof(Map09)) { continue; } Map09 obj = (Map09)t; writer.Write(obj.Header.position.x); writer.Write(obj.Header.position.y); writer.Write(obj.Header.position.z); writer.Write(obj.Header.rotation.x); writer.Write(obj.Header.rotation.y); writer.Write(obj.Header.rotation.z); writer.Write(obj.Header.rotation.w); writer.Write(obj.Header.LightType); writer.Write(obj.Header.LightFOV); writer.Write(obj.Header.Color.x); writer.Write(obj.Header.Color.y); writer.Write(obj.Header.Color.z); writer.Write(obj.Header.unknown1A); writer.Write(obj.Header.unknown1B); writer.Write(obj.Header.unknown2A); writer.Write(obj.Header.unknown2B); writer.Write(obj.Header.unknown2C); writer.Write(obj.Header.unknown2D); writer.Write(obj.Header.unknown3A); writer.Write(obj.Header.unknown3B); writer.Write(obj.Header.unknownPos1.x); writer.Write(obj.Header.unknownPos1.y); writer.Write(obj.Header.unknownPos1.z); writer.Write(obj.Header.unknownQuat1.x); writer.Write(obj.Header.unknownQuat1.y); writer.Write(obj.Header.unknownQuat1.z); writer.Write(obj.Header.unknownQuat1.w); writer.Write(obj.Header.unknownPos2.x); writer.Write(obj.Header.unknownPos2.y); writer.Write(obj.Header.unknownPos2.z); writer.Write(obj.Header.unknownQuat2.x); writer.Write(obj.Header.unknownQuat2.y); writer.Write(obj.Header.unknownQuat2.z); writer.Write(obj.Header.unknownQuat2.w); writer.Write(obj.Header.unknownPos3.x); writer.Write(obj.Header.unknownPos3.y); writer.Write(obj.Header.unknownPos3.z); writer.Write(obj.Header.unknownQuat3.x); writer.Write(obj.Header.unknownQuat3.y); writer.Write(obj.Header.unknownQuat3.z); writer.Write(obj.Header.unknownQuat3.w); writer.Write(obj.Header.unknown4A); writer.Write(obj.Header.unknown4B); writer.Write(obj.Header.unknown5); writer.Write(obj.Header.unknown6A); writer.Write(obj.Header.unknown6B); writer.Write(obj.Header.unknown7A); writer.Write(obj.Header.unknown7B); } } }
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(); } }
// dawn of a new project // STUExcavator: // go through all stu files and find GUIDs // future possibilities: // STUv1 excavation: // find padding, then try for guid public static void Main(string[] args) { string overwatchDir = args[0]; string outputDir = args[1]; const string language = "enUS"; // casc setup Config = CASCConfig.LoadLocalStorageConfig(overwatchDir, false, false); Config.Languages = new HashSet <string> { language }; CASC = CASCHandler.OpenStorage(Config); DataTool.Program.Files = new Dictionary <ulong, MD5Hash>(); DataTool.Program.TrackedFiles = new Dictionary <ushort, HashSet <ulong> >(); DataTool.Program.CASC = CASC; DataTool.Program.Root = CASC.Root as OwRootHandler; DataTool.Program.Flags = new ToolFlags { OverwatchDirectory = outputDir, Language = language }; IO.MapCMF(true); Files = DataTool.Program.Files; TrackedFiles = DataTool.Program.TrackedFiles; // prepare Version2Comparer Version2Comparer.InstanceJSON = STUHashTool.Program.LoadInstanceJson("RegisteredSTUTypes.json"); InvalidTypes = STUHashTool.Program.LoadInvalidTypes("IgnoredBrokenSTUs.txt"); // wipe ISTU ISTU.Clear(); // actual tool Dictionary <string, AssetTypeSummary> types = new Dictionary <string, AssetTypeSummary>(); CompileSTUs(); foreach (KeyValuePair <ushort, HashSet <ulong> > keyValuePair in TrackedFiles.OrderBy(x => x.Key)) { string type = keyValuePair.Key.ToString("X3"); if (type == "09C" || type == "062" || type == "077") { continue; } Log($"Processing type: {type}"); types[type] = Excavate(keyValuePair.Key, keyValuePair.Value); IO.CreateDirectoryFromFile(Path.Combine(outputDir, type, "master.json")); using (Stream masterFile = File.OpenWrite(Path.Combine(outputDir, type, "master.json"))) { masterFile.SetLength(0); string masterJson = JsonConvert.SerializeObject(types[type], Formatting.Indented); using (TextWriter writer = new StreamWriter(masterFile)) { writer.WriteLine(masterJson); } } if (types[type].Assets == null) { continue; } foreach (Asset asset in types[type].Assets) { string assetFile = Path.Combine(outputDir, type, "assets", $"{asset.GUID}.json"); IO.CreateDirectoryFromFile(assetFile); using (Stream assetStream = File.OpenWrite(assetFile)) { assetStream.SetLength(0); string assetJson = JsonConvert.SerializeObject(asset, Formatting.Indented); using (TextWriter writer = new StreamWriter(assetStream)) { writer.WriteLine(assetJson); } } } } }
public static T GetInstance <T>(ulong key) where T : STUInstance { ISTU stu = OpenSTUSafe(key); return(stu?.Instances.OfType <T>().FirstOrDefault()); }
public object Deserialize(object instance, ISTU stu, FieldInfo field, BinaryReader reader, BinaryReader metadataReader) { Value = new Guid(reader.ReadBytes(16)); return(this); }
// Version 2.0 prefix //[STUField(STUVersionOnly = new uint[] {2})] //public uint FieldListIndex; public override string ToString() { return(ISTU.GetName(GetType())); }
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(); } } }
/*INPUT FILES : * BASIC DOMAIN INFORMATION GRAMM.geb * MAIN CONTROL PARAM FILEs iin.dat or IIN.dat * GEOMETRY DATA ggeom.asc * LANDUSE DATA landuse.asc * METEOROLOGICAL DATA meteopgt.all * MAX. NUMBER OF CPUs Max_Proc.txt */ static void Main(string[] args) { // Arguments: "First Situation" "Final Situation" "Max. Time Step" "RelaxV" "RelaxT" // if "First Situation" = "?" -> print Info & Stop int p = (int)Environment.OSVersion.Platform; if ((p == 4) || (p == 6) || (p == 128)) { //Console.WriteLine ("Running on Unix"); unix = true; } else { //Console.WriteLine ("NOT running on Unix"); } //WRITE GRAMM VERSION INFORMATION TO SCREEN Console.WriteLine(""); Console.WriteLine("+------------------------------------------------------+"); Console.WriteLine("| |"); string Info = "+ > > G R A M M VERSION: 20.09 < < +"; Console.WriteLine(Info); if (unix) { Console.WriteLine("| L I N U X |"); } #if NETCOREAPP2_1 || NETCOREAPP2_0 || NETCOREAPP3_0 Console.WriteLine("| .Net Core Version |"); #endif Console.WriteLine("+------------------------------------------------------+"); Console.WriteLine(" "); //show licence terms ShowCopyright(args); // 11.04.17 Ku use arguments Console_Arguments(args); //User defined decimal seperator decsep = NumberFormatInfo.CurrentInfo.NumberDecimalSeparator; //read number of grid cells stored in the file "GRAMM.geb" Read_Gramm_Geb(); //check if chemistry is envoked if (File.Exists("chemistry.txt")) { Read_Chemistry(); //@Johannes: at this place call the chemical mechanism, that feeds back the number of spezies to be computed } // Write to "Logfile_GRAMMCore" try { ProgramWriters.LogfileGrammCoreWrite(new String('-', 80)); ProgramWriters.LogfileGrammCoreWrite(Info); ProgramWriters.LogfileGrammCoreWrite("Computation started at: " + DateTime.Now.ToString()); ProgramWriters.LogfileGrammCoreWrite("Computation folder: " + Directory.GetCurrentDirectory()); Info = "Application hash code: " + GetAppHashCode(); ProgramWriters.LogfileGrammCoreWrite(Info); } catch { } //Allocate Memory -> Define Arrays Define_Arrays(); List <int>[] Month_List = new List <int> [3]; // 3 types of month lists Month_List[0] = new List <int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; Month_List[1] = new List <int>() { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2 }; Month_List[2] = new List <int>() { 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5 }; if (NX * NY < 50 * 50) { TerminalThreshold = 12; } else if (NX * NY < 200 * 200) { TerminalThreshold = 6; } else { TerminalThreshold = 1; } Console.WriteLine("."); //END OF VARIABLE DECLARATION BLOCK //SET NUMBER OF FLOW FIELD SITUATION TO ZERO IWETTER = 0; //OPEN THE MAIN CONTROL FILE "IIN.dat" Read_IIN_Dat(); //read k-epsilon constant Read_TURB_Dat(); //When using ERA5 data GRAMM automatically starts with a number for the weather situation based on the existing *wnd files if (ISTAT >= 2) { string wdir = Directory.GetCurrentDirectory(); DirectoryInfo d = new DirectoryInfo(wdir); FileInfo[] Files = d.GetFiles("*.wnd"); IWETTER = Files.Length; } //Total simulation time DTI = TLIMIT2; DTMAX = DT; max_time_step_original = DTMAX; if (MaxTimeStep_Console > 0.99) { max_time_step_original = MaxTimeStep_Console; } if (Relaxv_Console > 0.0099) { RELAXV = Relaxv_Console; } if (Relaxt_Console > 0.0099) { RELAXT = Relaxt_Console; } // Read number of max. used processors IPROC = 1; Max_Proc_File_Read(); //Convert relative humidity in % QUINIT *= 0.01; //Get year, month, day, hour, and minute of the simulation start if (NDATUM.ToString().Length == 8) { IJAHR4digits = Convert.ToInt32(Math.Floor(NDATUM / 10000d)); IJAHR = IJAHR4digits - Convert.ToInt32(Math.Floor(IJAHR4digits / 100d)) * 100; IMON = Convert.ToInt32(Math.Floor(NDATUM / 100d)) - IJAHR4digits * 100; ITAG = NDATUM - IJAHR4digits * 10000 - IMON * 100; } else { IJAHR = Convert.ToInt32(Math.Floor(NDATUM / 10000d)); IJAHR4digits = IJAHR; IMON = Convert.ToInt32(Math.Floor(NDATUM / 100d)) - IJAHR * 100; ITAG = NDATUM - IJAHR * 10000 - IMON * 100; } ISTU = Convert.ToInt32(Math.Floor(ISTUNDE / 100d)); IMIN = ISTUNDE - 100 * ISTU; //Set flags for various compuation options ICU = false; ICV = false; ICW = false; ICPN = false; ICT = false; ICPH = false; IFOU = false; ICQU = false; ICPSI = false; ICTE = false; ICSTR = false; ICPR = false; ICBR = false; ICTB = false; ICGW = false; Int32 INUMM = 0; if (IFLAGS1 / 1000000 == 1) { ICU = true; } if (ICU) { INUMM += 1000000; } if ((IFLAGS1 - INUMM + 1) / 100000 == 1) { ICV = true; } if (ICV) { INUMM += 100000; } if ((IFLAGS1 - INUMM + 1) / 10000 == 1) { ICW = true; } if (ICW) { INUMM += 10000; } if ((IFLAGS1 - INUMM + 1) / 1000 == 1) { ICPN = true; } if (ICPN) { INUMM += 1000; } if ((IFLAGS1 - INUMM + 1) / 100 == 1) { ICT = true; } if (ICT) { INUMM += 100; } if ((IFLAGS1 - INUMM + 1) / 10 == 1) { ICGW = true; } if (ICGW) { INUMM += 10; } if ((IFLAGS1 - INUMM) == 1) { IFOU = true; } INUMM = 0; if (IFLAGS2 / 1000000 == 1) { ICBR = true; } if (ICBR) { INUMM += 1000000; } if ((IFLAGS2 - INUMM + 1) / 100000 == 1) { ICPR = true; } if (ICPR) { INUMM += 100000; } if ((IFLAGS2 - INUMM + 1) / 10000 == 1) { ICQU = true; } if (ICQU) { INUMM += 10000; } if ((IFLAGS2 - INUMM + 1) / 1000 == 1) { ICPSI = true; } if (ICPSI) { INUMM += 1000; } if ((IFLAGS2 - INUMM + 1) / 100 == 1) { ICTE = true; } if (ICTE) { INUMM += 100; } if ((IFLAGS2 - INUMM + 1) / 10 == 1) { ICTB = true; } if (ICTB) { INUMM += 10; } if ((IFLAGS2 - INUMM) == 1) { ICSTR = true; } //COMPUTE MODEL GRID Console.WriteLine(" *** GENERATING MODEL GRID *** "); GEOM(); //INQUIRE IF RECEPTOR POINTS ARE SET Read_Receptor_Dat(); //INQUIRE IF PROBE POINTS ARE SET Read_Probes_Dat(); //Analyze_Topography(); // find U valleys and bassins Relaxv_ori = RELAXV; Relaxt_ori = RELAXT; Relax_Border_factor[0][0] = -4; // flag, that factor must be computed ProgramWriters.LogfileGrammCoreInfo(); // init radiation model RadiationModel = new RadiationCalculation(); //Loop_______________________________________________________________________________________________ NEXTWEATHERSITUATION: clear_arrays(); //INITIALIZE FIELDS Console.WriteLine(); Console.WriteLine(); Console.WriteLine(" *** INITIALIZATION *** "); INITA(NX, NY, NZ); Int32 ISTUD = Convert.ToInt32(Math.Floor(TLIMIT / 3600d)); double AMIND = (TLIMIT / 3600 - (float)ISTUD) * 60; Int32 IMIND = Convert.ToInt32(Math.Floor(AMIND)); double ASECD = (AMIND - (float)IMIND) * 60; Int32 ISECD = Convert.ToInt32(Math.Floor(ASECD)); if (ISTAT == 0) { Intermed_Threshold = IOUTPUT / 2; // 1st intermediate output after IOUTPUT / 2 (default 1800 s) for SC 5, 6 and SC 7 if (AKLA < 5) { Intermed_Threshold = IOUTPUT; // 1st intermediate output after IOUTPUT s } } else { Intermed_Threshold = IOUTPUT; } int Radiation_Threshold = 1800; // compute new radiation each 1800 s //set further initial values if (ISTAT < 2) { INITB.INIT(NX, NY, NZ); } Relax_Border(); // set reduction factors for the border cells //initialize the radiation model if (((METEO != "Y") && (METEO != "y")) || (Program.ISTAT != 0)) { TLIMIT = TLIMIT2; } Boolean LGEOM = false; Boolean LGEOMW = false; Boolean LGEOMR = false; INIT_Radiation(ref LGEOM, ref LGEOMW, ref LGEOMR, ref ISTUD, ref AMIND, ref IMIND, ref ASECD, ref ISECD, Month_List); Console.WriteLine(ITAG.ToString() + "." + IMON.ToString() + " - " + ISTU.ToString() + ":" + IMIND.ToString("D2")); REALTIME = 0; ITIME = 0; INUMS = 0; DIVSUM = 0; IDIV = 0; DT = 1.5; for (int i = 0; i < 11; i++) { MASSOURCE[i] = 0; } // Create File ${IWETTER}.probes.dat initProbes(); //START OF THE INTEGRATION LOOP while (REALTIME < TLIMIT) { //number of iteration ITIME++; if (ITIME % 20 == 0) { Max_Proc_File_Read(); // read MaxProc at 20th time step } //total simulation expressed in seconds TJETZT = (float)ISTU * 3600 + (float)IMIN * 60 + REALTIME; //write normalised actual time used in the GUI for visualisation of the modelling progress if ((ITIME % 10) == 0 && (IWetter_Console_First <= 1)) // 11.4.17 Ku use arguments { try { using (StreamWriter w = new StreamWriter("PercentGramm.txt")) { double tnorm = REALTIME * TLIMIT2 / TLIMIT; w.WriteLine(tnorm.ToString()); } } catch { } } //Online output of fields for GUI if (GRAMM_Online_flag || (ITIME % 10d) == 0) { GRAMM_Online_flag = false; // reset flag GrammOnline(NX, NY, NZ); // flag is at GRAMMOnline set to true, if only output is necessary } //Implicit solution algorith for conservation equations (SIMPLE - Patankar, 1980) if (REALTIME <= DTI) { if (SOLUTION(NX, NY, NZ) == false && ISTAT == 0) // numerical problems using overall massdivergence { computation_retry++; if (computation_retry < 3) // try 3 times -> otherwise let the app crash { IWETTER--; //try same situation TLIMIT += TLIMIT2; DTI += TLIMIT2; clear_arrays(); GEOM(); goto NEXTWEATHERSITUATION; } } } //new radiation data if (ITIME == 1) { LGEOM = true; LGEOMW = true; LGEOMR = false; } else { LGEOM = false; LGEOMW = false; LGEOMR = false; } if (ICSTR == true) { if ((ITIME == 1) || ((ITIME % IRAD) == 0)) { double TJETZT1 = TJETZT; int IMIN_RAD = IMIN; int ITAG_RAD = ITAG; int IMON_RAD = IMON; if (ISTAT == 0) { ISTUD = Convert.ToInt32(Math.Floor((TJETZT + 10) / 3600d)); } else if (ISTAT == 1) { ISTUD = ISTU; TJETZT1 = (float)ISTU * 3600 + (float)IMIN * 60; } else if (ISTAT >= 2) { //ISTUD = Convert.ToInt32(Math.Floor((TJETZT + 10) / 3600d)); //GRAMM uses sun time -> UTC has to be transferred DateTime dateref = new DateTime(Program.IJAHR4digits, Program.IMON, Program.ITAG, Program.ISTU, Program.IMIN, 0); dateref = dateref.AddSeconds(REALTIME); IMON_RAD = dateref.Month; ITAG_RAD = dateref.Day; ISTUD = dateref.Hour; IMIND = dateref.Minute; TJETZT1 = ISTUD * 3600; } AMIND = (TJETZT / 3600 - (float)ISTUD) * 60; IMIND = Convert.ToInt32(Math.Floor(AMIND)); ASECD = (AMIND - (float)IMIND) * 60; ISECD = Convert.ToInt32(Math.Floor(ASECD)); for (int II = 1; II <= 1000; II++) { if (TJETZT1 >= 86400) { TJETZT1 -= 86400; } } RadiationModel.RADIATRAD(LGEOM, LGEOMW, LGEOMR, ITAG_RAD, IMON_RAD, IJAHR, TJETZT1, NX, NY, NZ); Console.WriteLine(ITAG_RAD.ToString() + "." + IMON_RAD.ToString() + " - " + ISTUD.ToString() + ":" + IMIND.ToString("D2")); } //dynamic sun (global radiation) every 1800 seconds if (((METEO == "Y") || (METEO == "y")) && (Program.ISTAT == 0)) { if (Program.AKLA < 4) { if (REALTIME > Radiation_Threshold) { Radiation_Threshold += 1800; // compute new radiation each 1800 s double TJETZT1 = TJETZT; ISTUD = Convert.ToInt32(Math.Floor((TJETZT + 10) / 3600d)); AMIND = (TJETZT / 3600 - (float)ISTUD) * 60; IMIND = Convert.ToInt32(Math.Floor(AMIND)); ASECD = (AMIND - (float)IMIND) * 60; ISECD = Convert.ToInt32(Math.Floor(ASECD)); for (int II = 1; II <= 1000; II++) { if (TJETZT1 >= 86400) { TJETZT1 -= 86400; } } RadiationModel.RADIATRAD(LGEOM, LGEOMW, LGEOMR, ITAG, IMON, IJAHR, TJETZT1, NX, NY, NZ); Console.WriteLine(ITAG.ToString() + "." + IMON.ToString() + " - " + ISTUD.ToString() + ":" + IMIND.ToString("D2")); } } } } //store last time step STOREcalculate(NX, NY, NZ); //intermediate output if (((METEO == "Y") || (METEO == "y")) && (Program.ISTAT == 0)) { //only in case of steady-state simulations using meteopgt.all no intermediate output is provided if (Program.meteopgt_nr == 0) { IOUTPUT = 100000000; Intermed_Threshold = 100000000; } } Int16 IHOUR = Convert.ToInt16(Math.Floor(TJETZT / IOUTPUT)); if (REALTIME > Intermed_Threshold && DTI > 3602) // if threshold is exceeded && simulation time > 1 h -> create intermed. outputs { Console.Write(" INTERMEDIATE OUTPUT "); // set new Threshold value if (Intermed_Threshold < IOUTPUT) { Intermed_Threshold = IOUTPUT * 2; // 2nd intermediate output after 2 hours } else { Intermed_Threshold += IOUTPUT; } OUTPUT(NX, NY, NZ, true); // intermediate output //generating meteopgt.all and mettimeseries.dat for ERA5/GUI postprocessing if (Program.ISTAT == 2 || Program.ISTAT == 4) { Meteopgtall.GRALGenerateMeteoFilesForERA5(); } Console.WriteLine(); Console.WriteLine(); if (((METEO != "Y") && (METEO != "y")) || (Program.ISTAT != 0)) { IWETTER++; } } //increase simulation time REALTIME += DT; IHOURO = IHOUR; //save intermediate surface flow fields after 75% of the total simulatin time (VDI 3783-7) if ((REALTIME >= DTI * 0.75) && (REALTIME <= (DTI * 0.75 + DT * 2))) { Parallel.For(1, NX + 1, Program.pOptions, i => { for (int j = 1; j <= NY; j++) { U_TEMP[i][j] = (float)(U[i][j][1]); V_TEMP[i][j] = (float)(V[i][j][1]); W_TEMP[i][j] = (float)(W[i][j][1]); } }); } } computation_retry = 0; // reset compuation retry counter //Ultimate output at the end of each situation Console.WriteLine(""); Console.Write(" MMAIN : OUT "); if ((METEO != "Y") && (METEO != "y")) { OUTPUT(NX, NY, NZ, false); // final output Console.WriteLine(); } else { OUTPUT(NX, NY, NZ, false); // final output Console.WriteLine(); goto NEXTWEATHERSITUATION; } }
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); //} } }
// dawn of a new project // STUExcavator: // go through all stu files and find GUIDs // future possibilities: // STUv1 excavation: // find padding, then try for guid public static void Main(string[] args) { string overwatchDir = args[0]; string outputDir = args[1]; const string language = "enUS"; // usage: "STUExcavator overwatch_dir output_dir [dataset_dir]" string datasetFolder = ""; if (args.Length >= 3) { datasetFolder = args[2]; } // casc setup Config = CASCConfig.LoadLocalStorageConfig(overwatchDir, false, false); Config.Languages = new HashSet <string> { language }; CASC = CASCHandler.OpenStorage(Config); DataTool.Program.Files = new Dictionary <ulong, PackageRecord>(); DataTool.Program.TrackedFiles = new Dictionary <ushort, HashSet <ulong> >(); DataTool.Program.CASC = CASC; DataTool.Program.Root = CASC.Root as OwRootHandler; DataTool.Program.Flags = new ToolFlags { OverwatchDirectory = outputDir, Language = language }; IO.MapCMF(true); Files = DataTool.Program.Files; TrackedFiles = DataTool.Program.TrackedFiles; // prepare Version2Comparer Version2Comparer.InstanceJSON = STUHashTool.Program.LoadInstanceJson(Path.Combine(datasetFolder, "RegisteredSTUTypes.json")); InvalidTypes = STUHashTool.Program.LoadInvalidTypes(Path.Combine(datasetFolder, "IgnoredBrokenSTUs.txt")); //STUHashTool.Program.LoadHashCSV(Path.Combine(datasetFolder, "KnownFields.csv"), out FieldNames); //STUHashTool.Program.LoadHashCSV(Path.Combine(datasetFolder, "KnownEnums.csv"), out EnumNames); //STUHashTool.Program.LoadHashCSV(Path.Combine(datasetFolder, "KnownTypes.csv"), out InstanceNames); FieldNames = new Dictionary <uint, string>(); EnumNames = new Dictionary <uint, string>(); InstanceNames = new Dictionary <uint, string>(); JsonConvert.DefaultSettings = () => new JsonSerializerSettings { Converters = new List <JsonConverter> { new GUIDArrayConverter(), new GUIDConverter() }, PreserveReferencesHandling = PreserveReferencesHandling.All }; // wipe ISTU ISTU.Clear(); // actual tool Dictionary <string, AssetTypeSummary> types = new Dictionary <string, AssetTypeSummary>(); CompileSTUs(); foreach (KeyValuePair <ushort, HashSet <ulong> > keyValuePair in TrackedFiles.OrderBy(x => x.Key)) { string type = keyValuePair.Key.ToString("X3"); if (type == "09C" || type == "062" || type == "077") { continue; } Log($"Processing type: {type}"); types[type] = Excavate(keyValuePair.Key, keyValuePair.Value); IO.CreateDirectoryFromFile(Path.Combine(outputDir, type, "master.json")); using (Stream masterFile = File.OpenWrite(Path.Combine(outputDir, type, "master.json"))) { masterFile.SetLength(0); string masterJson = JsonConvert.SerializeObject(types[type], Formatting.Indented); using (TextWriter writer = new StreamWriter(masterFile)) { writer.WriteLine(masterJson); } } if (types[type].Assets == null) { continue; } foreach (Asset asset in types[type].Assets) { string assetFile = Path.Combine(outputDir, type, "assets", $"{asset.GUID}.json"); string assetFileJson = Path.Combine(outputDir, type, "jsondump", $"{asset.GUID}.json"); IO.CreateDirectoryFromFile(assetFile); IO.CreateDirectoryFromFile(assetFileJson); using (Stream assetStream = File.OpenWrite(assetFile)) { assetStream.SetLength(0); string assetJson = JsonConvert.SerializeObject(asset, Formatting.Indented); using (TextWriter writer = new StreamWriter(assetStream)) { writer.WriteLine(assetJson); } } if (asset.JSONDump == null) { continue; } using (Stream assetStream = File.OpenWrite(assetFileJson)) { assetStream.SetLength(0); using (TextWriter writer = new StreamWriter(assetStream)) { writer.WriteLine(asset.JSONDump); } } } } }
public object DeserializeArray(object instance, ISTU stu, FieldInfo field, BinaryReader reader, BinaryReader metadataReader) { throw new NotImplementedException(); }
public static T[] GetInstances <T>(ulong key) where T : STUInstance { ISTU stu = OpenSTUSafe(key); return(stu?.Instances.OfType <T>().ToArray() ?? new T[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++; } } } }
public static ISTU OpenSTUSafe(ulong key) { using (Stream stream = OpenFile(key)) { return(stream == null ? null : ISTU.NewInstance(stream, BuildVersion)); } }