コード例 #1
0
        public static void Main(string[] args)
        {
            string  filepath = @"D:\Download\4722_Ragnarok_NDS-VENOM\v-ragnar.nds";
            NDSFile nds      = new NDSFile(filepath);

            ExtractNodes(nds.Files);
        }
コード例 #2
0
        public static bool Check(NDSFile file)
        {
            if (Path.GetExtension(file.Name) != ".bin")
            {
                return(false);
            }
            // The theoretical minimum size for a text table is the text count + first text address
            // + null byte as the first text.
            const uint minimumSize = sizeof(uint) + sizeof(uint) + 1;

            if (file.LatestVersionSize < minimumSize)
            {
                return(false);
            }
            return(true);
        }
コード例 #3
0
 public static bool Check(NDSFile file)
 {
     return(Path.GetExtension(file.Name) == ".sdat");
 }
コード例 #4
0
        private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = (BackgroundWorker)sender;

            worker.ReportProgress(0, new Tuple <int, string, int, int>(0, "Reading System Files", 0, 0));

            string fsPath = path + "\\" + "File System";

            try
            {
                Directory.CreateDirectory(fsPath);
            }
            catch (Exception exception)
            {
                DialogResult dialog = CustomMessageBox.Show(
                    exception.Message,
                    exception.GetType().ToString(),
                    400,
                    new List <string>(),
                    new List <DialogResult>());

                return;
            }

            if (worker.CancellationPending)
            {
                e.Cancel = true;
                return;
            }

            File.Copy(file, path + "\\" + "[" + code + "] " + title + ".nds");

            using (MemoryStream romStream = new MemoryStream(File.ReadAllBytes(file)))
            {
                using (BinaryReader romReader = new BinaryReader(romStream))
                {
                    romReader.BaseStream.Position = 32;
                    int arm9Offset = Convert.ToInt32(romReader.ReadUInt32());
                    romReader.BaseStream.Position = 44;
                    int arm9Length = Convert.ToInt32(romReader.ReadUInt32());
                    int arm7Offset = Convert.ToInt32(romReader.ReadUInt32());
                    romReader.BaseStream.Position = 60;
                    int arm7Length = Convert.ToInt32(romReader.ReadUInt32());
                    int fntOffset  = Convert.ToInt32(romReader.ReadUInt32());
                    int fntLength  = Convert.ToInt32(romReader.ReadUInt32());
                    int fatOffset  = Convert.ToInt32(romReader.ReadUInt32());
                    int fatLength  = Convert.ToInt32(romReader.ReadUInt32());
                    int oat9Offset = Convert.ToInt32(romReader.ReadUInt32());
                    int oat9Length = Convert.ToInt32(romReader.ReadUInt32());
                    int oat7Offset = Convert.ToInt32(romReader.ReadUInt32());
                    int oat7Length = Convert.ToInt32(romReader.ReadUInt32());
                    romReader.BaseStream.Position = 104;
                    int bnrOffset = Convert.ToInt32(romReader.ReadUInt32());
                    romReader.BaseStream.Position = bnrOffset;
                    int bnrLength = Convert.ToInt32(romReader.ReadUInt16());
                    switch (bnrLength)
                    {
                    case 1:
                        bnrLength = 2112;
                        break;

                    case 2:
                        bnrLength = 2112;
                        break;

                    case 3:
                        bnrLength = 3072;
                        break;

                    case 259:
                        bnrLength = 9216;
                        break;
                    }

                    byte[] fntArray = new byte[fntLength];
                    byte[] fatArray = new byte[fatLength];

                    romReader.BaseStream.Position = fntOffset;
                    romReader.Read(fntArray, 0, fntLength);
                    romReader.BaseStream.Position = fatOffset;
                    romReader.Read(fatArray, 0, fatLength);

                    if (fatArray.Count() % 8 > 0)
                    {
                        // Exception handling for rewrite later.
                        throw new Exception(
                                  "Table length must be a multiple of 8. This table has a length of " + fatArray.Count() + "."
                                  + "\n " + fatArray.Count() + " ÷ 8 = " + (fatArray.Count() / 8)
                                  + "\n Remainder: " + (fatArray.Count() % 8)
                                  );
                    }

                    List <NDSFile> fileList = new List <NDSFile>();
                    fileList.Add(new NDSFile("Header", "", "", 0, 16384));
                    fileList.Add(new NDSFile("File Name Table", "", "", fntOffset, fntLength));
                    fileList.Add(new NDSFile("File Allocation Table", "", "", fatOffset, fatLength));
                    fileList.Add(new NDSFile("Banner", "", ".bnr", bnrOffset, bnrLength));
                    fileList.Add(new NDSFile("ARM9 Binary", "", ".bin", arm9Offset, arm9Length));
                    fileList.Add(new NDSFile("ARM9 Overlay Table", "", "", oat9Offset, oat9Length));
                    if (arm7Length > 0)
                    {
                        fileList.Add(new NDSFile("ARM7 Binary", "", ".bin", arm7Offset, arm9Length));
                    }
                    if (oat7Length > 0)
                    {
                        fileList.Add(new NDSFile("ARM7 Overlay Table", "", "", oat7Offset, oat9Length));
                    }

                    int directoryCount = BitConverter.ToUInt16(fntArray, 6);
                    int firstFile      = BitConverter.ToInt16(fntArray, 4);
                    int fileCount      = fatArray.Count() / 8;
                    int workload       = (fileCount * 4) + (directoryCount * 2);
                    int progress       = 0;

                    worker.ReportProgress(workload, new Tuple <int, string, int, int>(progress, "Reading File Name And Allocation Tables", fileCount, 0));
                    NDSFile[] files = new NDSFile[fileCount];

                    for (int i = 0; i < fileCount; i++)
                    {
                        if (worker.CancellationPending)
                        {
                            e.Cancel = true;
                            return;
                        }

                        files[i] = new NDSFile();
                        NDSFile currentFile = files[i];
                        files[i].Offset = Convert.ToInt32(BitConverter.ToUInt32(fatArray, i * 8));
                        files[i].Length = Convert.ToInt32(BitConverter.ToUInt32(fatArray, i * 8 + 4)) - files[i].Offset;

                        progress++;
                        worker.ReportProgress(workload, new Tuple <int, string, int, int>(progress, "Reading File Allocation Table", fileCount, i + 1));
                    }

                    worker.ReportProgress(workload, new Tuple <int, string, int, int>(progress, "Reading Overlay Allocation Table", firstFile, 0));

                    string[]      directories;
                    List <string> dirList = new List <string>();
                    directories = new string[directoryCount];
                    if (firstFile > 0)
                    {
                        directories[0] = "\\Root";
                        dirList.Add("\\Overlays");
                        for (int i = 0; i < firstFile; i++)
                        {
                            if (worker.CancellationPending)
                            {
                                e.Cancel = true;
                                return;
                            }

                            files[i].Name = "Overlay " + i.ToString("D" + firstFile.ToString().Length) + ".bin";
                            files[i].Path = "\\Overlays";

                            progress++;
                            worker.ReportProgress(workload, new Tuple <int, string, int, int>(progress, "Reading Overlay Allocation Table", firstFile, i + 1));
                        }
                    }
                    else
                    {
                        directories[0] = "";
                    }

                    worker.ReportProgress(workload, new Tuple <int, string, int, int>(progress, "Reading File Name Table", fileCount + directoryCount, 0));

                    int unnamedCount = 0;
                    int dirProgress  = 0;
                    int fileProgress = 0;

                    for (int i = 0; i < directoryCount; i++)
                    {
                        int entryPos  = Convert.ToInt32(BitConverter.ToUInt32(fntArray, i * 8));
                        int fileIndex = Convert.ToInt32(BitConverter.ToUInt16(fntArray, (i * 8) + 4));

                        while (true)
                        {
                            if (worker.CancellationPending)
                            {
                                e.Cancel = true;
                                return;
                            }

                            byte entryByte = fntArray[entryPos++];

                            if (entryByte == 0)
                            {
                                break;
                            }

                            else if (entryByte == 128)
                            {
                                int index = BitConverter.ToUInt16(fntArray, entryPos) - 61440;
                                directories[index] = directories[i] + "\\Unnamed " + unnamedCount++;
                                dirProgress++;
                                entryPos += 2;
                            }

                            else if (entryByte > 128)
                            {
                                int index = BitConverter.ToUInt16(fntArray, (entryPos) + (entryByte - 128)) - 61440;
                                directories[index] = directories[i] + "\\" + System.Text.Encoding.UTF8.GetString(fntArray, entryPos, entryByte - 128);
                                dirProgress++;
                                entryPos += (entryByte - 128) + 2;
                            }

                            else
                            {
                                files[fileIndex].Name = System.Text.Encoding.UTF8.GetString(fntArray, entryPos, entryByte);
                                files[fileIndex].Path = directories[i];
                                fileIndex++;
                                fileProgress++;
                                entryPos += entryByte;
                            }

                            progress++;
                            worker.ReportProgress(workload, new Tuple <int, string, int, int>(progress, "Reading File Name Table", fileCount + directoryCount, dirProgress + fileProgress));
                        }
                    }

                    worker.ReportProgress(workload, new Tuple <int, string, int, int>(progress, "Getting File Extensions", fileCount, 0));

                    fileList.AddRange(files.ToList());
                    dirList.AddRange(directories.ToList());
                    files       = null;
                    directories = null;
                    List <NDSFile> narcList = new List <NDSFile>();
                    for (int i = 0; i < fileCount; i++)
                    {
                        if (worker.CancellationPending)
                        {
                            e.Cancel = true;
                            return;
                        }

                        NDSFile file = fileList[i];
                        file.GetExtension(romStream);

                        if (file.Extension == ".narc")
                        {
                            narcList.Add(file);
                            workload++;
                        }

                        progress++;
                        worker.ReportProgress(workload, new Tuple <int, string, int, int>(progress, "Getting File Extensions", fileCount, i + 1));
                    }

                    worker.ReportProgress(workload, new Tuple <int, string, int, int>(progress, "Reading NARC Files", directoryCount, 0));

                    if (narcList.Count > 0)
                    {
                        for (int i = 0; i < narcList.Count; i++)
                        {
                            if (worker.CancellationPending)
                            {
                                e.Cancel = true;
                                return;
                            }

                            NDSFile file = narcList[i];
                            NARC    narc = new NARC(romStream, file);
                            if (narc.isValid)
                            {
                                fileList.Remove(file);
                                dirList.AddRange(narc.dirList);
                                fileList.AddRange(narc.fileList);
                            }

                            progress++;
                            worker.ReportProgress(workload, new Tuple <int, string, int, int>(progress, "Reading NARC Files", narcList.Count, i + 1));
                        }
                    }

                    worker.ReportProgress(workload, new Tuple <int, string, int, int>(progress, "Writing Folder Structure", directoryCount, 0));

                    double compWorkload = directoryCount / dirList.Count;
                    for (int i = 0; i < dirList.Count; i++)
                    {
                        if (worker.CancellationPending)
                        {
                            e.Cancel = true;
                            return;
                        }

                        Directory.CreateDirectory(fsPath + dirList[i]);

                        int p = Convert.ToInt32((i + 1) * compWorkload);
                        worker.ReportProgress(workload, new Tuple <int, string, int, int>(progress + p, "Writing Folder Structure", directoryCount, (int)((i + 1) * compWorkload)));
                    }

                    progress += directoryCount;
                    worker.ReportProgress(workload, new Tuple <int, string, int, int>(progress, "Extracting Files", fileList.Count, 0));

                    compWorkload = (double)fileCount / (double)fileList.Count;
                    for (int i = 0; i < fileList.Count; i++)
                    {
                        if (worker.CancellationPending)
                        {
                            e.Cancel = true;
                            return;
                        }

                        NDSFile file = fileList[i];
                        romReader.BaseStream.Position = file.Offset;
                        byte[] image = new byte[file.Length];
                        romReader.Read(image, 0, file.Length);

                        Directory.CreateDirectory(path + "\\Text Files");
                        if (file.Path == "\\Root\\a\\0\\2\\7.narc")
                        {
                            PokeTextIV TextFile = new PokeTextIV(romStream, file);

                            System.IO.File.WriteAllLines(path + "\\Text Files\\" + file.Name + ".txt", TextFile.StringList);
                        }

                        /*
                         * using ( BinaryWriter writer = new BinaryWriter(File.Open(fsPath + file.Path + "\\" + file.Name + file.Extension, FileMode.Create)) )
                         * {
                         *      writer.Write(image, 0, file.Length);
                         * }
                         */

                        int p = Convert.ToInt32((i + 1) * compWorkload);
                        worker.ReportProgress(workload, new Tuple <int, string, int, int>(progress + p, "Extracting Files", fileList.Count, (i + 1)));
                    }
                }
            }
        }