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;
 }
Beispiel #3
0
 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>());
            }
Beispiel #9
0
        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];
Beispiel #10
0
        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);
        }
Beispiel #11
0
        // 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));
        }
Beispiel #12
0
        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);
        }
Beispiel #13
0
        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);
        }
Beispiel #14
0
        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);
        }
Beispiel #15
0
        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 !);
Beispiel #17
0
 public DatModelFileBundle(IFileHierarchyFile datFile)
 {
     this.DatFile = datFile;
 }
 public VisModelFileBundle(IFileHierarchyFile visFile, HWContext context)
 {
     this.VisFile = visFile;
     this.Context = context;
 }
Beispiel #19
0
        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);
Beispiel #21
0
        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);
        }
Beispiel #22
0
 public static bool Verify(IFileHierarchyFile file, string expected)
 {
     using var r = file.Impl.OpenRead();
     return(expected.All(c => (byte)c == r.ReadByte()));
 }