Example #1
0
 public void Dispose()
 {
     if (m_should_dispose && !_disposed)
     {
         m_file.Dispose();
         _disposed = true;
     }
 }
Example #2
0
        public override ArcFile TryOpen(ArcView file)
        {
            var name = Path.GetFileName(file.Name);

            if (!NamePattern.IsMatch(name))
            {
                return(null);
            }
            var match   = NamePattern.Match(name);
            int name_id = 1;
            var num_str = match.Groups["num"].Value;

            if (!string.IsNullOrEmpty(num_str))
            {
                name_id = Int32.Parse(num_str);
            }
            if (name_id < 1)
            {
                return(null);
            }
            ArcView index = file;

            try
            {
                if (name_id != 1)
                {
                    string index_name;
                    if (file.Name.HasExtension(".dat"))
                    {
                        index_name = VFS.ChangeFileName(file.Name, "0001.dat");
                    }
                    else
                    {
                        index_name = VFS.ChangeFileName(file.Name, "data");
                    }
                    if (!VFS.FileExists(index_name))
                    {
                        return(null);
                    }
                    index = VFS.OpenView(index_name);
                }
                var dir = ReadIndex(index, name_id, file.MaxOffset);
                if (null == dir || 0 == dir.Count)
                {
                    return(null);
                }
                return(new ArcFile(file, this, dir));
            }
            finally
            {
                if (index != file)
                {
                    index.Dispose();
                }
            }
        }
Example #3
0
 protected override void Dispose(bool disposing)
 {
     if (!_vff_disposed)
     {
         if (disposing && ExtraFile != null)
         {
             ExtraFile.Dispose();
         }
         _vff_disposed = true;
     }
     base.Dispose(disposing);
 }
Example #4
0
        public override ArcFile TryOpen(ArcView file)
        {
            var name = Path.GetFileName(file.Name);

            if (!NamePattern.IsMatch(name))
            {
                return(null);
            }
            var match   = NamePattern.Match(name);
            int name_id = Int32.Parse(match.Groups[1].Value);

            if (name_id < 1)
            {
                return(null);
            }
            ArcView index = file;

            try
            {
                if (name_id != 1)
                {
                    var index_name = VFS.ChangeFileName(file.Name, "0001.dat");
                    if (!VFS.FileExists(index_name))
                    {
                        return(null);
                    }
                    index = VFS.OpenView(index_name);
                }
                var dir = ReadIndex(index, name_id, file.MaxOffset);
                if (null == dir || 0 == dir.Count)
                {
                    return(null);
                }
                return(new ArcFile(file, this, dir));
            }
            finally
            {
                if (index != file)
                {
                    index.Dispose();
                }
            }
        }
Example #5
0
        public override void Create(Stream output, IEnumerable <Entry> list, ResourceOptions options,
                                    EntryCallback callback)
        {
            ArcFile base_archive = null;
            var     ami_options  = GetOptions <AmiOptions> (options);

            if (null != ami_options && ami_options.UseBaseArchive && !string.IsNullOrEmpty(ami_options.BaseArchive))
            {
                var base_file = new ArcView(ami_options.BaseArchive);
                try
                {
                    if (base_file.View.ReadUInt32(0) == Signature)
                    {
                        base_archive = TryOpen(base_file);
                    }
                    if (null == base_archive)
                    {
                        throw new InvalidFormatException(string.Format("{0}: base archive could not be read",
                                                                       Path.GetFileName(ami_options.BaseArchive)));
                    }
                    base_file = null;
                }
                finally
                {
                    if (null != base_file)
                    {
                        base_file.Dispose();
                    }
                }
            }
            try
            {
                var file_table = new SortedDictionary <uint, PackedEntry>();
                if (null != base_archive)
                {
                    foreach (AmiEntry entry in base_archive.Dir)
                    {
                        file_table[entry.Id] = entry;
                    }
                }
                int update_count = UpdateFileTable(file_table, list);
                if (0 == update_count)
                {
                    throw new InvalidFormatException(arcStrings.AMINoFiles);
                }

                uint file_count = (uint)file_table.Count;
                if (null != callback)
                {
                    callback((int)file_count + 1, null, null);
                }

                int  callback_count = 0;
                long start_offset   = output.Position;
                uint data_offset    = file_count * 16 + 16;
                output.Seek(data_offset, SeekOrigin.Current);
                foreach (var entry in file_table)
                {
                    if (null != callback)
                    {
                        callback(callback_count++, entry.Value, arcStrings.MsgAddingFile);
                    }
                    long current_offset = output.Position;
                    if (current_offset > uint.MaxValue)
                    {
                        throw new FileSizeException();
                    }
                    if (entry.Value is AmiEntry)
                    {
                        CopyAmiEntry(base_archive, entry.Value, output);
                    }
                    else
                    {
                        entry.Value.Size = WriteAmiEntry(entry.Value, output);
                    }
                    entry.Value.Offset = (uint)current_offset;
                }
                if (null != callback)
                {
                    callback(callback_count++, null, arcStrings.MsgWritingIndex);
                }
                output.Position = start_offset;
                using (var header = new BinaryWriter(output, Encoding.ASCII, true))
                {
                    header.Write(Signature);
                    header.Write(file_count);
                    header.Write(data_offset);
                    header.Write((uint)0);
                    foreach (var entry in file_table)
                    {
                        header.Write(entry.Key);
                        header.Write((uint)entry.Value.Offset);
                        header.Write((uint)entry.Value.UnpackedSize);
                        header.Write((uint)entry.Value.Size);
                    }
                }
            }
            finally
            {
                if (null != base_archive)
                {
                    base_archive.Dispose();
                }
            }
        }
Example #6
0
        public override ArcFile TryOpen(ArcView file)
        {
            var match = s_ResNameRe.Match(file.Name);

            if (!match.Success || file.View.AsciiEqual(0, "AiFS"))
            {
                return(null);
            }

            var digits    = match.Groups[1];
            int arc_num   = UInt16.Parse(digits.Value);
            int toc_num   = arc_num - 1;
            int arc_index = 1; // number by which archive is referenced within toc file

            // look for toc file
            ArcView toc_file    = null;
            var     toc_name_sb = new StringBuilder(file.Name.Length);

            while (toc_num >= 0)
            {
                toc_name_sb.Clear();
                toc_name_sb.Append(file.Name);
                toc_name_sb.Remove(digits.Index, digits.Length);
                toc_name_sb.Insert(digits.Index, toc_num.ToString("D4"));
                var toc_name = toc_name_sb.ToString();
                if (!VFS.FileExists(toc_name))
                {
                    return(null);
                }
                toc_file = VFS.OpenView(toc_name);
                if (toc_file.View.AsciiEqual(0, "AiFS"))
                {
                    break;
                }
                toc_file.Dispose();
                toc_file = null;
                toc_num--;
                arc_index++;
            }
            if (null == toc_file)
            {
                return(null);
            }
            using (toc_file)
            {
                int res_count = toc_file.View.ReadInt32(0xC);
                if (res_count < arc_index)
                {
                    return(null);
                }
                uint index_offset = 0x10;
                // find archive reference within toc file
                bool arc_found = false;
                for (int i = 0; i < res_count && index_offset < toc_file.MaxOffset; ++i)
                {
                    int num = toc_file.View.ReadInt32(index_offset);
                    if (0x01000000 == num)
                    {
                        index_offset += 4;
                        num           = toc_file.View.ReadInt32(index_offset);
                    }
                    if (num == arc_index)
                    {
                        arc_found = true;
                        break;
                    }
                    uint entries = toc_file.View.ReadUInt32(index_offset + 0xC);
                    index_offset += 0x10 + entries * 8;
                }
                if (!arc_found)
                {
                    return(null);
                }
                int count = toc_file.View.ReadInt32(index_offset + 0xC);
                if (!IsSaneCount(count))
                {
                    return(null);
                }
                int start_index = toc_file.View.ReadInt32(index_offset + 4);
                index_offset += 0x10;
                var dir = new List <Entry> (count);
                for (int i = 0; i < count; ++i)
                {
                    uint offset = toc_file.View.ReadUInt32(index_offset);
                    uint size   = toc_file.View.ReadUInt32(index_offset + 4);
                    if (size != 0)
                    {
                        var entry = new Entry {
                            Name   = string.Format("{0:D5}.ogg", start_index + i),
                            Type   = "audio",
                            Offset = offset,
                            Size   = size,
                        };
                        entry.Offset = toc_file.View.ReadUInt32(index_offset);
                        if (!entry.CheckPlacement(file.MaxOffset))
                        {
                            return(null);
                        }
                        dir.Add(entry);
                    }
                    index_offset += 8;
                }
                if (0 == dir.Count)
                {
                    return(null);
                }
                return(new ArcFile(file, this, dir));
            }
        }
Example #7
0
        public override ArcFile TryOpen(ArcView file)
        {
            uint    base_offset = 0;
            ArcView index_file  = file;
            ArcView extra_file  = null;

            try
            {
                // possible filesystem structure:
                //   game.dat  -- main archive body
                //   game.001  -- [optional] extra part
                //   game.ext  -- [optional] separate index (could be included into the main body)

                uint signature = index_file.View.ReadUInt32(0);
                if (file.Name.HasExtension(".exe") &&
                    (0x5A4D == (signature & 0xFFFF)))    // 'MZ'
                {
                    base_offset = SkipExeData(index_file);
                    signature   = index_file.View.ReadUInt32(base_offset);
                }
                else if (!file.Name.HasExtension(".dat"))
                {
                    return(null);
                }
                else if (0x666676 != signature)
                {
                    var ext_filename = Path.ChangeExtension(file.Name, ".ext");
                    if (!VFS.FileExists(ext_filename))
                    {
                        return(null);
                    }
                    index_file = VFS.OpenView(ext_filename);
                    signature  = index_file.View.ReadUInt32(0);
                }
                if (0x666676 != signature)
                {
                    return(null);
                }
                int count = index_file.View.ReadInt32(base_offset + 6);
                if (!IsSaneCount(count))
                {
                    return(null);
                }

                var dir = ReadIndex(index_file, base_offset, count);
                if (null == dir)
                {
                    return(null);
                }
                long max_offset = file.MaxOffset;
                for (int i = 0; i < dir.Count; ++i)
                {
                    if (!dir[i].CheckPlacement(max_offset))
                    {
                        if (extra_file != null)
                        {
                            // remove entries that don't fit into game.dat+game.001
                            int discard = dir.Count - i;
                            Trace.WriteLine(string.Format("{0} entries didn't fit and were discarded", discard), "[vff]");
                            dir.RemoveRange(i, discard);
                            break;
                        }
                        var extra_filename = Path.ChangeExtension(file.Name, ".001");
                        if (!VFS.FileExists(extra_filename))
                        {
                            return(null);
                        }
                        extra_file  = VFS.OpenView(extra_filename);
                        max_offset += extra_file.MaxOffset;
                        if (!dir[i].CheckPlacement(max_offset))
                        {
                            return(null);
                        }
                    }
                }
                if (null == extra_file)
                {
                    return(new ArcFile(file, this, dir));
                }
                return(new VffArchive(file, this, dir, extra_file));
            }
            catch
            {
                if (extra_file != null)
                {
                    extra_file.Dispose();
                }
                throw;
            }
            finally
            {
                if (index_file != file)
                {
                    index_file.Dispose();
                }
            }
        }
Example #8
0
        public override void Create(Stream output, IEnumerable<Entry> list, ResourceOptions options,
                                     EntryCallback callback)
        {
            ArcFile base_archive = null;
            var ami_options = GetOptions<AmiOptions> (options);
            if (null != ami_options && ami_options.UseBaseArchive && !string.IsNullOrEmpty (ami_options.BaseArchive))
            {
                var base_file = new ArcView (ami_options.BaseArchive);
                try
                {
                    if (base_file.View.ReadUInt32(0) == Signature)
                        base_archive = TryOpen (base_file);
                    if (null == base_archive)
                        throw new InvalidFormatException (string.Format ("{0}: base archive could not be read",
                            Path.GetFileName (ami_options.BaseArchive)));
                    base_file = null;
                }
                finally
                {
                    if (null != base_file)
                        base_file.Dispose();
                }
            }
            try
            {
                var file_table = new SortedDictionary<uint, PackedEntry>();
                if (null != base_archive)
                {
                    foreach (AmiEntry entry in base_archive.Dir)
                        file_table[entry.Id] = entry;
                }
                int update_count = UpdateFileTable (file_table, list);
                if (0 == update_count)
                    throw new InvalidFormatException (arcStrings.AMINoFiles);

                uint file_count = (uint)file_table.Count;
                if (null != callback)
                    callback ((int)file_count+1, null, null);

                int callback_count = 0;
                long start_offset = output.Position;
                uint data_offset = file_count * 16 + 16;
                output.Seek (data_offset, SeekOrigin.Current);
                foreach (var entry in file_table)
                {
                    if (null != callback)
                        callback (callback_count++, entry.Value, arcStrings.MsgAddingFile);
                    long current_offset = output.Position;
                    if (current_offset > uint.MaxValue)
                        throw new FileSizeException();
                    if (entry.Value is AmiEntry)
                        CopyAmiEntry (base_archive, entry.Value, output);
                    else
                        entry.Value.Size = WriteAmiEntry (entry.Value, output);
                    entry.Value.Offset = (uint)current_offset;
                }
                if (null != callback)
                    callback (callback_count++, null, arcStrings.MsgWritingIndex);
                output.Position = start_offset;
                using (var header = new BinaryWriter (output, Encoding.ASCII, true))
                {
                    header.Write (Signature);
                    header.Write (file_count);
                    header.Write (data_offset);
                    header.Write ((uint)0);
                    foreach (var entry in file_table)
                    {
                        header.Write (entry.Key);
                        header.Write ((uint)entry.Value.Offset);
                        header.Write ((uint)entry.Value.UnpackedSize);
                        header.Write ((uint)entry.Value.Size);
                    }
                }
            }
            finally
            {
                if (null != base_archive)
                    base_archive.Dispose();
            }
        }
Example #9
0
        public override ArcFile TryOpen(ArcView file)
        {
            uint    base_offset = 0;
            ArcView index_file  = file;

            try
            {
                // possible filesystem structure:
                //   game.dat  -- main archive body
                //   game.ext  -- [optional] separate index (could be included into the main body)
                //   game.001  -- [optional] extra parts
                //   game.002
                //   ...

                uint signature = index_file.View.ReadUInt32(0);
                if (file.Name.HasExtension(".exe") &&
                    (0x5A4D == (signature & 0xFFFF)))    // 'MZ'
                {
                    base_offset = SkipExeData(index_file);
                    signature   = index_file.View.ReadUInt32(base_offset);
                }
                else if (!file.Name.HasExtension(".dat"))
                {
                    return(null);
                }
                else if (0x666676 != signature)
                {
                    var ext_filename = Path.ChangeExtension(file.Name, ".ext");
                    if (!VFS.FileExists(ext_filename))
                    {
                        return(null);
                    }
                    index_file = VFS.OpenView(ext_filename);
                    signature  = index_file.View.ReadUInt32(0);
                }
                if (0x666676 != signature)
                {
                    return(null);
                }
                int count = index_file.View.ReadInt32(base_offset + 6);
                if (!IsSaneCount(count))
                {
                    return(null);
                }

                var dir = ReadIndex(index_file, base_offset, count);
                if (null == dir)
                {
                    return(null);
                }
                long max_offset = file.MaxOffset;
                var  parts      = new List <ArcView>();
                try
                {
                    for (int i = 1; i < 100; ++i)
                    {
                        var ext           = string.Format(".{0:D3}", i);
                        var part_filename = Path.ChangeExtension(file.Name, ext);
                        if (!VFS.FileExists(part_filename))
                        {
                            break;
                        }
                        var arc_file = VFS.OpenView(part_filename);
                        max_offset += arc_file.MaxOffset;
                        parts.Add(arc_file);
                    }
                }
                catch
                {
                    foreach (var part in parts)
                    {
                        part.Dispose();
                    }
                    throw;
                }
                if (0 == parts.Count)
                {
                    return(new ArcFile(file, this, dir));
                }
                return(new MultiFileArchive(file, this, dir, parts));
            }
            finally
            {
                if (index_file != file)
                {
                    index_file.Dispose();
                }
            }
        }
        static void Main(string[] args)
        {
            Console.WriteLine("ONE Eternal Patch v1.0");
            Console.WriteLine("developed by Sep7\n");

            //////////
            //INPUTS
            //////////
            string inputLanguage = "";

            do
            {
                Console.WriteLine("Enter 1 if you want to patch the Japanese Version.");
                Console.WriteLine("Enter 2 if you want to patch the English translated Version.");

                inputLanguage = Console.ReadLine();

                if (inputLanguage.Length != 1 || (inputLanguage.Substring(0, 1) != "1" && inputLanguage.Substring(0, 1) != "2"))
                {
                    Console.WriteLine("Syntax Error.\n");
                }
            } while (inputLanguage.Length != 1 || (inputLanguage.Substring(0, 1) != "1" && inputLanguage.Substring(0, 1) != "2"));

            string inputBonusCG = "";

            do
            {
                Console.WriteLine("\nEnter 1 if you want to add the bonus CGs.");
                Console.WriteLine("Enter 2 if you want to remove them.");

                inputBonusCG = Console.ReadLine();

                if (inputBonusCG.Length != 1 || (inputBonusCG.Substring(0, 1) != "1" && inputBonusCG.Substring(0, 1) != "2"))
                {
                    Console.WriteLine("Syntax Error.");
                }
            } while (inputBonusCG.Length != 1 || (inputBonusCG.Substring(0, 1) != "1" && inputBonusCG.Substring(0, 1) != "2"));

            //////////////////////////////
            //EXTRACTING OF THE PATCH FILES
            //////////////////////////////
            //First, we create a view of the file that'll allow us to work on it, the file is still encrypted.
            ArcView originalFile = null;
            ArcView patchFile    = null;

            try
            {
                patchFile = new ArcView("./ONE_Patch_Files");
            }
            catch (System.IO.FileNotFoundException e)
            {
                Console.WriteLine("\nError: the file \"ONE_Patch_Files\" was not found.\n" +
                                  "Make sure to place it in the same directory as the executable.\n\n" +
                                  "Error details: " + e +
                                  "\n\nPress any key to continue.");
                Console.ReadKey(true);
                System.Environment.Exit(1);
            }
            catch (System.UnauthorizedAccessException e)
            {
                Console.WriteLine("\nError: the file \"ONE_Patch_Files\" can't be accessed.\n" +
                                  "Make sure that the file and the current folder are not in read only access.\n\n" +
                                  "Error details: " + e +
                                  "\n\nPress any key to continue.");
                Console.ReadKey(true);
                System.Environment.Exit(1);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                Console.ReadKey(true);
                System.Environment.Exit(1);
            }

            LstOpener         lst              = new LstOpener();
            List <Entry>      resultFilesList  = new List <Entry>();
            ArcFile           arcOriginalFiles = null;
            ArcFile           arcPatchFiles    = null;
            ArchiveFileSystem afsOriginalFiles = null;
            ArchiveFileSystem afsPatchFiles    = null;
            String            suffix           = "";

            try
            {
                //then, we want to get the encrypted file with the LstOpener
                //the arcfile is composed of the view on the original file, of an instance of LstOpener used to determinate the format
                //and of a list of all the files/entries with their names, type, offset and size
                arcPatchFiles = lst.TryOpen(patchFile);
            }
            catch (System.UnauthorizedAccessException e)
            {
                Console.WriteLine("\nError: the file \"ONE_Patch_Files.lst\" can't be accessed.\n" +
                                  "Make sure that the file and the current folder are not in read only access.\n\n" +
                                  "Error details: " + e +
                                  "\n\nPress any key to continue.");
                Console.ReadKey(true);
                System.Environment.Exit(1);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                Console.ReadKey(true);
                System.Environment.Exit(1);
            }


            try
            {
                //create a dictionary of data where the key is equal to the name of the entry and where the content is equal to the current entry
                afsPatchFiles = arcPatchFiles.CreateFileSystem();
            }
            catch (System.NullReferenceException e)
            {
                Console.WriteLine("\nError: the file \"ONE_Patch_Files.lst\" was not found.\n" +
                                  "Make sure to place it in the same directory as the executable.\n\n" +
                                  "Error details: " + e +
                                  "\n\nPress any key to continue.");
                Console.ReadKey(true);
                System.Environment.Exit(1);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                Console.ReadKey(true);
                System.Environment.Exit(1);
            }

            List <Entry> patchFilesList = new List <Entry>();

            //Remove the Bonus CGs in the Japanese version
            if (inputBonusCG.Substring(0, 1) == "2" && inputLanguage.Substring(0, 1) == "1")
            {
                suffix = "_JAP";
            }
            //Remove the Bonus CGs in the English version
            else if (inputBonusCG.Substring(0, 1) == "2" && inputLanguage.Substring(0, 1) == "2")
            {
                suffix = "_ENG";
            }
            //Add the Bonus CGs in the Japanese version
            else if (inputBonusCG.Substring(0, 1) == "1" && inputLanguage.Substring(0, 1) == "1")
            {
                suffix = "_JAPBCG";
            }
            //Add the Bonus CGs in the English version
            else
            {
                suffix = "_ENGBCG";
            }

            //Scripts
            patchFilesList.Add(afsPatchFiles.FindFile("AK26" + suffix + ".SNX"));
            patchFilesList.Add(afsPatchFiles.FindFile("CGMODEAK" + suffix + ".SNX"));
            patchFilesList.Add(afsPatchFiles.FindFile("CGMODEMO" + suffix + ".SNX"));
            patchFilesList.Add(afsPatchFiles.FindFile("CGMODEMS" + suffix + ".SNX"));
            patchFilesList.Add(afsPatchFiles.FindFile("CGMODEMU" + suffix + ".SNX"));
            patchFilesList.Add(afsPatchFiles.FindFile("CGMODEMZ" + suffix + ".SNX"));
            patchFilesList.Add(afsPatchFiles.FindFile("CGMODENN" + suffix + ".SNX"));
            patchFilesList.Add(afsPatchFiles.FindFile("DS01" + suffix + ".SNX"));
            patchFilesList.Add(afsPatchFiles.FindFile("DS05" + suffix + ".SNX"));
            patchFilesList.Add(afsPatchFiles.FindFile("DS07" + suffix + ".SNX"));
            patchFilesList.Add(afsPatchFiles.FindFile("DS09" + suffix + ".SNX"));
            patchFilesList.Add(afsPatchFiles.FindFile("DS10_A" + suffix + ".SNX"));
            patchFilesList.Add(afsPatchFiles.FindFile("DS19" + suffix + ".SNX"));
            patchFilesList.Add(afsPatchFiles.FindFile("MS22" + suffix + ".SNX"));
            patchFilesList.Add(afsPatchFiles.FindFile("MS25" + suffix + ".SNX"));
            patchFilesList.Add(afsPatchFiles.FindFile("MS27" + suffix + ".SNX"));
            patchFilesList.Add(afsPatchFiles.FindFile("MY24" + suffix + ".SNX"));
            patchFilesList.Add(afsPatchFiles.FindFile("NV30" + suffix + ".SNX"));
            patchFilesList.Add(afsPatchFiles.FindFile("RM24" + suffix + ".SNX"));
            patchFilesList.Add(afsPatchFiles.FindFile("SBD25N1" + suffix + ".SNX"));
            patchFilesList.Add(afsPatchFiles.FindFile("SBRM14N1" + suffix + ".SNX"));
            patchFilesList.Add(afsPatchFiles.FindFile("SBRM17M1" + suffix + ".SNX"));

            //PNGs
            if (inputBonusCG.Substring(0, 1) == "1")
            {
                patchFilesList.Add(afsPatchFiles.FindFile("BG400.PNG"));
            }

            patchFilesList.Add(afsPatchFiles.FindFile("CGMODEAKBK" + suffix + ".PNG"));
            patchFilesList.Add(afsPatchFiles.FindFile("CGMODEAKCHIP" + suffix + ".PNG"));
            patchFilesList.Add(afsPatchFiles.FindFile("CGMODEMOBK" + suffix + ".PNG"));
            patchFilesList.Add(afsPatchFiles.FindFile("CGMODEMOCHIP" + suffix + ".PNG"));
            patchFilesList.Add(afsPatchFiles.FindFile("CGMODEMSBK" + suffix + ".PNG"));
            patchFilesList.Add(afsPatchFiles.FindFile("CGMODEMSCHIP" + suffix + ".PNG"));
            patchFilesList.Add(afsPatchFiles.FindFile("CGMODEMUBK" + suffix + ".PNG"));
            patchFilesList.Add(afsPatchFiles.FindFile("CGMODEMUCHIP" + suffix + ".PNG"));
            patchFilesList.Add(afsPatchFiles.FindFile("CGMODEMZBK" + suffix + ".PNG"));
            patchFilesList.Add(afsPatchFiles.FindFile("CGMODEMZCHIP" + suffix + ".PNG"));
            patchFilesList.Add(afsPatchFiles.FindFile("CGMODENNBK" + suffix + ".PNG"));
            patchFilesList.Add(afsPatchFiles.FindFile("CGMODENNCHIP" + suffix + ".PNG"));

            if (inputBonusCG.Substring(0, 1) == "1")
            {
                patchFilesList.Add(afsPatchFiles.FindFile("FGAK17.PNG"));
                patchFilesList.Add(afsPatchFiles.FindFile("FGAK18.PNG"));
                patchFilesList.Add(afsPatchFiles.FindFile("FGMI17.PNG"));
                patchFilesList.Add(afsPatchFiles.FindFile("FGMI18.PNG"));
                patchFilesList.Add(afsPatchFiles.FindFile("FGMI19.PNG"));
                patchFilesList.Add(afsPatchFiles.FindFile("FGMS18.PNG"));
                patchFilesList.Add(afsPatchFiles.FindFile("FGMS19.PNG"));
                patchFilesList.Add(afsPatchFiles.FindFile("FGMY16.PNG"));
                patchFilesList.Add(afsPatchFiles.FindFile("FGMY17.PNG"));
                patchFilesList.Add(afsPatchFiles.FindFile("FGMZ17.PNG"));
                patchFilesList.Add(afsPatchFiles.FindFile("FGMZ18.PNG"));
                patchFilesList.Add(afsPatchFiles.FindFile("FGRM16.PNG"));
                patchFilesList.Add(afsPatchFiles.FindFile("FGRM17.PNG"));
                patchFilesList.Add(afsPatchFiles.FindFile("FGRM18.PNG"));
            }

            //This file only exists in the English translated version and is placed at the end of the archive for some reasons.
            //I'm pretty sure it's a mistake of the TL team but I prefer to update it, just in case.
            if (inputLanguage.Substring(0, 1) == "2")
            {
                patchFilesList.Add(afsPatchFiles.FindFile("CGMODEAKMU" + suffix + ".PNG"));
            }

            List <String> filesListToNotUpdate = new List <String> {
                "BG400.PNG", "FGAK17.PNG", "FGAK18.PNG",
                "FGMI17.PNG", "FGMI18.PNG", "FGMI19.PNG", "FGMS18.PNG", "FGMS19.PNG", "FGMY16.PNG", "FGMY17.PNG",
                "FGMZ17.PNG", "FGMZ18.PNG", "FGRM16.PNG", "FGRM17.PNG", "FGRM18.PNG"
            };

            //////////////////////////////
            //EXTRACTING OF THE ORIGINAL FILES
            //////////////////////////////
            try
            {
                originalFile = new ArcView("./one");
            }
            catch (System.IO.FileNotFoundException e)
            {
                Console.WriteLine("\nError: the file \"one\" was not found.\n" +
                                  "Make sure to place it in the same directory as the executable.\n\n" +
                                  "Error details: " + e +
                                  "\n\nPress any key to continue.");
                Console.ReadKey(true);
                System.Environment.Exit(1);
            }
            catch (System.UnauthorizedAccessException e)
            {
                Console.WriteLine("\nError: the file \"one\" can't be accessed.\n" +
                                  "Make sure that the file and the current folder are not in read only access.\n\n" +
                                  "Error details: " + e +
                                  "\n\nPress any key to continue.");
                Console.ReadKey(true);
                System.Environment.Exit(1);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                Console.ReadKey(true);
                System.Environment.Exit(1);
            }

            try
            {
                arcOriginalFiles = lst.TryOpen(originalFile);
            }
            catch (System.UnauthorizedAccessException e)
            {
                Console.WriteLine("\nError: the file \"one.lst\" can't be accessed.\n" +
                                  "Make sure that the file and the current folder are not in read only access.\n\n" +
                                  "Error details: " + e +
                                  "\n\nPress any key to continue.");
                Console.ReadKey(true);
                System.Environment.Exit(1);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                Console.ReadKey(true);
                System.Environment.Exit(1);
            }
            try
            {
                afsOriginalFiles = arcOriginalFiles.CreateFileSystem();
            }
            catch (System.NullReferenceException e)
            {
                Console.WriteLine("\nError: the file \"one.lst\" was not found.\n" +
                                  "Make sure to place it in the same directory as the executable.\n\n" +
                                  "Error details: " + e +
                                  "\n\nPress any key to continue.");
                Console.ReadKey(true);
                System.Environment.Exit(1);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                Console.ReadKey(true);
                System.Environment.Exit(1);
            }


            List <Entry> originalFilesList = new List <Entry>();

            originalFilesList = (List <Entry>)afsOriginalFiles.GetFiles();

            int i = 0;

            foreach (Entry entry in originalFilesList)
            {
                String fileName = "";
                //Updating the name of the file
                if (patchFilesList.ToArray().Length > i)
                {
                    fileName = ((Entry)patchFilesList.ToArray()[i]).Name;
                    //Remove the suffix of the name of the files
                    if (fileName.Contains(suffix))
                    {
                        fileName = fileName.Replace(suffix, "");
                    }
                }

                //Skip the bonus CGs if the user doesn't want them
                if (inputBonusCG.Substring(0, 1) == "2" && filesListToNotUpdate.Any(entry.Name.Contains))
                {
                    continue;
                }

                //Update
                if (patchFilesList.ToArray().Length > i &&
                    entry.Name.Equals(fileName))
                {
                    resultFilesList.Add((Entry)patchFilesList.ToArray()[i]);
                    Console.WriteLine(fileName + " will be updated.");
                    i++;
                }
                //Insert new file(s) and the current original file
                else if (patchFilesList.ToArray().Length > i &&
                         entry.Type.Equals(((Entry)patchFilesList.ToArray()[i]).Type) &&
                         String.Compare(entry.Name, fileName) > 0)
                {
                    while (patchFilesList.ToArray().Length > i &&
                           entry.Type.Equals(((Entry)patchFilesList.ToArray()[i]).Type) &&
                           String.Compare(entry.Name, fileName) > 0 &&
                           !fileName.Equals("CGMODEAKMU.PNG"))
                    {
                        resultFilesList.Add((Entry)patchFilesList.ToArray()[i]);
                        Console.WriteLine(fileName + " will be inserted.");
                        i++;

                        //Updating the name of the file
                        if (patchFilesList.ToArray().Length > i)
                        {
                            fileName = ((Entry)patchFilesList.ToArray()[i]).Name;
                            //Remove the suffix of the name of the files
                            if (fileName.Contains(suffix))
                            {
                                fileName = fileName.Replace(suffix, "");
                            }
                        }
                    }

                    resultFilesList.Add(entry);
                }
                //Insert the current original file
                else
                {
                    resultFilesList.Add(entry);
                }
            }


            ////////////////////
            //WRITING PART
            ////////////////////
            Console.WriteLine("Writing...");

            var cp932   = Encodings.cp932.WithFatalFallback(); //cp932 is the encoding for the Japanese characters
            var nbFiles = resultFilesList.ToArray().Length;    //count the number of files

            //The file one_TEMP will be written directly into binary
            BinaryWriter bw = null;

            bw = new BinaryWriter(File.Create("./one_TEMP.lst"));
            Boolean headerWritten = false;
            long    offset        = 0;

            //The key is always equal to 01 in hexa (at least for ONE), it's possible to change it without any impact but I don't see the point to do it
            var key          = 0x01;
            var convertedKey = key;

            //The first operation takes the key, convert it into binary, move the bits to 8 positions towards the left and make a binary OR with the first key, I've put some examples
            //This allows the key to be on 32 bits instead of 8 (the program uses a lot of 32 bits functions)
            convertedKey |= convertedKey << 8;  //1 => 257, 0001 => 0000 0001 0000 0001
            convertedKey |= convertedKey << 16; //257 => 16 843 009 => 0001 0001 0001 0001

            //This key is used to encrypt the SNX files, she's always equal to 02
            //We only need the key to be on 8 bits so we don't do a conversion
            var keySNX = 0x02;

            //This part is used to initialize the variables used to read the one_TEMP file
            Stream stream = null;
            var    output = PhysicalFileSystem.CreateFile("./one_TEMP");

            //Loop that will treat each file, it's going to insert an entry into the one_TEMP.lst file and then insert it into the one_TEMP file afterwards
            foreach (Entry entry in resultFilesList)
            {
                //We start with the transformation of the data
                //Remove the suffix of the name of the files
                String fileName = entry.Name;
                if (fileName.Contains(suffix))
                {
                    fileName = fileName.Replace(suffix, "");
                }
                int    pointPosition = fileName.IndexOf(".");
                String extension     = fileName.Substring(pointPosition + 1, fileName.Length - pointPosition - 1);

                byte[] bufferName      = LstOpener.WriteName(fileName.Substring(0, pointPosition), 64, (byte)key, cp932);
                long   fileSize        = entry.Size ^ convertedKey;
                long   convertedOffset = offset ^ convertedKey;
                offset += entry.Size;

                //Type is the only part that is not encrypted with the key
                int type = 0;
                if (extension.Equals("SNX"))
                {
                    type = 1;
                }
                else if (extension.Equals("BMP"))
                {
                    type = 2;
                }
                else if (extension.Equals("PNG"))
                {
                    type = 3;
                }
                else if (extension.Equals("WAV"))
                {
                    type = 4;
                }
                else if (extension.Equals("OGG"))
                {
                    type = 5;
                }
                else
                {
                    type = -1;
                }

                //Byte writing in the lst file
                //Writing of the header
                if (!headerWritten)
                {
                    //The header corresponds to the 4 first bytes of the files, he indicates the number of files and the key (4th bytes)
                    var header = nbFiles ^ convertedKey;
                    bw.Write(header);
                    headerWritten = true;
                }
                bw.Write((int)convertedOffset);
                bw.Write((int)fileSize);
                bw.Write(bufferName);
                bw.Write(type);

                //Creation of the file into the one file
                //These two conditions are used to determinate if the current file comes from the original files or the patch files
                if (afsOriginalFiles.FileExists(entry.Name))
                {
                    stream = arcOriginalFiles.OpenEntry(entry);
                }
                else if (afsPatchFiles.FileExists(entry.Name))
                {
                    stream = arcPatchFiles.OpenEntry(entry);
                }

                int byteTempo = 0;
                //The SNX files need to be written byte by byte, indeed, we need to transform them because they're encrypted in the one file with a XOR key 02 to make sure that nobody can read them
                if (type == 1)
                {
                    while ((byteTempo = stream.ReadByte()) > -1)
                    {
                        byteTempo = byteTempo ^ keySNX;
                        output.WriteByte((byte)byteTempo); //we directly wrote the bytes into the file without using the stream
                    }
                }
                else
                {
                    stream.CopyTo(output);
                }

                stream.Dispose();
            }

            //The original Japanese version ends with 48 bytes corresponding to the end of a PNG file.
            //It's not the case for the English translation, it doesn't seem to have an impact in the game and it's very probably a mistake since the last file is also a PNG file (the value is duplicated).
            //However, I prefer to put it in order to have a faithful recreation of the file.
            if (inputLanguage.Substring(0, 1) == "1")
            {
                List <byte> listByteFinFichier = new List <byte> {
                    0xa4, 0x01, 0xcc, 0x9c, 0x72, 0x05, 0x0c, 0x0c, 0x33,
                    0x01, 0x47, 0x00, 0x8f, 0x07, 0xef, 0x9f, 0xce, 0xaa, 0x0a, 0x60, 0xb8, 0x6e, 0x5e, 0x0c, 0x7e, 0x0b,
                    0x30, 0x00, 0xf1, 0x70, 0xc4, 0x43, 0x75, 0x7e, 0x8f, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e,
                    0x44, 0xae, 0x42, 0x60, 0x82
                };

                foreach (byte b in listByteFinFichier)
                {
                    output.WriteByte(b);
                }
            }

            bw.Close();
            output.Close();
            output.Dispose();
            originalFile.Dispose();
            patchFile.Dispose();

            //At the end, we replace the original files with the files that we have created.
            File.SetAttributes("one", FileAttributes.Normal);
            File.SetAttributes("one.lst", FileAttributes.Normal);

            File.Delete("one");
            File.Delete("one.lst");

            File.Move("one_TEMP", "one");
            File.Move("one_TEMP.lst", "one.lst");

            Console.WriteLine("\nDone!");
            Console.WriteLine("\nPress any key to continue.");
            Console.ReadKey(true);
        }