Exemple #1
0
        public void Seeking_OperateCorrectly()
        {
            var data      = new byte[] { 1, 2, 3, 24, 1, 3, 24, 1, 3, 8, 3, 5, 7 };
            var subStream = new SubStream(new MemoryStream(data)
            {
                Position = 0
            }, 2, 9);

            MemoryStream ouputStream = new MemoryStream();

            subStream.CopyTo(ouputStream);

            Assert.AreEqual(subStream.Length, subStream.Position);

            CollectionAssert.AreEqual(
                data.Skip(2).Take(9).ToArray(),
                ouputStream.ToArray());

            subStream.Position = 4;

            ouputStream = new MemoryStream();
            subStream.CopyTo(ouputStream);

            CollectionAssert.AreEqual(
                data.Skip(2 + 4).Take(9 - 4).ToArray(),
                ouputStream.ToArray());
        }
Exemple #2
0
        private (IList <short>, Stream) SplitTiles(byte[] imageData, int bitDepth)
        {
            var tileSize = _tileEntrySize * bitDepth / 8;

            var result = new MemoryStream();
            var tiles  = new short[imageData.Length / tileSize];

            var tileDictionary = new Dictionary <uint, int>();
            var crc32          = Crc32.Create(Crc32Formula.Normal);

            var offset    = 0;
            var tileIndex = 0;

            for (var i = 0; i < imageData.Length / tileSize; i++)
            {
                var tileStream = new SubStream(new MemoryStream(imageData), offset, tileSize);
                var hash       = BinaryPrimitives.ReadUInt32BigEndian(crc32.Compute(tileStream));

                if (!tileDictionary.ContainsKey(hash))
                {
                    tileDictionary[hash] = tileIndex++;

                    tileStream.Position = 0;
                    tileStream.CopyTo(result);
                }

                tiles[i] = (short)tileDictionary[hash];
                offset  += tileSize;
            }

            return(tiles, result);
        }
Exemple #3
0
        /// <summary>
        /// Locate and load the encrypted FAT data into memory
        /// </summary>
        /// <returns>Returns true on success</returns>
        public bool LoadRawFAT()
        {
            // Read all File Table Data into Memory
            FAT.SetLength(0);

            long TotalFileInfoSize = (fileCount + extraFileCount) * fileInfoSize;

            _owner._gpFileStream.Seek(0, SeekOrigin.End);
            FirstFileInfoOffset = _owner._gpFileStream.Position;

            // Search for the first file location, it needs to be alligned to a 0x200 size block
            FirstFileInfoOffset -= headerSize;
            FirstFileInfoOffset -= TotalFileInfoSize;
            var dif = FirstFileInfoOffset % 0x200;

            // Align to previous block of 512 bytes
            FirstFileInfoOffset -= dif;

            _owner._gpFileStream.Position = FirstFileInfoOffset;

            SubStream _fat = new SubStream(_owner._gpFileStream, FirstFileInfoOffset, _owner._gpFileStream.Length - FirstFileInfoOffset);

            _fat.CopyTo(FAT);

            return(true);
        }
Exemple #4
0
        private (Stream imageData, Stream tileData) SplitTiles(Stream image, int bitDepth)
        {
            var tileByteDepth = 64 * bitDepth / 8;

            var tileTable = new MemoryStream();
            var imageData = new MemoryStream();

            using var tileBw  = new BinaryWriterX(tileTable, true);
            using var imageBw = new BinaryWriterX(imageData, true);

            if (_tileTableLegacyStart != null)
            {
                tileTable.Write(_tileTableLegacyStart, 0, _tileTableLegacyStart.Length);
            }

            var crc32          = Crc32.Create(Crc32Formula.Normal);
            var tileDictionary = new Dictionary <uint, int>();

            // Add placeholder tile for all 0's
            var zeroTileHash = ToUInt32BigEndian(crc32.Compute(new byte[tileByteDepth]));

            tileDictionary[zeroTileHash] = -1;

            var imageOffset = 0;
            var tileIndex   = 0;

            while (imageOffset < image.Length)
            {
                var tile     = new SubStream(image, imageOffset, tileByteDepth);
                var tileHash = ToUInt32BigEndian(crc32.Compute(tile));
                if (!tileDictionary.ContainsKey(tileHash))
                {
                    tile.Position = 0;
                    tile.CopyTo(imageBw.BaseStream);

                    tileDictionary[tileHash] = tileIndex++;
                }

                if (_tileTableLegacyStart != null)
                {
                    tileBw.Write(tileDictionary[tileHash]);
                }
                else
                {
                    tileBw.Write((short)tileDictionary[tileHash]);
                }

                imageOffset += tileByteDepth;
            }

            imageData.Position = tileTable.Position = 0;
            return(imageData, tileTable);
        }
Exemple #5
0
        private static void Main(string[] args)
        {
            try
            {
                Dictionary <string, RS5DirectoryEntry> directory = OpenRS5Files();
                Console.Write("Processing environment ... ");
                SubStream environdata = directory["environment"].Data.Chunks["DATA"].Data;
                using (Stream environfile = File.Create("environment.bin"))
                {
                    environdata.CopyTo(environfile);
                }
                RS5Environment environ = new RS5Environment(environdata);
                Dictionary <string, List <AnimationClip> > animclips = ProcessEnvironmentAnimations(environ);
                Console.WriteLine("Done");
                XElement environ_xml = environ.ToXML();

                try
                {
                    environ_xml.Save("environment.xml");
                    WriteRS5Contents(directory, animclips);
                }
                catch (UnauthorizedAccessException)
                {
                    System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly();
                    string exepath = Path.GetDirectoryName(asm.Location);
                    Console.WriteLine("Unable to write to working directory {0}", Environment.CurrentDirectory);
                    Console.WriteLine("Do you want to write to the directory the executable is in?");
                    Console.WriteLine("({0})", exepath);
                    Console.Write("[y/N] ");
                    ConsoleKeyInfo keyinfo = Console.ReadKey(false);
                    Console.WriteLine();
                    if (keyinfo.KeyChar == 'y' || keyinfo.KeyChar == 'Y')
                    {
                        Environment.CurrentDirectory = exepath;
                        environ_xml.Save("environment.xml");
                        WriteRS5Contents(directory, animclips);
                    }
                }
            }
            catch (FileNotFoundException)
            {
                Console.WriteLine("Unable to load RS5 files");
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine("Caught exception: {0}\n\nPlease report this to Ben Peddell <*****@*****.**>", ex.ToString());
            }


            Console.Error.Write("Press any key to exit");
            Console.ReadKey(true);
        }
Exemple #6
0
        public void SubStream_ReturnsSubSectionOfInnerStreamData(byte[] data, int offset, int amount)
        {
            var subStream = new SubStream(new MemoryStream(data)
            {
                Position = 0
            }, offset, amount);

            Assert.AreEqual(0, subStream.Position);
            Assert.AreEqual(amount, subStream.Length);

            MemoryStream ouputStream = new MemoryStream();

            subStream.CopyTo(ouputStream);

            Assert.AreEqual(subStream.Length, subStream.Position);

            CollectionAssert.AreEqual(
                data.Skip(offset).Take(amount).ToArray(),
                ouputStream.ToArray());
        }
Exemple #7
0
        private (Stream imageData, Stream tileData) SplitTiles(Stream image, int bitDepth)
        {
            var tileByteDepth = 64 * bitDepth / 8;

            var tileTable = new MemoryStream();
            var imageData = new MemoryStream();

            using var tileBw  = new BinaryWriterX(tileTable, true);
            using var imageBw = new BinaryWriterX(imageData, true);

            var crc32          = Crc32.Default;
            var tileDictionary = new Dictionary <uint, short>();

            // Add placeholder tile for all 0's
            var zeroTileHash = crc32.ComputeValue(new byte[tileByteDepth]);

            tileDictionary[zeroTileHash] = -1;

            var imageOffset = 0;
            var tileIndex   = 0;

            while (imageOffset < image.Length)
            {
                var tile     = new SubStream(image, imageOffset, tileByteDepth);
                var tileHash = crc32.ComputeValue(tile);
                if (!tileDictionary.ContainsKey(tileHash))
                {
                    tile.Position = 0;
                    tile.CopyTo(imageBw.BaseStream);

                    tileDictionary[tileHash] = (short)tileIndex++;
                }

                tileBw.Write(tileDictionary[tileHash]);

                imageOffset += tileByteDepth;
            }

            imageData.Position = tileTable.Position = 0;
            return(imageData, tileTable);
        }
Exemple #8
0
        static void Main(string[] args)
        {
#if !DEBUG
            if (args.Length < 1)
            {
                Console.WriteLine("FARC Pack");
                Console.WriteLine("=========");
                Console.WriteLine("Packer/unpacker for .FARC files.\n");
                Console.WriteLine("Usage:");
                Console.WriteLine("    FarcPack [options] [source] [destination]");
                Console.WriteLine("    Source can be either FARC or directory.");
                Console.WriteLine("    Destination can be left empty.\n");
                Console.WriteLine("Options:");
                Console.WriteLine("    -a, -alignment         Set alignment for output FARC.");
                Console.WriteLine("                           16 by default.\n");
                Console.WriteLine("    -c, --compress         Compress files in output FARC.");
                Console.WriteLine("                           Disabled by default.");
                Console.ReadLine();
                return;
            }
#endif
            string sourcePath      = null;
            string destinationPath = null;

            bool compress  = false;
            uint alignment = 16;

            for (int i = 0; i < args.Length; i++)
            {
                string arg = args[i];

                Func <string, string, bool> compare = (a, b) => arg.Equals(a, StringComparison.OrdinalIgnoreCase) || arg.Equals(b, StringComparison.OrdinalIgnoreCase);
                alignment = compare("-a", "-alignment") ? uint.Parse(args[++i]) : alignment;

                compress = compare("-c", "-compress") || compress;

                if (sourcePath == null && !compare("-c", "-compress") && !compare("-a", "-alignment"))
                {
                    sourcePath = arg;
                }


                else if (destinationPath == null && !compare("-c", "-compress") && !compare("-a", "-alignment"))
                {
                    destinationPath = arg;
                }
            }

#if DEBUG
            sourcePath = @"C:\Users\waelw.WAELS-PC\Desktop\farc\vr_cmn";
#endif

            if (sourcePath == null)
            {
                throw new ArgumentException("You must provide a source.", nameof(sourcePath));
            }

            var serial = new BinarySerializer();

            if (sourcePath.EndsWith(".farc", StringComparison.OrdinalIgnoreCase))
            {
                destinationPath = destinationPath ?? Path.ChangeExtension(sourcePath, null);
#if USE_NEW
                var archive = new FarcArchiveBin();
                using (var file = File.Open(sourcePath, FileMode.Open))
                {
                    archive = serial.Deserialize <FarcArchiveBin>(file);
                    archive.Unpack(destinationPath);
                }
#else
                var archive = new FarcArchive();
                archive.Load(sourcePath);

                using (Stream source = File.OpenRead(sourcePath))
                {
                    foreach (var entry in archive)
                    {
                        using (Stream entrySource = new SubStream(source, entry.Position, entry.Length))
                            using (Stream destination = File.Create(Path.Combine(destinationPath, entry.FileName)))
                            {
                                if (archive.IsEncrypted)
                                {
                                    using (AesManaged aes = new AesManaged
                                    {
                                        KeySize = 128,
                                        Key = FarcArchive.FarcEncryptionKeyBytes,
                                        BlockSize = 128,
                                        Mode = CipherMode.ECB,
                                        Padding = PaddingMode.Zeros,
                                        IV = new byte[16],
                                    })
                                        using (CryptoStream cryptoStream = new CryptoStream(
                                                   entrySource,
                                                   aes.CreateDecryptor(),
                                                   CryptoStreamMode.Read))
                                        {
                                            if (archive.IsCompressed && entry.Length != entry.CompressedLength)
                                            {
                                                using (GZipStream gzipStream = new GZipStream(cryptoStream, CompressionMode.Decompress))
                                                {
                                                    gzipStream.CopyTo(destination);
                                                }
                                            }

                                            else
                                            {
                                                cryptoStream.CopyTo(destination);
                                            }
                                        }
                                }

                                else if (archive.IsCompressed && entry.Length != entry.CompressedLength)
                                {
                                    using (GZipStream gzipStream = new GZipStream(entrySource, CompressionMode.Decompress))
                                    {
                                        gzipStream.CopyTo(destination);
                                    }
                                }

                                else
                                {
                                    entrySource.CopyTo(destination);
                                }
                            }
                    }
                }
#endif
            }

            else if (File.GetAttributes(sourcePath).HasFlag(FileAttributes.Directory))
            {
#if USE_NEW
                var archive = new FarcArchiveBin();
                archive.Alignment = (int)alignment;
#else
                var archive = new FarcArchive();
                archive.Alignment = alignment;
#endif
                archive.IsCompressed = compress;
#if DEBUG
                archive.Alignment = 64;
#endif
                destinationPath = destinationPath ?? sourcePath + ".farc";

                foreach (string fileName in Directory.GetFiles(sourcePath))
                {
#if USE_NEW
                    archive.Add(new FarcEntryBin(fileName));
#else
                    archive.Add(new FarcEntry
                    {
                        FileName = Path.GetFileName(fileName),
                        FilePath = new FileInfo(fileName)
                    });
#endif
                }

#if USE_NEW
                archive.Flush();
                using (var save = File.Create(destinationPath))
                {
                    serial.Serialize(save, archive);
                }
#else
                archive.Save(destinationPath);
#endif
            }
        }
Exemple #9
0
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("FARC Pack");
                Console.WriteLine("=========");
                Console.WriteLine("Packer/unpacker for .FARC files.\n");
                Console.WriteLine("Usage:");
                Console.WriteLine("    FarcPack [options] [source] [destination]");
                Console.WriteLine("    Source can be either FARC or directory.");
                Console.WriteLine("    Destination can be left empty.\n");
                Console.WriteLine("Options:");
                Console.WriteLine("    -a, -alignment         Set alignment for output FARC.");
                Console.WriteLine("                           16 by default.\n");
                Console.WriteLine("    -c, --compress         Compress files in output FARC.");
                Console.WriteLine("                           Disabled by default.");
                Console.ReadLine();
                return;
            }

            string sourcePath      = null;
            string destinationPath = null;

            bool compress  = false;
            uint alignment = 16;

            for (int i = 0; i < args.Length; i++)
            {
                string arg = args[i];

                if (arg.Equals("-a", StringComparison.OrdinalIgnoreCase) ||
                    arg.Equals("-alignment", StringComparison.OrdinalIgnoreCase))
                {
                    alignment = uint.Parse(args[++i]);
                }

                else if (arg.Equals("-c", StringComparison.OrdinalIgnoreCase) ||
                         arg.Equals("-compress", StringComparison.OrdinalIgnoreCase))
                {
                    compress = true;
                }

                else if (sourcePath == null)
                {
                    sourcePath = arg;
                }

                else if (destinationPath == null)
                {
                    destinationPath = arg;
                }
            }

            if (sourcePath == null)
            {
                throw new ArgumentException("You must provide a source.", nameof(sourcePath));
            }

            if (sourcePath.EndsWith(".farc", StringComparison.OrdinalIgnoreCase))
            {
                FarcArchive archive = new FarcArchive();
                archive.Load(sourcePath);

                if (destinationPath == null)
                {
                    destinationPath = Path.ChangeExtension(sourcePath, null);
                }

                Directory.CreateDirectory(destinationPath);

                using (Stream source = File.OpenRead(sourcePath))
                {
                    foreach (FarcEntry entry in archive)
                    {
                        using (Stream entrySource = new SubStream(source, entry.Position, entry.Length))
                            using (Stream destination = File.Create(Path.Combine(destinationPath, entry.FileName)))
                            {
                                if (archive.IsEncrypted)
                                {
                                    using (AesManaged aes = new AesManaged
                                    {
                                        KeySize = 128,
                                        Key = FarcArchive.FarcEncryptionKeyBytes,
                                        BlockSize = 128,
                                        Mode = CipherMode.ECB,
                                        Padding = PaddingMode.Zeros,
                                        IV = new byte[16],
                                    })
                                        using (CryptoStream cryptoStream = new CryptoStream(
                                                   entrySource,
                                                   aes.CreateDecryptor(),
                                                   CryptoStreamMode.Read))
                                        {
                                            if (archive.IsCompressed && entry.Length != entry.CompressedLength)
                                            {
                                                using (GZipStream gzipStream = new GZipStream(cryptoStream, CompressionMode.Decompress))
                                                {
                                                    gzipStream.CopyTo(destination);
                                                }
                                            }

                                            else
                                            {
                                                cryptoStream.CopyTo(destination);
                                            }
                                        }
                                }

                                else if (archive.IsCompressed && entry.Length != entry.CompressedLength)
                                {
                                    using (GZipStream gzipStream = new GZipStream(entrySource, CompressionMode.Decompress))
                                    {
                                        gzipStream.CopyTo(destination);
                                    }
                                }

                                else
                                {
                                    entrySource.CopyTo(destination);
                                }
                            }
                    }
                }
            }

            else if (File.GetAttributes(sourcePath).HasFlag(FileAttributes.Directory))
            {
                FarcArchive archive = new FarcArchive();
                archive.Alignment    = alignment;
                archive.IsCompressed = compress;

                if (destinationPath == null)
                {
                    destinationPath = sourcePath + ".farc";
                }

                foreach (string fileName in Directory.GetFiles(sourcePath))
                {
                    archive.Add(new FarcEntry
                    {
                        FileName = Path.GetFileName(fileName),
                        FilePath = new FileInfo(fileName)
                    });
                }

                archive.Save(destinationPath);
            }
        }