public ModelBundle( IFileHierarchyFile modelFile, IList <IFileHierarchyFile> animationFiles) { this.ModelFile = modelFile; this.AnimationFiles = animationFiles; }
public GloModelFileBundle(IFileHierarchyFile gloFile, IReadOnlyList <IFileHierarchyDirectory> textureDirectories) { this.GloFile = gloFile; this.TextureDirectories = textureDirectories; }
public XtdModelFileBundle(IFileHierarchyFile xtdFile, IFileHierarchyFile xttFile, HWContext context) { this.XtdFile = xtdFile; this.XttFile = xttFile; this.Context = context; }
public IList <IFileHierarchyFile> GetBcksForBmd( IFileHierarchyFile bmdFile, IList <IFileHierarchyFile> bckFiles) { var prefix = StringUtil.UpTo(bmdFile.NameWithoutExtension, "_"); return(bckFiles.Where(file => file.Name.StartsWith(prefix)).ToArray()); }
public override IList <IFileHierarchyFile> GetAnimationsForModel( IFileHierarchyFile modelFile, IList <IFileHierarchyFile> animationFiles) { var prefix = modelFile.NameWithoutExtension; return(animationFiles.Where(file => file.Name.StartsWith(prefix)) .ToArray()); }
public CmbModelFileBundle(IFileHierarchyFile cmbFile, IReadOnlyList <IFileHierarchyFile>?csabFiles, IReadOnlyList <IFileHierarchyFile>?ctxbFiles, IReadOnlyList <IFileHierarchyFile>?shpaFiles) { this.CmbFile = cmbFile; this.CsabFiles = csabFiles; this.CtxbFiles = ctxbFiles; this.ShpaFiles = shpaFiles; }
public IList <IFileHierarchyFile> GetBcksForBmd( IFileHierarchyFile bmdFile, IList <IFileHierarchyFile> bckFiles) { var suffix = bmdFile.NameWithoutExtension.Substring( bmdFile.NameWithoutExtension.Length - this.suffixLength_); return(bckFiles.Where(file => file.Name.StartsWith(suffix)).ToArray()); }
public IList <IFileHierarchyFile> GetBcksForBmd( IFileHierarchyFile bmdFile, IList <IFileHierarchyFile> bckFiles) { if (bmdFile.NameWithoutExtension.ToLower().Contains(this.name_)) { return(bckFiles); } return(Array.Empty <IFileHierarchyFile>()); }
public bool Run(IFileHierarchyFile resFile) { Asserts.True( resFile.Impl.Exists, $"Cannot dump RES because it does not exist: {resFile}"); var directoryFullName = resFile.FullNameWithoutExtension; var isResGz = resFile.Name.EndsWith(".res.gz"); if (isResGz) { directoryFullName = directoryFullName[..^ 4];
private bool ReadFile_(IFileHierarchyFile rarcFile) { using var er = new EndianBinaryReader(rarcFile.Impl.OpenRead()); var header = new RarcHeader(); header.type = er.ReadString(Encoding.ASCII, 4); if (header.type != "RARC") { return(false); } header.size = er.ReadUInt32(); header.unknown = er.ReadUInt32(); header.dataStartOffset = er.ReadUInt32(); er.ReadUInt32s(header.unknown2); header.numNodes = er.ReadUInt32(); header.firstNodeOffset = er.ReadUInt32(); header.numDirectories = er.ReadUInt32(); header.fileEntriesOffset = er.ReadUInt32(); header.stringTableLength = er.ReadUInt32(); header.stringTableOffset = er.ReadUInt32(); er.ReadUInt32s(header.unknown5); var cwd = Directory.GetCurrentDirectory(); var directoryPath = rarcFile.FullName + "_dir"; { var nodes = new RarcNode[header.numNodes]; for (var i = 0; i < header.numNodes; ++i) { nodes[i] = this.GetNode_(er, header, i); } ; foreach (var node in nodes) { Directory.SetCurrentDirectory(directoryPath); this.DumpNode_(er, node, header); } } Directory.SetCurrentDirectory(cwd); return(true); }
// Based on version 1 of rarcdump by thakis. // Expanded with information from: http://wiki.tockdom.com/wiki/RARC_(File_Format) private bool Impl_(IFileHierarchyFile rarcFile) { var directoryPath = rarcFile.FullName + "_dir"; if (Directory.Exists(directoryPath)) { //return false; } var logger = Logging.Create <RarcDump>(); using var rarcDumpScope = logger.BeginScope("rarcdump"); logger.LogInformation($"Dumping ARC {rarcFile.LocalPath}..."); return(this.ReadFile_(rarcFile)); }
public bool Extract(IFileHierarchyFile zarFile) { Asserts.True(zarFile.Exists, $"Could not extract ZAR because it does not exist: {zarFile.FullName}"); Asserts.Equal(".zar", zarFile.Extension, $"Could not extract file because it is not a ZAR: {zarFile.FullName}"); var directoryPath = zarFile.FullName.Substring(0, zarFile.FullName.Length - ".zar".Length); var directory = new FinDirectory(directoryPath); if (directory.Exists) { return(false); } var logger = Logging.Create <ZarExtractor>(); logger.LogInformation($"Extracting ZAR {zarFile.LocalPath}..."); Zar zar; { using var er = new EndianBinaryReader(zarFile.Impl.OpenRead(), Endianness.LittleEndian); zar = new Zar(er); } foreach (var fileType in zar.FileTypes) { foreach (var file in fileType.Files) { var filePath = Path.Join(directoryPath, file.FileName); Directory.CreateDirectory( Asserts.CastNonnull(Path.GetDirectoryName(filePath))); File.WriteAllBytes(filePath, file.Bytes); } } zarFile.Impl.Info.Delete(); return(true); }
public bool Extract(IFileHierarchyFile garFile) { Asserts.True(garFile.Exists, $"Could not extract GAR because it does not exist: {garFile.FullName}"); var directoryPath = StringUtil.UpTo(garFile.FullName, ".gar"); var directory = new FinDirectory(directoryPath); if (directory.Exists) { return(false); } var logger = Logging.Create <ZarExtractor>(); logger.LogInformation($"Extracting GAR {garFile.LocalPath}..."); Gar gar; { using var er = new EndianBinaryReader(garFile.Impl.OpenRead(), Endianness.LittleEndian); gar = new Gar(er); } foreach (var fileType in gar.FileTypes) { foreach (var file in fileType.Files) { var fileName = file.FileName; if (!fileName.EndsWith($".{fileType.TypeName}")) { fileName = $"{fileName}.{fileType.TypeName}"; } var filePath = Path.Join(directoryPath, fileName); Directory.CreateDirectory(Path.GetDirectoryName(filePath) !); File.WriteAllBytes(filePath, file.Bytes); } } garFile.Impl.Info.Delete(); return(true); }
public bool Run(IFileHierarchyFile rarcFile, bool cleanup) { Asserts.True( rarcFile.Impl.Exists, $"Cannot dump RARC because it does not exist: {rarcFile}"); var finalDirectoryPath = rarcFile.FullNameWithoutExtension; if (Directory.Exists(finalDirectoryPath)) { return(false); } if (!MagicTextUtil.Verify(rarcFile, "RARC")) { return(false); } var directoryPath = rarcFile.FullName + "_dir"; if (!Directory.Exists(directoryPath)) { var logger = Logging.Create <RarcDump>(); logger.LogInformation($"Dumping RARC {rarcFile.LocalPath}..."); // TODO: Is this implementation right? It *seems* to only export the // first node in a RARC. Files.RunInDirectory( rarcFile.Impl.GetParent() !, () => { ProcessUtil.ExecuteBlockingSilently( GcnToolsConstants.RARCDUMP_EXE, $"\"{rarcFile.FullName}\""); }); Asserts.True(Directory.Exists(directoryPath), $"Directory was not created: {directoryPath}"); } Directory.Move(directoryPath, finalDirectoryPath); if (cleanup) { rarcFile.Impl.Info.Delete(); } return(true); }
public bool Run(IFileHierarchyFile file, bool cleanup) { Asserts.True( file.Exists, $"Cannot decrypt YAY0 because it does not exist: {file}"); var finalRarcPath = file.FullNameWithoutExtension + ".rarc"; if (File.Exists(finalRarcPath)) { return(false); } if (!MagicTextUtil.Verify(file, "Yay0")) { return(false); } var rarcPath = file.FullName + " 0.rarc"; if (!File.Exists(rarcPath)) { var logger = Logging.Create <Yay0Dec>(); Files.RunInDirectory( file.Impl.GetParent() !, () => { ProcessUtil.ExecuteBlockingSilently( GcnToolsConstants.YAY0DEC_EXE, $"\"{file.FullName}\""); }); Asserts.True(File.Exists(rarcPath), $"File was not created: {rarcPath}"); } File.Move(rarcPath, finalRarcPath); if (cleanup) { file.Impl.Info.Delete(); } return(true); }
public static IDirectory GetOutputDirectoryForFile( IFileHierarchyFile fileHierarchyFile) => GetOutputDirectoryForDirectory(fileHierarchyFile.Parent !);
public DatModelFileBundle(IFileHierarchyFile datFile) { this.DatFile = datFile; }
public VisModelFileBundle(IFileHierarchyFile visFile, HWContext context) { this.VisFile = visFile; this.Context = context; }
public bool Run( IFileHierarchyFile rarcFile, bool cleanup, IReadOnlySet <string> junkTerms) { Asserts.True( rarcFile.Impl.Exists, $"Cannot dump RARC because it does not exist: {rarcFile}"); if (!MagicTextUtil.Verify(rarcFile, "RARC")) { return(false); } var directoryPath = rarcFile.FullName + "_dir"; if (!Directory.Exists(directoryPath)) { var logger = Logging.Create <RarcDump>(); logger.LogInformation($"Dumping RARC {rarcFile.LocalPath}..."); Files.RunInDirectory( rarcFile.Impl.GetParent() !, () => { ProcessUtil.ExecuteBlockingSilently( GcnToolsConstants.RARCDUMP_EXE, $"\"{rarcFile.FullName}\""); }); Asserts.True(Directory.Exists(directoryPath), $"Directory was not created: {directoryPath}"); } // Determines final directory path from var directory = new FinDirectory(directoryPath); var subdir = directory.GetExistingSubdirs().Single(); var subdirName = subdir.Name; var isSubdirJunk = junkTerms.Contains(subdirName); var rarcName = rarcFile.NameWithoutExtension; var isRarcJunk = junkTerms.Contains(rarcName); string finalDirectoryName; // If only one is in the junk set, uses the other. if (isSubdirJunk && !isRarcJunk) { finalDirectoryName = rarcName; } else if (!isSubdirJunk && isRarcJunk) { finalDirectoryName = subdirName; } // If subdir has same name or is an abbreviation of the parent, // just collapses them with the parent name. else if ((subdirName.Length <= rarcName.Length && subdirName.ToLower() == rarcName.Substring(0, subdirName.Length).ToLower()) || (junkTerms?.Contains(subdirName) ?? false)) { finalDirectoryName = rarcName; } // If parent has same name or is an abbreviation of the subdir, // just collapses them with the subdir name. else if (subdirName.Length >= rarcName.Length && subdirName.Substring(0, rarcName.Length).ToLower() == rarcName.ToLower()) { finalDirectoryName = subdirName; } // If subdir has a different name, merges their names together and // collapses them. else { finalDirectoryName = $"{rarcName}_{subdirName}"; } var finalDirectoryPath = Path.Join(Path.GetDirectoryName(directoryPath), finalDirectoryName); Asserts.True(!Directory.Exists(finalDirectoryPath)); subdir.MoveTo(finalDirectoryPath); Directory.Delete(directoryPath); if (cleanup) { rarcFile.Impl.Info.Delete(); } return(true); }
public abstract IList <IFileHierarchyFile> GetAnimationsForModel( IFileHierarchyFile modelFile, IList <IFileHierarchyFile> animationFiles);
public bool Run( IFileHierarchyFile relFile, IFileHierarchyFile mapFile, bool cleanup) { Asserts.True(relFile.Exists); Asserts.True(mapFile.Exists); string REL_Location = relFile.FullName; string MAP_Location = mapFile.FullName; string Data_Dir = Path.GetDirectoryName(REL_Location) + "\\" + Path.GetFileNameWithoutExtension(REL_Location); if (Directory.Exists(Data_Dir)) { return(false); } this.currentHeaderSize_ = Path.GetExtension(REL_Location).Contains("dol") ? RelDump.DOL_HEADER_SIZE : RelDump.REL_HEADER_SIZE; byte[] REL_Data = File.ReadAllBytes(REL_Location); string[] MAP_Data = File.ReadAllLines(MAP_Location); string Memory_Map = MAP_Data.FirstOrDefault(o => o.Contains("Memory map:")); if (!string.IsNullOrEmpty(Memory_Map)) { int Memory_Map_Idx = Array.IndexOf(MAP_Data, Memory_Map); if (Memory_Map_Idx > -1) { Memory_Map_Idx += 3; // Data starts three lines after Directory.CreateDirectory(Data_Dir); // Create Section Folders this.dataSectionMap_ = new Dictionary <string, int>(); for (int i = Memory_Map_Idx; i < MAP_Data.Length; i++) { if (string.IsNullOrEmpty(MAP_Data[i])) { break; } string Section_Info = MAP_Data[i].TrimStart(); string Section_Name = Regex.Match(Section_Info, @"^[^ ]*").Value; string Section_Offsets = Section_Info.Substring(Section_Name.Length + 11); string Section_Size = Regex.Match(Section_Offsets, @"^[^ ]*").Value; string Section_Offset = Section_Offsets.Substring(Section_Size.Length + 1, 8); if (int.TryParse(Section_Offset, NumberStyles.AllowHexSpecifier, null, out int Offset) && int.TryParse(Section_Size, NumberStyles.AllowHexSpecifier, null, out int Size)) { string Section_Dir = Data_Dir + "\\" + Section_Name; if (!Directory.Exists(Section_Dir)) { Directory.CreateDirectory(Section_Dir); } this.dataSectionMap_.Add(Section_Name, Offset); } } // Section off data string Current_Section = ""; for (int i = 0; i < Memory_Map_Idx - 3; i++) { string Line = MAP_Data[i]; if (!string.IsNullOrEmpty(Line)) { if (Line.Contains(" section layout")) { i += 3; // Skip column text Current_Section = Regex.Match(Line.TrimStart(), @"^[^ ]*").Value; Console.WriteLine("Switched to section: " + Current_Section); //Console.ReadKey(); } else if (!string.IsNullOrEmpty(Current_Section)) { if (Line.Contains(@"...")) { //Console.WriteLine("Contained ... : " + Line); continue; } Line = Line.Trim(); // Clear Leading/Trailing Whitespace Line = Line.Replace("\t", " "); // Confirm all tabs get turned into a space Line = Regex.Replace(Line, @"\s+", " "); // Turn multiple spaces/tabs to one space string[] Line_Data = Line.Split(' '); /* * Line_Data contents * ================= * Starting Address (relative to section start) 0 * Size 1 * Virtual Address (same as Starting Address??) 2 * Type (1 = Object, 4 = Method) 3 * Name 4 * Object 5 */ int Offset = this.GetRELOffset_( this.dataSectionMap_[Current_Section], int.Parse( Line_Data[1], NumberStyles .AllowHexSpecifier)); int Size = int.Parse(Line_Data[1], NumberStyles.AllowHexSpecifier); bool IsObject = Line_Data[3].Equals("1"); string Method_Name = Line_Data[4]; string Object_Name = Line_Data[5]; if (Line_Data.Length >= 7) { Object_Name += ("_" + Line_Data[6]); } string Dir = Data_Dir + "\\" + Current_Section + "\\" + Object_Name; if (!Directory.Exists(Dir)) { Directory.CreateDirectory(Dir); } if (!IsObject) { try { using (FileStream Data_File = File.Create(Dir + "\\" + Method_Name + ".bin")) { Data_File.Write(REL_Data, Offset, Size); Data_File.Flush(); } } catch { //Console.WriteLine(string.Format("Unable to create file for: {0}/{1}! Offset was past the end of the file!", //Current_Section, Object_Name)); //Console.ReadKey(); } } else { Console.WriteLine( string.Format("Parsing data for {0}/{1}", Current_Section, Object_Name)); } } } } } } // TODO: Clean up REL/MAP files here return(true); }
public static bool Verify(IFileHierarchyFile file, string expected) { using var r = file.Impl.OpenRead(); return(expected.All(c => (byte)c == r.ReadByte())); }