예제 #1
0
        public void CreateFromSectionPathInvalidArgsThrows()
        {
            string tempFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());

            try {
                using (var stream = new FileStream(tempFile, FileMode.CreateNew)) {
                    stream.WriteByte(0xCA);
                    stream.WriteByte(0xFE);
                }

                Assert.Throws <ArgumentNullException>(() =>
                                                      DataStreamFactory.FromFile(null, FileOpenMode.Append, 0, 0));
                Assert.Throws <ArgumentNullException>(() =>
                                                      DataStreamFactory.FromFile(string.Empty, FileOpenMode.Append, 0, 0));
                Assert.Throws <ArgumentOutOfRangeException>(() =>
                                                            DataStreamFactory.FromFile(tempFile, FileOpenMode.Read, -1, 0));
                Assert.Throws <ArgumentOutOfRangeException>(() =>
                                                            DataStreamFactory.FromFile(tempFile, FileOpenMode.Read, 3, 0));
                Assert.Throws <ArgumentOutOfRangeException>(() =>
                                                            DataStreamFactory.FromFile(tempFile, FileOpenMode.Read, 0, -1));
                Assert.Throws <ArgumentOutOfRangeException>(() =>
                                                            DataStreamFactory.FromFile(tempFile, FileOpenMode.Read, 0, 3));
                Assert.Throws <ArgumentOutOfRangeException>(() =>
                                                            DataStreamFactory.FromFile(tempFile, FileOpenMode.Read, 1, 2));
            } finally {
                File.Delete(tempFile);
            }
        }
예제 #2
0
        public void CreateFromSectionPathDoesNotAllowToExpand()
        {
            string tempFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());

            int        beforeCount  = DataStream.ActiveStreams;
            FileStream createStream = null;
            DataStream writeStream  = null;

            try {
                createStream = new FileStream(tempFile, FileMode.CreateNew);
                createStream.WriteByte(0xCA);
                createStream.WriteByte(0xFE);
                createStream.WriteByte(0xAA);
                createStream.Dispose();
                createStream = null; // prevent two disposes

                writeStream          = DataStreamFactory.FromFile(tempFile, FileOpenMode.Write, 1, 2);
                writeStream.Position = 2;
                Assert.That(() => writeStream.WriteByte(0xB4), Throws.InvalidOperationException);
            } finally {
                createStream?.Dispose();
                writeStream?.Dispose();
                File.Delete(tempFile);
            }

            Assert.AreEqual(beforeCount, DataStream.ActiveStreams);
        }
예제 #3
0
        public static void TranslatePOwithAnotherPO(string BasePO, string TargetPo)
        {
            Po BPo = null, TPo = null;

            using (DataStream name = DataStreamFactory.FromFile(BasePO, FileOpenMode.Read))
                using (BinaryFormat binaryname = new BinaryFormat(name))
                {
                    BPo = (Po)ConvertFormat.With <Po2Binary>(binaryname);
                }

            using (DataStream name = DataStreamFactory.FromFile(TargetPo, FileOpenMode.Read))
                using (BinaryFormat binaryname = new BinaryFormat(name))
                {
                    TPo = (Po)ConvertFormat.With <Po2Binary>(binaryname);
                }

            foreach (PoEntry entryBPo in BPo.Entries)
            {
                foreach (PoEntry entryTPo in TPo.Entries)
                {
                    if (entryBPo.Original == entryTPo.Original && (entryBPo.Translated != null && entryBPo.Translated != ""))
                    {
                        entryTPo.Translated = entryBPo.Translated;

                        if (entryBPo.TranslatorComment != string.Empty && entryBPo.TranslatorComment != null && entryBPo.TranslatorComment.Trim() != "")
                        {
                            entryTPo.TranslatorComment = entryBPo.TranslatorComment;
                        }
                    }
                }
            }

            ConvertFormat.To <BinaryFormat>(TPo).Stream.WriteTo(TargetPo);
        }
예제 #4
0
        public void CreateFromPathWritesFile()
        {
            string tempFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());

            Assert.That(File.Exists(tempFile), Is.False);

            int        beforeCount = DataStream.ActiveStreams;
            DataStream writeStream = null;
            FileStream readStream  = null;

            try {
                writeStream = DataStreamFactory.FromFile(tempFile, FileOpenMode.Write);
                Assert.AreEqual(0x0, writeStream.Offset);
                Assert.AreEqual(0x0, writeStream.Length);
                Assert.AreEqual(0x0, writeStream.Position);
                writeStream.WriteByte(0xCA);
                writeStream.Dispose();
                writeStream = null; // prevent two dispose

                Assert.That(File.Exists(tempFile), Is.True);
                readStream = new FileStream(tempFile, FileMode.Open);
                Assert.AreEqual(0x1, readStream.Length);
                Assert.AreEqual(0xCA, readStream.ReadByte());
            } finally {
                writeStream?.Dispose();
                readStream?.Dispose();
                File.Delete(tempFile);
            }

            Assert.AreEqual(beforeCount, DataStream.ActiveStreams);
        }
예제 #5
0
        private static void Decrypt(Options.Decrypt opts)
        {
            WriteHeader();

            if (!File.Exists(opts.InputFile))
            {
                Console.WriteLine($"ERROR: \"{opts.InputFile}\" not found!!!!");
                return;
            }

            if (File.Exists(opts.OutputFile))
            {
                Console.WriteLine($"WARNING: \"{opts.OutputFile}\" already exists. It will be overwritten.");
                Console.Write("Continue? (y/N) ");
                string answer = Console.ReadLine();
                if (!string.IsNullOrEmpty(answer) && answer.ToUpperInvariant() != "Y")
                {
                    Console.WriteLine("CANCELLED BY USER.");
                    return;
                }
            }

            // Encryption uses 2 keys:
            // 1. First bytes in file, XORed with input file name without extension in upper case
            // 2. Fixed byte array.
            string fileWithoutExtension = Path.GetFileNameWithoutExtension(opts.InputFile).ToUpperInvariant();

            using DataStream input  = DataStreamFactory.FromFile(opts.InputFile, FileOpenMode.Read);
            using DataStream output = DataStreamFactory.FromMemory();

            Console.Write($"Decrypting '{opts.InputFile}'...");
            Decrypt(input, output, fileWithoutExtension);
            output.WriteTo(opts.OutputFile);
            Console.WriteLine(" DONE!");
        }
예제 #6
0
        public void CreateFromSectionPathReadsFile()
        {
            string tempFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());

            Assert.That(File.Exists(tempFile), Is.False);

            int        beforeCount = DataStream.ActiveStreams;
            FileStream writeStream = null;
            DataStream readStream  = null;

            try {
                writeStream = new FileStream(tempFile, FileMode.CreateNew);
                writeStream.WriteByte(0xCA);
                writeStream.WriteByte(0xFE);
                writeStream.WriteByte(0xAA);
                writeStream.Dispose();
                writeStream = null; // prevent two disposes

                readStream = DataStreamFactory.FromFile(tempFile, FileOpenMode.Read, 1, 2);
                Assert.IsNull(readStream.ParentDataStream);
                Assert.AreEqual(0x1, readStream.Offset);
                Assert.AreEqual(0x2, readStream.Length);
                Assert.AreEqual(0x0, readStream.Position);
                Assert.AreEqual(0xFE, readStream.ReadByte());
            } finally {
                writeStream?.Dispose();
                readStream?.Dispose();
                File.Delete(tempFile);
            }

            Assert.AreEqual(beforeCount, DataStream.ActiveStreams);
        }
        public override void ImportPo(string inputFile, bool save = true)
        {
            var dataStream = DataStreamFactory.FromFile(inputFile, FileOpenMode.Read);
            var binary     = new BinaryFormat(dataStream);
            var binary2Po  = new Yarhl.Media.Text.Po2Binary();
            var po         = binary2Po.Convert(binary);

            _text = GetText();
            var tmp = _text.Text.Replace(LineEnding.ShownLineEnding, LineEnding.PoLineEnding);

            if (string.IsNullOrEmpty(tmp))
            {
                tmp = "<!empty>";
            }
            var entry = po.FindEntry(tmp);

            if (!string.IsNullOrEmpty(entry.Translated))
            {
                _text.Translation = entry.Translated.Replace(LineEnding.PoLineEnding, LineEnding.ShownLineEnding);
            }

            if (save)
            {
                SaveChanges();
            }
        }
예제 #8
0
        public static BinaryFormat Lzss(BinaryFormat bf, string mode)
        {
            string tempFile = Path.GetTempFileName();

            if (mode == "-d")
            {
                using (var substream = new DataStream(bf.Stream, 4, bf.Stream.Length - 4))
                {
                    substream.WriteTo(tempFile);
                }
            }
            else
            {
                using (var substream = new DataStream(bf.Stream, 0, bf.Stream.Length))
                {
                    substream.WriteTo(tempFile);
                }
            }



            string program = System.IO.Path.GetFullPath(@"..\..\") + @"\lib\NDS_Compressors_CUE\lzss.exe";

            string arguments = mode + " " + tempFile;

            if (Environment.OSVersion.Platform != PlatformID.Win32NT)
            {
                program = System.IO.Path.GetFullPath(@"../../") + "/lib/NDS_Compressors_CUE/lzss";
            }

            Process process = new Process();

            process.StartInfo.FileName               = program;
            process.StartInfo.Arguments              = arguments;
            process.StartInfo.UseShellExecute        = false;
            process.StartInfo.CreateNoWindow         = true;
            process.StartInfo.ErrorDialog            = false;
            process.StartInfo.RedirectStandardOutput = true;
            process.Start();

            process.WaitForExit();

            DataStream fileStream   = DataStreamFactory.FromFile(tempFile, FileOpenMode.Read);
            DataStream memoryStream = new DataStream();

            if (mode != "-d")
            {
                memoryStream.Seek(0);
                memoryStream.Write(Encoding.ASCII.GetBytes("DSCP"), 0, 4);
            }

            fileStream.WriteTo(memoryStream);

            fileStream.Dispose();
            File.Delete(tempFile);

            return(new BinaryFormat(memoryStream));
        }
예제 #9
0
 public void CreateFromPathWithInvalidArgThrows()
 {
     Assert.That(
         () => DataStreamFactory.FromFile(null, FileOpenMode.Append),
         Throws.ArgumentNullException);
     Assert.That(
         () => DataStreamFactory.FromFile(string.Empty, FileOpenMode.Append),
         Throws.ArgumentNullException);
 }
예제 #10
0
        public static void Decrypt(string overlay19)
        {
            var config = new Configuration {
                OverlayRamAddress = 0x02159FE0,
                AddressOffset     = 0x2100,
                ConstantOffset    = 0x0215C1CC,
            };

            using (var stream = DataStreamFactory.FromFile(overlay19, FileOpenMode.ReadWrite)) {
                DecryptEntrypoints(stream, config);
                VerifyJumpChecksums(stream, config);
                DecryptApCode(stream, config);
                PredictCorrectAnswer();
            }
        }
        public void AddDictionary(string file)
        {
            if (!File.Exists(file))
            {
                throw new FileNotFoundException();
            }

            var openFile = new Yarhl.IO.TextReader(
                DataStreamFactory.FromFile(file, FileOpenMode.Read));

            if (openFile.Stream.Length == 0)
            {
                throw new Exception("The file is empty.");
            }

            var separatorLine = openFile.ReadLine();

            if (!separatorLine.Contains("separator="))
            {
                throw new Exception("The separator has not been set.");
            }

            if (separatorLine.Length != 11)
            {
                throw new Exception("The separator not support multiple chars like == or ::");
            }

            var separator = separatorLine[10];

            do
            {
                var line = openFile.ReadLine();

                if (string.IsNullOrWhiteSpace(line))
                {
                    continue;
                }

                var textSplit = line.Split(separator);

                if (textSplit.Length != 2)
                {
                    throw new Exception("The original or modified string contains the separator or is missing, please check your separator.");
                }

                replacer.Add(textSplit[0], textSplit[1]);
            } while (!openFile.Stream.EndOfStream);
        }
예제 #12
0
        public override void ImportPo(string inputFile, bool save = true, bool parallel = true)
        {
            var dataStream = DataStreamFactory.FromFile(inputFile, FileOpenMode.Read);
            var binary     = new BinaryFormat(dataStream);
            var binary2Po  = new Yarhl.Media.Text.Po2Binary();
            var po         = binary2Po.Convert(binary);

            LoadBeforeImport();
            foreach (var dataColumn in _data.Columns)
            {
                if (dataColumn.GetType().Name != nameof(Column) && dataColumn.DataCount > 0 && dataColumn.Size > 0)
                {
                    var values    = dataColumn.GetUniqueValues();
                    var newValues = new Dictionary <string, string>();
                    for (var i = 0; i < values.Count; i++)
                    {
                        var value    = values[i];
                        var original = value.Item1;

                        if (string.IsNullOrEmpty(original))
                        {
                            original = "<!empty>";
                        }

                        var tmp   = original.Replace(LineEnding.ShownLineEnding, LineEnding.PoLineEnding);
                        var entry = po.FindEntry(tmp, $"{dataColumn.Name}_{i}");

                        if (entry.Text == "<!empty>")
                        {
                            newValues.Add($"{dataColumn.Name}|{i}", value.Item1);
                        }
                        else
                        {
                            var tmp1 = entry.Translated;
                            tmp1 = string.IsNullOrEmpty(tmp1) ? value.Item1 : tmp1.Replace(LineEnding.PoLineEnding, LineEnding.ShownLineEnding);
                            newValues.Add($"{dataColumn.Name}|{i}", tmp1);
                        }
                    }

                    dataColumn.SetUniqueValues(newValues, true);
                }
            }

            if (save && NeedSaving)
            {
                SaveChanges();
            }
        }
예제 #13
0
        public void CreateFromPathAllowsToExpand()
        {
            string tempFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());

            int        beforeCount = DataStream.ActiveStreams;
            DataStream writeStream = null;

            try {
                writeStream = DataStreamFactory.FromFile(tempFile, FileOpenMode.Write);
                Assert.That(() => writeStream.WriteByte(0xCA), Throws.Nothing);
            } finally {
                writeStream?.Dispose();
                File.Delete(tempFile);
            }

            Assert.AreEqual(beforeCount, DataStream.ActiveStreams);
        }
예제 #14
0
        // Read the all text from a file ".po".
        public static List <string> ExtracTextFromPo(string PoAddress)
        {
            List <string> Text = new List <string>();

            Po     PoTranslated = null;
            string Sentence     = null;

            using (DataStream name = DataStreamFactory.FromFile(PoAddress, FileOpenMode.Read))
                using (BinaryFormat binaryname = new BinaryFormat(name))
                {
                    PoTranslated = (Po)ConvertFormat.With <Po2Binary>(binaryname);
                }

            foreach (PoEntry entry in PoTranslated.Entries)
            {
                if (entry.Original == "[EMPTY_LINE]" || entry.Translated == "[EMPTY_LINE]")
                {
                    Sentence = "";
                }
                else if (entry.Translated.Trim() != null && entry.Translated.Trim() != "")
                {
                    Sentence = entry.Translated;
                }
                else
                {
                    Sentence = entry.Original;
                }

                //Delete new extra lines and space. BND files are excluded from this.
                if (DRAT.eraseExtraLinefeedsToolStripMenuItem.Checked == true && Sentence != "" && Path.GetFileName(Path.GetDirectoryName(Path.GetDirectoryName(PoAddress))).ToLower() != "bnd")
                {
                    Sentence = Sentence.Trim();
                }

                if (Path.GetFileName(Path.GetDirectoryName(Path.GetDirectoryName(PoAddress))).ToLower() != "bnd" && Sentence != null && Sentence != "" && (DRAT.tabControl1.SelectedTab.Text.Contains("DRAE") || Path.GetFileNameWithoutExtension(PoAddress).ToLower().Contains("novel"))) // If the user is working on AE or with some Novel.
                {
                    Sentence += "\n";                                                                                                                                                                                                                                                      //Some files need it to be displayed in the right spot on the screen.
                }

                Text.Add(Sentence); //And finally save the sentence.
            }

            return(Text); // Return all the sentences.
        }
예제 #15
0
            public void TestPoContent()
            {
                var poFile   = DataStreamFactory.FromFile("Example.po", FileOpenMode.Read);
                var poBinary = new BinaryFormat(poFile);
                var po       = poBinary.Stream.ReadFormat <Po>();

                for (var i = 0; i < 7; i++)
                {
                    Assert.AreEqual(ExampleText[i], po.Entries[i].Original);
                    Assert.AreEqual(i + "|" + ExampleCharacters[i], po.Entries[i].Context);
                    Assert.AreEqual(ExampleCharacters[i], po.Entries[i].ExtractedComments);
                }


                Assert.AreEqual("Small kitty warm kitty little balls of fur" +
                                " meowwww and lick face hiss at owner, pee a lot," +
                                " and meow repeatedly scratch at fence purrrrrr" +
                                " eat muffins and poutine until owner comes back.", po.Entries[3].Translated);
            }
예제 #16
0
        public static Node FromFile(string filePath, string nodeName)
        {
            // We need to catch if the node creation fails
            // for instance for null names, to dispose the stream.
            FileOpenMode mode   = FileOpenMode.ReadWrite;
            var          format = new BinaryFormat(DataStreamFactory.FromFile(filePath, mode));
            Node         node;

            try {
                node = new Node(nodeName, format)
                {
                    Tags = { ["FileInfo"] = new FileInfo(filePath) },
                };
            } catch {
                format.Dispose();
                throw;
            }

            return(node);
        }
예제 #17
0
        public void CanReadCompressedFilesChangingEndianness()
        {
            var reader     = new StandardBinReader();
            var parameters = new ReaderParameters
            {
                Endianness = EndiannessMode.BigEndian,
                FileNames  = Array.Empty <string>(),
            };

            reader.Initialize(parameters);

            // BIN is Big Endian but has a file in Little Endian
            using DataStream stream = DataStreamFactory.FromFile("MultiEndianTests.bin", FileOpenMode.Read);
            var format = new BinaryFormat(stream);

            var result = reader.Convert(format);

            Assert.AreEqual(2, result.Root.Children.Count);
            Assert.AreEqual(FileType.Normal, result.Root.Children[0].Tags["Type"]);
            Assert.AreEqual(FileType.CompressedAlternateEndian, result.Root.Children[1].Tags["Type"]);
        }
예제 #18
0
파일: Decrypter.cs 프로젝트: Darkmet98/SiA
        static void Compare(byte[] data, int round)
        {
            if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("SIA_DEBUG")))
            {
                return;
            }

            string basePath = Environment.GetEnvironmentVariable("SIA_WORKDIR");
            string filePath = Path.Combine(basePath, $"round{round}_f.bin");

            using (var original = DataStreamFactory.FromFile(filePath, FileOpenMode.Read)) {
                using (var source = DataStreamFactory.FromArray(data, 0, data.Length)) {
                    if (!original.Compare(source))
                    {
                        string tempFile = Path.Combine(basePath, "temp.bin");
                        source.WriteTo(tempFile);
                        Console.WriteLine($"!! Error on round {round} !!");
                        Environment.Exit(1);
                    }
                }
            }
        }
예제 #19
0
        private void readTable()
        {
            string line;

            string[] chars;
            var      reader = new TextReader(DataStreamFactory.FromFile(indexPath, FileOpenMode.Read));

            while (!reader.Stream.EndOfStream)
            {
                line = reader.ReadLine();
                if (string.IsNullOrWhiteSpace(line))
                {
                    continue;
                }
                if (line[0] == '#')
                {
                    continue;
                }

                chars = line.Split('=');
                indexDic.Add(Convert.ToInt32(chars[0], 16), chars[1]);
            }
        }
        public override void ImportPo(string inputFile, bool save = true)
        {
            var dataStream = DataStreamFactory.FromFile(inputFile, FileOpenMode.Read);
            var binary     = new BinaryFormat(dataStream);
            var binary2Po  = new Yarhl.Media.Text.Po2Binary();
            var po         = binary2Po.Convert(binary);

            LoadBeforeImport();
            foreach (var subtitle in _subtitles)
            {
                var original = subtitle.Text;
                if (string.IsNullOrEmpty(original))
                {
                    original = "<!empty>";
                }

                var entry = po.FindEntry(original.Replace(LineEnding.ShownLineEnding, LineEnding.PoLineEnding),
                                         GetContext(subtitle));

                if (entry == null || entry.Text == "<!empty>" || original == "<!empty>")
                {
                    subtitle.Translation = subtitle.Text;
                }
                else
                {
                    var translation = entry.Translated;
                    subtitle.Translation = string.IsNullOrEmpty(translation)
                        ? subtitle.Text
                        : translation.Replace(LineEnding.PoLineEnding, LineEnding.ShownLineEnding);
                }
            }

            if (save && NeedSaving)
            {
                SaveChanges();
            }
        }
예제 #21
0
        public BinaryFormat Convert(BinaryFormat source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (!Arguments.Contains("<in>") && !Arguments.Contains("<inout>"))
            {
                throw new FormatException("Missing input in arguments");
            }

            // Save stream into temporal file
            string tempInputFolder = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());

            Directory.CreateDirectory(tempInputFolder);

            string tempInputName = string.IsNullOrEmpty(FileName) ? "input.bin" : FileName;
            string tempInputFile = Path.Combine(tempInputFolder, tempInputName);

            source.Stream.WriteTo(tempInputFile);

            // Get or create the output file
            string tempOutputFile;

            if (Arguments.Contains("<out>"))
            {
                tempOutputFile = Path.GetTempFileName();
            }
            else if (Arguments.Contains("<inout>"))
            {
                tempOutputFile = tempInputFile;
            }
            else
            {
                throw new FormatException("Missing output in arguments");
            }

            // Run the process
            string args = Arguments.Replace("<in>", tempInputFile)
                          .Replace("<inout>", tempInputFile)
                          .Replace("<out>", tempOutputFile);

            var process = new Process();

            process.StartInfo.FileName               = Program;
            process.StartInfo.Arguments              = args;
            process.StartInfo.UseShellExecute        = false;
            process.StartInfo.CreateNoWindow         = true;
            process.StartInfo.ErrorDialog            = false;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardError  = true;

            if (!string.IsNullOrEmpty(WorkingDirectory))
            {
                if (!Directory.Exists(WorkingDirectory))
                {
                    Directory.CreateDirectory(WorkingDirectory);
                }

                process.StartInfo.WorkingDirectory = WorkingDirectory;
            }

            process.Start();
            process.WaitForExit();

            if (process.ExitCode != 0)
            {
                Directory.Delete(tempInputFolder, true);
                DeleteIfExists(tempOutputFile);
                throw new Exception($"Error running: {Program} {args} {process.StandardError.ReadToEnd()} {process.StandardOutput.ReadToEnd()}");
            }

            // Read the file into memory so we can delete it.
            var convertedStream = new BinaryFormat();

            using (var tempStream = DataStreamFactory.FromFile(tempOutputFile, FileOpenMode.Read)) {
                tempStream.WriteTo(convertedStream.Stream);
            }

            Directory.Delete(tempInputFolder, true);
            DeleteIfExists(tempOutputFile);
            return(convertedStream);
        }
예제 #22
0
        public ParFile Convert(NodeContainerFormat source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

            DataStream dataStream = string.IsNullOrEmpty(this.parameters.OutputPath) ? DataStreamFactory.FromMemory() : DataStreamFactory.FromFile(this.parameters.OutputPath, FileOpenMode.Write);

            var writer = new DataWriter(dataStream)
            {
                DefaultEncoding = Encoding.GetEncoding(1252),
                Endianness      = EndiannessMode.BigEndian,
            };

            var folders = new List <Node>();
            var files   = new List <Node>();

            if (this.parameters.IncludeDots)
            {
                var parFolderRootNode = new Node(".", new NodeContainerFormat());
                source.MoveChildrenTo(parFolderRootNode);
                folders.Add(parFolderRootNode);
            }

            GetFoldersAndFiles(source.Root, folders, files, this.parameters);
            CompressFiles(files, this.parameters.CompressorVersion);

            int  headerSize        = 32 + (64 * folders.Count) + (64 * files.Count);
            int  folderTableOffset = headerSize;
            int  fileTableOffset   = folderTableOffset + (folders.Count * 32);
            long dataPosition      = fileTableOffset + (files.Count * 32);

            dataPosition = Align(dataPosition, 2048);

            writer.Write("PARC", 4, false);

            if (source.Root.Tags.ContainsKey("PlatformId"))
            {
                writer.Write((byte)source.Root.Tags["PlatformId"]);
            }
            else
            {
                writer.Write((byte)0x02);
            }

            if (source.Root.Tags.ContainsKey("Endianness"))
            {
                var endianness = (byte)source.Root.Tags["Endianness"];
                writer.Write(endianness);
                writer.Endianness = endianness == 0x00 ? EndiannessMode.LittleEndian : EndiannessMode.BigEndian;
            }
            else
            {
                writer.Write((byte)0x01);
            }

            writer.Write((ushort)0x0000); // extended size and relocated

            if (source.Root.Tags.ContainsKey("Version"))
            {
                writer.Write((int)source.Root.Tags["Version"]);
            }
            else
            {
                writer.Write(0x00020001);
            }

            writer.Write(0x00000000); // data size

            writer.Write(folders.Count);
            writer.Write(folderTableOffset);
            writer.Write(files.Count);
            writer.Write(fileTableOffset);

            WriteNames(writer, folders);
            WriteNames(writer, files);

            WriteFolders(writer, folders);
            WriteFiles(writer, files, dataPosition);

            dataStream.Seek(0, SeekMode.End);
            writer.WritePadding(0, 2048);

            var result = new ParFile(dataStream)
            {
                CanBeCompressed = false,
            };

            return(result);
        }
예제 #23
0
        private static void Build(BuildOptions opts)
        {
            if (!Directory.Exists(opts.Input))
            {
                Console.WriteLine("INPUT DIRECTORY NOT FOUND!!");
                return;
            }

            if (File.Exists(opts.Output))
            {
                Console.WriteLine("OUTPUT FILE ALREADY EXISTS. IT WILL BE DELETED");
                Console.Write("Continue (y/N)?");
                string continueValue = Console.ReadLine();
                if (string.IsNullOrEmpty(continueValue) || !string.Equals(continueValue, "y", StringComparison.InvariantCultureIgnoreCase))
                {
                    Console.WriteLine("Cancelled by user.");
                    return;
                }

                File.Delete(opts.Output);
            }

            List <FileInfo> filesInfo = new ();

            if (!File.Exists(Path.Combine(opts.Input, "fileInfo.yaml")))
            {
                Console.WriteLine("fileInfo.yaml not found. Using default values");
                string[] files = Directory.GetFiles(opts.Input, "*");
                filesInfo.AddRange(files.Select(file => new FileInfo
                {
                    Name = Path.GetRelativePath(opts.Input, file),
                    Type = FileType.Normal,
                }));
            }
            else
            {
                string info         = Path.Combine(opts.Input, "fileInfo.yaml");
                string yaml         = File.ReadAllText(info);
                var    deserializer = new DeserializerBuilder()
                                      .WithNamingConvention(CamelCaseNamingConvention.Instance)
                                      .Build();
                filesInfo = deserializer.Deserialize <List <FileInfo> >(yaml);
            }

            Console.Write($"Reading files in {opts.Input}... ");
            var container = NodeFactory.CreateContainer("root");

            for (int i = 0; i < filesInfo.Count; i++)
            {
                var        fileInfo = filesInfo[i];
                DataStream s        = DataStreamFactory.FromFile(Path.Combine(opts.Input, fileInfo.Name), FileOpenMode.Read);
                Node       node     = NodeFactory.FromSubstream(i.ToString(), s, 0, s.Length);
                node.Tags["Type"]  = fileInfo.Type;
                node.Tags["Index"] = fileInfo.Index;
                container.Add(node);
            }

            container.SortChildren((x, y) => ((int)x.Tags["Index"]).CompareTo((int)y.Tags["Index"]));
            Console.WriteLine("DONE");

            DataStream stream     = DataStreamFactory.FromFile(opts.Output, FileOpenMode.Write);
            var        parameters = new WriterParameters
            {
                Endianness = opts.BigEndian ? EndiannessMode.BigEndian : EndiannessMode.LittleEndian,
                Stream     = stream,
            };

            Console.Write("Building BIN archive... ");
            if (opts.Dlc)
            {
                container.TransformWith <DlcBinWriter, WriterParameters>(parameters);
            }
            else
            {
                container.TransformWith <StandardBinCompressor, EndiannessMode>(parameters.Endianness)
                .TransformWith <StandardBinWriter, WriterParameters>(parameters);
            }

            stream.Flush();
            stream.Dispose();
            Console.WriteLine("DONE");
        }
예제 #24
0
        public override void ImportPo(string inputFile, bool save = true, bool parallel = true)
        {
            using (DataStream dataStream = DataStreamFactory.FromFile(inputFile, FileOpenMode.Read))
            {
                var binary    = new BinaryFormat(dataStream);
                var binary2Po = new Yarhl.Media.Text.Binary2Po();
                Po  po        = binary2Po.Convert(binary);

                LoadBeforeImport();
                var dictionary = new ConcurrentDictionary <string, Subtitle>();
                foreach (Subtitle subtitle in _subtitles)
                {
                    dictionary[GetContext(subtitle)] = subtitle;
                }

                void UpdateSubtitleFromPoEntry(PoEntry entry)
                {
                    string context = entry.Context;

                    if (!dictionary.TryGetValue(context, out Subtitle subtitle))
                    {
                        return;
                    }

                    if (entry.Original == "<!empty>" || string.IsNullOrEmpty(subtitle.Text))
                    {
                        subtitle.Translation = subtitle.Text;
                    }
                    else
                    {
                        if (entry.Original.Replace(LineEnding.PoLineEnding, LineEnding.ShownLineEnding) !=
                            subtitle.Text)
                        {
                            // El texto original de la entrada no coincide con el del subtítulo, así que no podemos aplicar la traducción
                            subtitle.Translation = subtitle.Text;
                        }
                        else
                        {
                            string translation = entry.Translated;
                            subtitle.Translation = string.IsNullOrEmpty(translation)
                                ? subtitle.Text
                                : translation.Replace(LineEnding.PoLineEnding, LineEnding.ShownLineEnding);
                        }
                    }
                }

                if (parallel)
                {
                    Parallel.ForEach(po.Entries, UpdateSubtitleFromPoEntry);
                }
                else
                {
                    foreach (PoEntry entry in po.Entries)
                    {
                        UpdateSubtitleFromPoEntry(entry);
                    }
                }
            }

            if (save && NeedSaving)
            {
                SaveChanges();
            }
        }
예제 #25
0
        private static void Update(UpdateOptions opts)
        {
            if (!File.Exists(opts.InputBin))
            {
                Console.WriteLine("INPUT FILE NOT FOUND!!");
                return;
            }

            if (!Directory.Exists(opts.InputDir))
            {
                Console.WriteLine("INPUT DIRECTORY NOT FOUND!!");
                return;
            }

            if (File.Exists(opts.Output))
            {
                Console.WriteLine("OUTPUT FILE ALREADY EXISTS. IT WILL BE DELETED");
                Console.Write("Continue (y/N)?");
                string continueValue = Console.ReadLine();
                if (string.IsNullOrEmpty(continueValue) || !string.Equals(continueValue, "y", StringComparison.InvariantCultureIgnoreCase))
                {
                    Console.WriteLine("Cancelled by user.");
                    return;
                }

                File.Delete(opts.Output);
            }

            string[] fileList;

            if (!string.IsNullOrEmpty(opts.FileList) && File.Exists(opts.FileList))
            {
                Console.WriteLine($"Using \"{opts.FileList}\" as file list...");
                fileList = File.ReadAllLines(opts.FileList);
            }
            else
            {
                fileList = Array.Empty <string>();
            }

            Console.Write("Reading BIN file... ");
            Node binFile = NodeFactory.FromFile(opts.InputBin);

            (BinType binType, EndiannessMode endianness) = IdentifyFile(binFile);
            var readerParameters = new ReaderParameters
            {
                Endianness = endianness,
                FileNames  = fileList,
            };

            switch (binType)
            {
            case BinType.Standard:
                binFile.TransformWith <StandardBinReader, ReaderParameters>(readerParameters);
                break;

            case BinType.Dlc:
                binFile.TransformWith <DlcBinReader, ReaderParameters>(readerParameters);
                break;

            default:
                Console.WriteLine("Unknown file type");
                return;
            }

            Console.WriteLine("DONE");

            Console.Write($"Reading files in {opts.InputDir}... ");
            string[] newFiles = Directory.GetFiles(opts.InputDir, "*", SearchOption.AllDirectories);
            Parallel.ForEach(newFiles, newFile =>
            {
                string file  = Path.GetRelativePath(opts.InputDir, newFile).Replace('\\', '/');
                Node oldNode = Navigator.SearchNode(binFile, file);
                if (oldNode == null)
                {
                    Console.WriteLine($"{file} not found in {opts.InputBin}");
                    return;
                }

                DataStream s = DataStreamFactory.FromFile(newFile, FileOpenMode.Read);
                var type     = oldNode.Tags["Type"];
                switch (type)
                {
                case FileType.Normal:
                    oldNode.ChangeFormat(new BinaryFormat(s), true);
                    break;

                case FileType.Compressed:
                    oldNode.ChangeFormat(new BinaryFormat(s), true);
                    oldNode.Tags["InflatedSize"] = (uint)s.Length;
                    oldNode.TransformWith <Compressor, EndiannessMode>(endianness);
                    break;

                case FileType.CompressedAlternateEndian:
                    oldNode.ChangeFormat(new BinaryFormat(s), true);
                    oldNode.Tags["InflatedSize"] = (uint)s.Length;
                    oldNode.TransformWith <Compressor, EndiannessMode>(endianness == EndiannessMode.BigEndian
                                ? EndiannessMode.LittleEndian
                                : EndiannessMode.BigEndian);
                    break;
                }
            });

            Console.WriteLine("DONE");

            Console.Write("Building BIN archive... ");
            DataStream stream     = DataStreamFactory.FromFile(opts.Output, FileOpenMode.Write);
            var        parameters = new WriterParameters
            {
                Endianness = endianness,
                Stream     = stream,
            };

            var container = NodeFactory.CreateContainer("root");
            int index     = 0;

            foreach (Node srcNode in Navigator.IterateNodes(binFile))
            {
                if (srcNode.IsContainer)
                {
                    continue;
                }

                Node node = NodeFactory.FromSubstream(index.ToString(), srcNode.Stream, 0, srcNode.Stream.Length);
                foreach (string key in srcNode.Tags.Keys)
                {
                    node.Tags[key] = srcNode.Tags[key];
                }

                container.Add(node);
                index++;
            }

            container.SortChildren((x, y) => ((int)x.Tags["Index"]).CompareTo((int)y.Tags["Index"]));

            switch (binType)
            {
            case BinType.Standard:
                container.TransformWith <StandardBinWriter, WriterParameters>(parameters);
                break;

            case BinType.Dlc:
                container.TransformWith <DlcBinWriter, WriterParameters>(parameters);
                break;
            }

            stream.Flush();
            stream.Dispose();
            Console.WriteLine("DONE");
        }