示例#1
0
            public FileNode(RARC BR, byte[] Data, UInt32 Offset, RARCHeader Header)
            {
                BaseRARC = BR;

                Offset = RARCHeader.Size + (Offset * Size);

                Tag                  = Helpers.ReadString(Data, (int)Offset, 4);
                FilenameOffset       = Helpers.Read32(Data, (int)Offset + 4);
                NumFileEntries       = Helpers.Read16(Data, (int)Offset + 10);
                FirstFileEntryOffset = Helpers.Read32(Data, (int)Offset + 12);

                NodeName = Helpers.ReadString(Data, (int)(FilenameOffset + Header.StringTableOffset + 32));
                Console.WriteLine("Reading node: " + NodeName);
                for (int i = 0; i < NumFileEntries; ++i)
                {
                    UInt32    ReadOffset  = (UInt32)(Header.FileEntriesOffset + (FirstFileEntryOffset * FileEntry.Size) + (i * FileEntry.Size) + 32);
                    FileEntry CurrentFile = new FileEntry(BaseRARC, Data, ReadOffset, Header);
                    Console.WriteLine("Found fileEntry: " + CurrentFile.FileName);
                    if (CurrentFile.ID == 0xFFFF || CurrentFile.Unknown2 == 0x0200)         // 0x2000 correct???
                    {
                        if (CurrentFile.FilenameOffset != 0 && CurrentFile.FilenameOffset != 2)
                        {
                            ChildNodes.Add(new FileNode(BaseRARC, Data, CurrentFile.DataOffset, Header));
                        }
                    }
                    else
                    {
                        Files.Add(CurrentFile);
                    }
                }
            }
示例#2
0
            public FileEntry(RARC BR, byte[] Data, UInt32 Offset, RARCHeader Head)
            {
                BaseRARC = BR;

                ID             = Helpers.Read16(Data, (int)Offset);
                Unknown1       = Helpers.Read16(Data, (int)Offset + 2);
                Unknown2       = Helpers.Read16(Data, (int)Offset + 4);
                FilenameOffset = Helpers.Read16(Data, (int)Offset + 6);
                DataOffset     = Helpers.Read32(Data, (int)Offset + 8);
                DataSize       = Helpers.Read32(Data, (int)Offset + 12);

                FileName = Helpers.ReadString(Data, (int)(FilenameOffset + Head.StringTableOffset + 32));

                if (Helpers.ReadString(Head.FileData, (int)(Head.DataStartOffset + DataOffset + 32), 4) == "Yaz0")
                {
                    IsCompressed = true;
                }
                else
                {
                    IsCompressed = false;
                }

                Header   = Head;
                fileData = GetFileData_OLD();
            }
示例#3
0
            public RARCHeader(RARC BR, byte[] Data, ref FileNode Root)
            {
                BaseRARC = BR;

                Tag               = Helpers.ReadString(Data, 0, 4);
                FileSize          = Helpers.Read32(Data, 4);
                DataStartOffset   = Helpers.Read32(Data, 12);
                NumNodes          = Helpers.Read32(Data, 32);
                FileEntriesOffset = Helpers.Read32(Data, 44);
                StringTableOffset = Helpers.Read32(Data, 52);

                FileData = Data;

                Root = new FileNode(BaseRARC, Data, 0, this);
            }
示例#4
0
        public ZeldaArc(string File, TreeView TV, bool IgnoreModels = false)
        {
            Archive = new RARC(File);
            DZRs = new List<DZx>();
            DZSs = new List<DZx>();
            DZBs = new List<DZB>();
            J3Dxs = new List<J3Dx>();

            TreeNode NewNode = Helpers.CreateTreeNode(Archive.Filename, null);
            PopulateFileList(NewNode, Archive.Root, IgnoreModels);
            //TV.Nodes[TV.Nodes.Count - 1].Expand();
            //TV.SelectedNode = TV.Nodes[TV.Nodes.Count - 1];
            TV.Nodes.Add(NewNode);

            Filename = File;
        }
示例#5
0
文件: RARC.cs 项目: pho/WindViewer
            public RARCHeader(RARC BR, byte[] Data, ref FileNode Root)
            {
                BaseRARC = BR;

                Tag = Helpers.ReadString(Data, 0, 4);
                FileSize = Helpers.Read32(Data, 4);
                DataStartOffset = Helpers.Read32(Data, 12);
                NumNodes = Helpers.Read32(Data, 32);
                FileEntriesOffset = Helpers.Read32(Data, 44);
                StringTableOffset = Helpers.Read32(Data, 52);

                FileData = Data;

                Root = new FileNode(BaseRARC, Data, 0, this);
            }
示例#6
0
文件: RARC.cs 项目: pho/WindViewer
            public FileNode(RARC BR, byte[] Data, UInt32 Offset, RARCHeader Header)
            {
                BaseRARC = BR;

                Offset = RARCHeader.Size + (Offset * Size);

                Tag = Helpers.ReadString(Data, (int)Offset, 4);
                FilenameOffset = Helpers.Read32(Data, (int)Offset + 4);
                NumFileEntries = Helpers.Read16(Data, (int)Offset + 10);
                FirstFileEntryOffset = Helpers.Read32(Data, (int)Offset + 12);

                NodeName = Helpers.ReadString(Data, (int)(FilenameOffset + Header.StringTableOffset + 32));
                Console.WriteLine("Reading node: " + NodeName);
                for (int i = 0; i < NumFileEntries; ++i)
                {
                    UInt32 ReadOffset = (UInt32)(Header.FileEntriesOffset + (FirstFileEntryOffset * FileEntry.Size) + (i * FileEntry.Size) + 32);
                    FileEntry CurrentFile = new FileEntry(BaseRARC, Data, ReadOffset, Header);
                    Console.WriteLine("Found fileEntry: " + CurrentFile.FileName);
                    if (CurrentFile.ID == 0xFFFF || CurrentFile.Unknown2 == 0x0200)         // 0x2000 correct???
                    {
                        if (CurrentFile.FilenameOffset != 0 && CurrentFile.FilenameOffset != 2)
                            ChildNodes.Add(new FileNode(BaseRARC, Data, CurrentFile.DataOffset, Header));
                    }
                    else
                        Files.Add(CurrentFile);
                }
            }
示例#7
0
文件: RARC.cs 项目: pho/WindViewer
            public FileEntry(RARC BR, byte[] Data, UInt32 Offset, RARCHeader Head)
            {
                BaseRARC = BR;

                ID = Helpers.Read16(Data, (int)Offset);
                Unknown1 = Helpers.Read16(Data, (int)Offset + 2);
                Unknown2 = Helpers.Read16(Data, (int)Offset + 4);
                FilenameOffset = Helpers.Read16(Data, (int)Offset + 6);
                DataOffset = Helpers.Read32(Data, (int)Offset + 8);
                DataSize = Helpers.Read32(Data, (int)Offset + 12);

                FileName = Helpers.ReadString(Data, (int)(FilenameOffset + Head.StringTableOffset + 32));

                if (Helpers.ReadString(Head.FileData, (int)(Head.DataStartOffset + DataOffset + 32), 4) == "Yaz0")
                    IsCompressed = true;
                else
                    IsCompressed = false;

                Header = Head;
                fileData = GetFileData_OLD();
            }
示例#8
0
        private void PopulateFileList(TreeNode TN, RARC.FileNode ParentFN, bool IgnoreModels)
        {
            foreach (RARC.FileNode ChildFN in ParentFN.ChildNodes)
                PopulateFileList(TN, ChildFN, IgnoreModels);

            foreach (RARC.FileEntry FE in ParentFN.Files)
            {
                if (J3Dx.ValidExtensions.Contains(Path.GetExtension(FE.FileName)) && IgnoreModels == false)
                    J3Dxs.Add(new J3Dx(FE, TN));

                else if (Path.GetExtension(FE.FileName) == ".dzr")
                    DZRs.Add(new DZx(FE, TN, this));

                else if (Path.GetExtension(FE.FileName) == ".dzs")
                    DZSs.Add(new DZx(FE, TN, this));

                else if (Path.GetExtension(FE.FileName) == ".dzb")
                    DZBs.Add(new DZB(FE, TN));
            }
        }
示例#9
0
        public static void CreateNodes(RARC.FileNode n)
        {
            Console.WriteLine("Creating Node for " + n.NodeName);
            string dirName = n.NodeName;
            dirName = dirName.ToUpper();
            for (int c = 0; c < dirName.Length; c++) {
                if (c == 4)
                    break;
                nodes[numNodesDone].type = nodes[numNodesDone].type + dirName[c];

            }
            nodes[numNodesDone].filenameOffset = (uint)stringTable.Length;
            stringTable = stringTable + dirName.ToLower() + (char)0x00;
            int numFiles = n.Files.Count;
            nodes[numNodesDone].numFileEntries = (ushort)(numFiles + 2);
            nodes[numNodesDone].firstFileEntryOffset = (uint)totalNumFilesAdded;

            dirName = n.NodeName;
            nodes[numNodesDone].foldernameHash = Hash(dirName);

            numNodesDone++;
        }
示例#10
0
        public static void CreateNodeEntries(RARC.FileNode Root)
        {
            foreach (RARC.FileNode n in Root.ChildNodes) {
                Console.WriteLine("Creating fileEntry for node " + n.NodeName);

                fileEntries[totalNumFilesAdded].id = 0xFFFF;
                fileEntries[totalNumFilesAdded].unknown2 = 0x0200;
                fileEntries[totalNumFilesAdded].filenameOffset = (ushort)0xFFFE;
                string fileName = n.NodeName;
                fileEntries[totalNumFilesAdded].filenameHash = Hash(fileName);
                fileEntries[totalNumFilesAdded].dataOffset = (uint)0xFFFE;
                fileEntries[totalNumFilesAdded].dataSize = 0x10;

                totalNumFilesAdded++;

            }
        }
示例#11
0
        public static void CreateFileEntries(RARC.FileNode Root)
        {
            foreach (RARC.FileEntry f in Root.Files) {
                Console.WriteLine("Creating fileEntry for " + f.FileName);
                fileEntries[totalNumFilesAdded].id = (ushort)totalNumFilesAdded;

                if (f.FileName.EndsWith(".szs"))//Check if szs file and use right.. marker?
                    fileEntries[totalNumFilesAdded].unknown2 = 0x9500;
                else
                    fileEntries[totalNumFilesAdded].unknown2 = 0x1100;

                fileEntries[totalNumFilesAdded].filenameOffset = (ushort)stringTable.Length;
                string fileName = f.FileName;
                stringTable = stringTable + fileName + (char)0x00;
                fileEntries[totalNumFilesAdded].filenameHash = Hash(fileName);

                fileEntries[totalNumFilesAdded].dataOffset = lengthOfDataTable;
                lengthOfDataTable += (uint)f.fileData.Length;
                //Pad the data table out so new files start at a 0-based address
                while ((lengthOfDataTable % 16) != 0)
                    lengthOfDataTable++;
                if ((lengthOfDataTable % 32) != 0)//Check the new address is a multiple of 32 and add 16 if not
                    lengthOfDataTable += 16;
                filesData[numFilesWithData] = f.fileData;

                fileEntries[totalNumFilesAdded].dataSize = (uint)f.fileData.Length;

                numFilesWithData++;
                totalNumFilesAdded++;
            }
        }
示例#12
0
        public static void CreateEntries(RARC.FileNode Root)
        {
            CreateFileEntries(Root);
            CreateNodeEntries(Root);

            CreateDummyFiles();

            foreach (RARC.FileNode n in Root.ChildNodes) {
                CreateNodes(n);
                CreateEntries(n);

            }
        }
示例#13
0
        public static int countRARCFiles(RARC.FileNode Root)
        {
            int count = 0;
            foreach (RARC.FileEntry f in Root.Files) {
                Console.WriteLine("File: " + f.FileName);
                count++;
            }

            foreach (RARC.FileNode n in Root.ChildNodes) {
                count += countRARCFiles (n);
            }

            return count;
        }
示例#14
0
        public static int countRARCDirs(RARC.FileNode Root)
        {
            int count = 0;
            foreach (RARC.FileNode n in Root.ChildNodes) {
                Console.WriteLine("Node: " + n.NodeName);
                count++;
                count += countRARCDirs (n);
            }

            return count;
        }
示例#15
0
        public static void CompressRARC(string FullPath, RARC.FileNode Root)
        {
            Console.WriteLine("\n>> Compressing " + Root.NodeName + " to " + FullPath);
            string newFile = Root.NodeName;

            stringTable = CreateStringTable();//Setup the string table

            int directoriesCount = countRARCDirs(Root);
            nodes = new Node[directoriesCount + 1]; //Add 1 for the ROOT node

            numNodesDone = 0;
            numFilesWithData = 0;
            lengthOfDataTable = 0;

            //Fill out the ROOT node
            nodes[0].type = "ROOT";

            nodes[0].filenameOffset = (uint)stringTable.Length;
            String rootDirName = newFile;
            stringTable = stringTable + rootDirName + (char)0x00;

            nodes[0].foldernameHash = Hash(rootDirName);

            int filesCount = countRARCFiles (Root);
            nodes[0].numFileEntries = (ushort)(filesCount + 2);

            nodes[0].firstFileEntryOffset = 0;

            numNodesDone++; //One node is complete

            //Get the total number of subdirectories and files
            //string[] allFiles = Directory.GetFiles(args[0], "*", SearchOption.AllDirectories);
            //int numOfFilesAndDirs = allFiles.Length + directoriesCount;
            int numOfFilesAndDirs = filesCount + directoriesCount;

            //Now set up an array of FileEntrys(Taking into account the "." and ".." file entries for each folder
            fileEntries = new FileEntry[numOfFilesAndDirs + (directoriesCount * 2) + 2];
            Console.WriteLine("# fileEntries " + (numOfFilesAndDirs + (directoriesCount * 2) + 2));

            filesData = new byte[filesCount][]; //Setup an array to store all the file data paths in
            totalNumFilesAdded = 0; //How many file entries have been done

            CreateEntries(Root);

            //Fill out the filename & data offsets for the folder entries with the offset from the appropriate Node
            for (int n = 0; n < totalNumFilesAdded; n++)
            {
                if (fileEntries[n].filenameOffset == 0xFFFE)
                {
                    uint nodeNum = 0;
                    foreach (Node node in nodes)
                    {
                        if (node.foldernameHash == fileEntries[n].filenameHash)
                        {
                            fileEntries[n].filenameOffset = (ushort)node.filenameOffset;
                            fileEntries[n].dataOffset = nodeNum;
                        }
                        nodeNum++;
                    }
                }
            }

            //Make the data table a mutiple of 16
            int numOfPaddingBytes = 0;
            while ((lengthOfDataTable % 16) != 0)
            {
                lengthOfDataTable++;
                numOfPaddingBytes++;
            }

            //Fill out Header information
            RarcHeader header = new RarcHeader();
            header.type = "RARC";
            header.numFiles1 = (uint)totalNumFilesAdded;
            header.numFiles2 = (ushort)totalNumFilesAdded;
            header.sizeOfDataTable1 = lengthOfDataTable;
            header.sizeOfDataTable2 = lengthOfDataTable;
            header.unknown1 = 0x20;
            header.unknown6 = 0x20;
            header.unknown8 = 0x100;

            header.fileEntriesOffset = (numNodesDone * 16) + 0x20;
            if ((header.fileEntriesOffset % 32) != 0)//Check if it's a multiple of 32 and make it one if it's not
                header.fileEntriesOffset += 16;

            Console.WriteLine("fileEntriesOffset is: " + header.fileEntriesOffset);
            Console.WriteLine("totalNumFilesAdded: " + (totalNumFilesAdded+1));
            header.numNodes = numNodesDone;

            int numFileEntries = (numOfFilesAndDirs + (directoriesCount * 2) + 2);

            int x = 0;
            while (0 != (((numFileEntries) * 20) + x) % 16)
                x++;

            header.stringTableOffset = header.fileEntriesOffset + (uint)((numFileEntries * 20) + x);
            if ((header.stringTableOffset % 32) != 0)//Check if it's a multiple of 32 and make it one if it's not
                header.stringTableOffset += 16;

            Console.WriteLine("stringTableOffset is: " + header.stringTableOffset);

            while (0 != (stringTable.Length) % 16)//Pad out the string table so the data table starts at a 0based address
                stringTable = stringTable + (char)0x00;

            header.dataStartOffset = (uint)(header.stringTableOffset + stringTable.Length);
            if ((header.dataStartOffset % 32) != 0)//Check if it's a multiple of 32 and make it one if it's not
                header.dataStartOffset += 16;

            Console.WriteLine("dataStartOffset is: " + header.dataStartOffset);

            header.sizeOfStringTable = (uint)stringTable.Length;
            header.size = lengthOfDataTable + header.dataStartOffset + 0x20;

            //Let's write it out

            // Uncomment while testing
            //FullPath += ".new.arc";

            FileStream filestreamWriter = new FileStream(FullPath, FileMode.Create);
            BinaryWriter binWriter = new BinaryWriter(filestreamWriter);

            Console.WriteLine("Writing to file: " + FullPath);
            Console.WriteLine("Writing header...");
            //First the Header is written
            binWriter.Write(header.type[0]);
            binWriter.Write(header.type[1]);
            binWriter.Write(header.type[2]);
            binWriter.Write(header.type[3]);

            byte[] buffer = BitConverter.GetBytes(header.size);
            Array.Reverse(buffer);
            filestreamWriter.Write(buffer, 0, buffer.Length);

            buffer = BitConverter.GetBytes(header.unknown1);
            Array.Reverse(buffer);
            filestreamWriter.Write(buffer, 0, buffer.Length);

            buffer = BitConverter.GetBytes(header.dataStartOffset);
            Array.Reverse(buffer);
            filestreamWriter.Write(buffer, 0, buffer.Length);

            buffer = BitConverter.GetBytes(header.sizeOfDataTable1);
            Array.Reverse(buffer);
            filestreamWriter.Write(buffer, 0, buffer.Length);

            buffer = BitConverter.GetBytes(header.sizeOfDataTable2);
            Array.Reverse(buffer);
            filestreamWriter.Write(buffer, 0, buffer.Length);

            buffer = BitConverter.GetBytes(header.unknown4);
            Array.Reverse(buffer);
            filestreamWriter.Write(buffer, 0, buffer.Length);

            buffer = BitConverter.GetBytes(header.unknown5);
            Array.Reverse(buffer);
            filestreamWriter.Write(buffer, 0, buffer.Length);

            buffer = BitConverter.GetBytes(header.numNodes);
            Array.Reverse(buffer);
            filestreamWriter.Write(buffer, 0, buffer.Length);

            buffer = BitConverter.GetBytes(header.unknown6);
            Array.Reverse(buffer);
            filestreamWriter.Write(buffer, 0, buffer.Length);

            buffer = BitConverter.GetBytes(header.numFiles1);
            Array.Reverse(buffer);
            filestreamWriter.Write(buffer, 0, buffer.Length);

            buffer = BitConverter.GetBytes(header.fileEntriesOffset);
            Array.Reverse(buffer);
            filestreamWriter.Write(buffer, 0, buffer.Length);

            buffer = BitConverter.GetBytes(header.sizeOfStringTable);
            Array.Reverse(buffer);
            filestreamWriter.Write(buffer, 0, buffer.Length);

            buffer = BitConverter.GetBytes(header.stringTableOffset);
            Array.Reverse(buffer);
            filestreamWriter.Write(buffer, 0, buffer.Length);

            buffer = BitConverter.GetBytes(header.numFiles2);
            Array.Reverse(buffer);
            filestreamWriter.Write(buffer, 0, buffer.Length);

            buffer = BitConverter.GetBytes(header.unknown8);
            Array.Reverse(buffer);
            filestreamWriter.Write(buffer, 0, buffer.Length);

            buffer = BitConverter.GetBytes(header.unknown9);
            Array.Reverse(buffer);
            filestreamWriter.Write(buffer, 0, buffer.Length);

            Console.WriteLine("Writing nodes...");
            //Write each of the nodes
            foreach (Node currentNode in nodes)
            {
                Console.WriteLine("Writing " + currentNode.type);
                binWriter.Write(currentNode.type[0]);
                if (currentNode.type.Length > 1)       //Incase the dirname is only 1 char long
                    binWriter.Write(currentNode.type[1]);
                else
                    filestreamWriter.WriteByte(0x20);
                if (currentNode.type.Length > 2)       //Incase the dirname is only 2 char long
                    binWriter.Write(currentNode.type[2]);
                else
                    filestreamWriter.WriteByte(0x20);
                if (currentNode.type.Length == 4)       //Incase the dirname is only 3 char long
                    binWriter.Write(currentNode.type[3]);
                else
                    filestreamWriter.WriteByte(0x20);

                buffer = BitConverter.GetBytes(currentNode.filenameOffset);
                Array.Reverse(buffer);
                filestreamWriter.Write(buffer, 0, buffer.Length);
                buffer = BitConverter.GetBytes(currentNode.foldernameHash);
                Array.Reverse(buffer);
                filestreamWriter.Write(buffer, 0, buffer.Length);
                buffer = BitConverter.GetBytes(currentNode.numFileEntries);
                Array.Reverse(buffer);
                filestreamWriter.Write(buffer, 0, buffer.Length);
                buffer = BitConverter.GetBytes(currentNode.firstFileEntryOffset);
                Array.Reverse(buffer);
                filestreamWriter.Write(buffer, 0, buffer.Length);
            }

            //Pad out the file to get the file entries at their correct offset
            while (filestreamWriter.Position < (header.fileEntriesOffset + 32))
            {
                filestreamWriter.WriteByte(0x00);
            }

            //Write all the file entries
            foreach (FileEntry entry in fileEntries)
            {
                Console.WriteLine(String.Format("Writing fileEntry {0:X6}",entry.filenameOffset));

                buffer = BitConverter.GetBytes(entry.id);
                Array.Reverse(buffer);
                filestreamWriter.Write(buffer, 0, buffer.Length);

                buffer = BitConverter.GetBytes(entry.filenameHash);
                Array.Reverse(buffer);
                filestreamWriter.Write(buffer, 0, buffer.Length);

                buffer = BitConverter.GetBytes(entry.unknown2);
                Array.Reverse(buffer);
                filestreamWriter.Write(buffer, 0, buffer.Length);

                buffer = BitConverter.GetBytes(entry.filenameOffset);
                Array.Reverse(buffer);
                filestreamWriter.Write(buffer, 0, buffer.Length);

                buffer = BitConverter.GetBytes(entry.dataOffset);
                Array.Reverse(buffer);
                filestreamWriter.Write(buffer, 0, buffer.Length);

                buffer = BitConverter.GetBytes(entry.dataSize);
                Array.Reverse(buffer);
                filestreamWriter.Write(buffer, 0, buffer.Length);

                buffer = BitConverter.GetBytes(entry.zero);
                Array.Reverse(buffer);
                filestreamWriter.Write(buffer, 0, buffer.Length);
            }

            //Pad out the file to get the string table at its correct offset

            while (filestreamWriter.Position < (header.stringTableOffset + 32))
            {
               filestreamWriter.WriteByte(0x00);
            }

            //Write string table
            Encoding enc = Encoding.UTF8;
            binWriter.Write(enc.GetBytes(stringTable));

            //Pad out the file to get the data table at its correct offset
            while (filestreamWriter.Position < (header.dataStartOffset + 32))
            {
                filestreamWriter.WriteByte(0x00);
            }

            //Write files data
            foreach (byte[] file in filesData)
            {
                Console.WriteLine("Dumping file data...");
                buffer = file;
                filestreamWriter.Write(buffer, 0, buffer.Length);
                while ((filestreamWriter.Position % 32) != 0)//Pad out the data so the next file begins on a 0-based multiple of 32
                    filestreamWriter.WriteByte(0x00);
            }
            for (int pad = 0; pad < numOfPaddingBytes; pad++)//Write the bytes neccessary to make the entire file divisble by 32
                filestreamWriter.WriteByte(0x00);

            binWriter.Close();
            filestreamWriter.Close();

            Console.WriteLine("Packed and good to go!");
        }