/// <summary> /// Initialize with stream data /// </summary> /// <param name="buffer"></param> public RDBINFO(Span <byte> buffer) { // 0 1 2 3 4 5 var csv = ManagedFSHelper.GetFileList(buffer); // Format,Index,Offset,Length,Name,Path foreach (var line in csv) { var encodedName = line[4]; uint ktid; if (line.Length > 6) // .bin.info { encodedName = line[2]; ktid = uint.Parse(line[1], NumberStyles.HexNumber); } else // .info { if (encodedName.Length == 0) { continue; } ktid = RDB.Hash(line[4]); } Entries.Add((ktid, line)); var(name, _) = RDB.StripName(encodedName); NameMap[ktid] = name; HashMap[ktid] = encodedName; } }
public static void Main(string[] args) { Logger.PrintVersion("Nyotengu"); var flags = CommandLineFlags.ParseFlags <FilelistFlags>(CommandLineFlags.PrintHelp, args); if (flags == null || string.IsNullOrWhiteSpace(flags.GameDir)) { return; } Logger.Info("Nyotengu", "Generating filename list..."); var nyotengu = new Cethleann.ManagedFS.Nyotengu(flags); nyotengu.LoadFileList(flags.FileList, flags.GameId); foreach (var rdb in Directory.GetFiles(flags.GameDir, "*.rdb")) { nyotengu.AddDataFS(rdb); } nyotengu.SaveGeneratedFileList(null, flags.GameId); Logger.Info("Nyotengu", "Generating KTID property list..."); var propertyList = Cethleann.ManagedFS.Nyotengu.LoadKTIDFileListEx(null, "PropertyList"); foreach (var rdb in nyotengu.RDBs) { for (var i = 0; i < rdb.Entries.Count; ++i) { var entry = rdb.GetEntry(i); if (entry.FileKTID == rdb.Header.NameDatabaseKTID) { continue; } if (entry.TypeInfoKTID != 0xbf6b52c7) { continue; } var namedb = new NDB(rdb.ReadEntry(i).Span); foreach (var(_, strings) in namedb.Entries) { if (strings[1].Length == 0) { continue; } propertyList[RDB.Hash(strings[1])] = ("TypeInfo", strings[1]); foreach (var str in strings.Skip(2)) { propertyList[RDB.Hash(str)] = ("Property", str); } } } } Cethleann.ManagedFS.Nyotengu.SaveGeneratedFileList(propertyList, null, "DEBUG"); }
private static void HashNDB(Span <byte> buffer, Dictionary <KTIDReference, string> typeInfo, Dictionary <KTIDReference, string> extra, DatabaseFlags flags) { var name = new NDB(buffer); foreach (var(_, strings) in name.Entries) { typeInfo[RDB.Hash(strings[1])] = strings[1]; foreach (var str in strings.Skip(2)) { extra[RDB.Hash(str)] = str; } } }
private static void Main(string[] args) { Logger.PrintVersion("Softness"); var flags = CommandLineFlags.ParseFlags <HasherFlags>(CommandLineFlags.PrintHelp, args); if (flags == null) { return; } foreach (var str in flags.Strings) { Console.WriteLine($"{(flags.Raw ? RDB.Hash(str) : RDB.Hash(Path.GetFileNameWithoutExtension(str), flags.Format ?? Path.GetExtension(str).Substring(1).ToUpper(), flags.Prefix)):x8},{str}"); } }
/// <summary> /// Initialize with stream data /// </summary> /// <param name="buffer"></param> public NDB(Span <byte> buffer) { Header = MemoryMarshal.Read <NDBHeader>(buffer); Entries = new List <(KTIDReference reference, string[] strings)>(Header.Count); NameMap = new Dictionary <KTIDReference, string>(Header.Count); HashMap = new Dictionary <KTIDReference, string>(Header.Count); ExtMap = new Dictionary <KTIDReference, string>(Header.Count); var offset = Header.SectionHeader.Size; var entrySize = SizeHelper.SizeOf <NDBEntry>(); for (var i = 0; i < Header.Count; ++i) { var entry = MemoryMarshal.Read <NDBEntry>(buffer.Slice(offset)); var strings = new string[entry.Count]; Logger.Assert(entry.Count >= 2, "entry.Count >= 2"); if (entry.Count > 0) { var pointers = MemoryMarshal.Cast <byte, int>(buffer.Slice(offset + entrySize, entry.Count * 4)); for (var index = 0; index < pointers.Length; index++) { var pointer = pointers[index]; strings[index] = buffer.Slice(offset + pointer).ReadString() ?? string.Empty; } } offset += entry.SectionHeader.Size; offset = offset.Align(4); Entries.Add((entry.KTID, strings)); var(name, ext) = RDB.StripName(strings[0]); NameMap[entry.KTID] = name; HashMap[entry.KTID] = strings[0]; if (strings[1].Length > 0) { var hash = RDB.Hash(strings[1]); if (ext != null) { ExtMap[hash] = ext.ToLower(); } } foreach (var str in strings.Where(x => x.Length > 0)) { HashMap[RDB.Hash(str)] = str; } } }
private static void ProcessNDB(Span <byte> buffer, DatabaseFlags flags) { var name = new NDB(buffer); foreach (var(entry, strings) in name.Entries) { var filename = name.NameMap[entry.KTID]; var text = $"{entry.KTID:x8},{RDB.Hash(strings[0]):x8},{strings.ElementAt(0)},{filename},{RDB.Hash(strings[1]):x8},{strings[1]}"; if (strings.Length > 2) { text += string.Join(string.Empty, strings.Skip(2)); } Console.WriteLine(text); } }
private static void Main(string[] args) { Logger.PrintVersion("Nyotengu"); var flags = CommandLineFlags.ParseFlags <DatabaseFlags>(CommandLineFlags.PrintHelp, args); if (flags == null) { return; } var files = new HashSet <string>(); foreach (var path in flags.Paths) { if (File.Exists(path)) { files.Add(path); } if (!Directory.Exists(path)) { continue; } foreach (var file in Directory.GetFiles(path)) { files.Add(file); } } var ndbFiles = new Dictionary <KTIDReference, string>(); if (flags.NDBPaths != null) { foreach (var nameFile in flags.NDBPaths.Where(Directory.Exists).SelectMany(Directory.GetFiles).Union(flags.NDBPaths.Where(File.Exists))) { ndbFiles[RDB.Hash(Path.GetFileName(nameFile))] = nameFile; if (KTIDReference.TryParse(Path.GetFileNameWithoutExtension(nameFile), NumberStyles.HexNumber, null, out var hashedName)) { ndbFiles[hashedName] = nameFile; } } } var filelist = Cethleann.ManagedFS.Nyotengu.LoadKTIDFileListShared(flags.FileList, flags.GameId); var propertyList = Cethleann.ManagedFS.Nyotengu.LoadKTIDFileList(null, "PropertyList"); var filters = flags.TypeInfoFilter?.Split(',').Select(x => RDB.Hash(x.Trim())).ToHashSet() ?? new HashSet <KTIDReference>(); var typeHashes = new Dictionary <KTIDReference, string>(); var extraHashes = new Dictionary <KTIDReference, string>(); var missingProperties = new HashSet <KTIDReference>(); foreach (var file in files) { Logger.Log(ConsoleSwatch.XTermColor.White, true, Console.Error, "Nyotengu", "INFO", file); Span <byte> buffer = File.ReadAllBytes(file); // ReSharper disable once SwitchStatementHandlesSomeKnownEnumValuesWithDefault switch (buffer.GetDataType()) { case DataType.OBJDB: { ProcessOBJDB(buffer, ndbFiles, filelist, propertyList, filters, flags, missingProperties); break; } case DataType.NDB: { if (flags.HashTypes || flags.HashExtra) { HashNDB(buffer, typeHashes, extraHashes, flags); } else if (flags.CreateFilelist) { NDBFilelist(buffer, Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(file)), flags, filelist); } else { ProcessNDB(buffer, flags); } break; } default: Logger.Error("Nyotengu", $"Format for {file} is unknown!"); break; } } if (flags.HashTypes) { foreach (var(hash, text) in typeHashes.OrderBy(x => x.Key)) { Console.WriteLine($"TypeInfo,{hash:x8},{text}"); } } if (flags.HashExtra) { foreach (var(hash, text) in extraHashes.OrderBy(x => x.Key)) { Console.WriteLine($"Property,{hash:x8},{text}"); } } // ReSharper disable once InvertIf if (flags.CreateMissingList) { var location = ManagedFSHelper.GetFileListLocation(null, "MissingProperties", "rdb"); using var file = File.Open(location, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read); file.Seek(0, SeekOrigin.End); using var writer = new StreamWriter(file, Encoding.UTF8); foreach (var hash in missingProperties) { writer.WriteLine($"Property,{hash:x8},"); } } }
private static void Main(string[] args) { Logger.PrintVersion("Nyotengu"); var flags = CommandLineFlags.ParseFlags <AnimationGraphFlags>(CommandLineFlags.PrintHelp, args); if (flags == null) { return; } var objdbNdb = new NDB(); var singletonNdb = new NDB(); if (!string.IsNullOrEmpty(flags.OBJDBNDBPath) && File.Exists(flags.OBJDBNDBPath)) { objdbNdb = new NDB(File.ReadAllBytes(flags.OBJDBNDBPath)); } if (!string.IsNullOrEmpty(flags.SingletonDBNDBPath) && File.Exists(flags.SingletonDBNDBPath)) { singletonNdb = new NDB(File.ReadAllBytes(flags.SingletonDBNDBPath)); } // ReSharper disable InconsistentNaming var CE1DB = new OBJDB(File.ReadAllBytes(flags.OBJDBPath)); var CE1Singleton = new OBJDB(File.ReadAllBytes(flags.SingletonPath)); // ReSharper restore InconsistentNaming var filelist = Cethleann.ManagedFS.Nyotengu.LoadKTIDFileList(flags.FileList, flags.GameId); var animationFiles = new Dictionary <KTIDReference, string>(); foreach (var directory in flags.AnimationDirectories ?? new HashSet <string?>()) { if (directory == null || !Directory.Exists(directory)) { continue; } foreach (var file in Directory.GetFiles(directory)) { var basename = Path.GetFileNameWithoutExtension(file); if (basename.Length != 8 || !KTIDReference.TryParse(basename, out var reference)) { reference = RDB.Hash(file, "G1A"); } animationFiles[reference] = file; } } var typeKTID = RDB.Hash("TypeInfo::Object::MotorCharacterSetting"); foreach (var entry in CE1DB.Entries.Select(x => x.Value).Where(entry => entry.Record.TypeInfoKTID == typeKTID)) { var(_, values) = entry.GetProperty("CharacterModelNameHash"); if (values == null) { continue; } var(_, actions) = entry.GetProperty("CharacterActionObjectNameHashArray"); if (actions == null || actions.Length == 0) { continue; } var nameHashes = values.Where(x => x != null).Select(x => new KTIDReference(x)).ToArray(); if (!nameHashes.Any(x => flags.Hashes.Contains(x))) { continue; } Logger.Info("ANIM", $"Found Character Settings: {string.Join(", ", nameHashes.Select(x => GetKTIDNameValue(x, false, objdbNdb, filelist)))}"); var done = new HashSet <KTIDReference>(); foreach (var actionHash in actions.Select(x => new KTIDReference(x))) { if (!CE1Singleton.Entries.TryGetValue(actionHash, out var player)) { Logger.Error("ANIM", $"Can't find animation player settings for {GetKTIDNameValue(actionHash, false, singletonNdb, filelist)}"); continue; } var properties = player.GetProperties("AnimationDataObjectNameHashArray", "SrcAnimationDataObjectNameHash", "DstAnimationDataObjectNameHash", "FCurveAnimationDataObjectNameHash"); var animationDataHashes = properties.SelectMany(x => x.values ?? Array.Empty <object?>()).ToArray(); var ktidHashes = animationDataHashes.Where(x => x != null).Select(x => new KTIDReference(x)).ToArray(); foreach (var animationDataHash in ktidHashes) { if (!CE1Singleton.Entries.TryGetValue(animationDataHash, out var animationData)) { Logger.Error("ANIM", $"Can't find animation data for {GetKTIDNameValue(animationDataHash, false, singletonNdb, filelist)}"); continue; } var(_, animationHashes) = animationData.GetProperty("G1AFileResourceHash"); if (animationHashes == null) { Logger.Error("ANIM", $"Can't find animation references for {GetKTIDNameValue(animationDataHash, false, singletonNdb, filelist)}"); continue; } foreach (var animationHashActual in animationHashes.Where(x => x != null).Select(x => new KTIDReference(x))) { if (!done.Add(animationHashActual)) { continue; } Logger.Info("ANIM", GetKTIDNameValue(animationHashActual, false, singletonNdb, filelist)); if (string.IsNullOrWhiteSpace(flags.Output) || !animationFiles.TryGetValue(animationHashActual, out var path)) { continue; } if (!Directory.Exists(flags.Output)) { Directory.CreateDirectory(flags.Output); } File.Copy(path, Path.Combine(flags.Output, Path.GetFileName(path)), true); } } } Console.WriteLine(); } }