Пример #1
0
        /// <summary>
        ///     Read a file with decryption constants
        /// </summary>
        /// <param name="file"></param>
        /// <param name="game"></param>
        /// <param name="compressedSize"></param>
        /// <param name="size"></param>
        /// <param name="flags"></param>
        /// <param name="truth"></param>
        /// <param name="multiplier"></param>
        /// <param name="divisor"></param>
        /// <returns></returns>
        public static Span <byte> Read(Span <byte> file, string game, uint compressedSize, uint size, IDTableFlags flags, byte[] truth, ulong multiplier, ulong divisor)
        {
            if (compressedSize > file.Length)
            {
                Logger.Warn("PKGINFO", "Compressed Size is larger than actual file! The package info might have drifted from the saved files. Please verify game data!");
            }

            if (game == "VenusVacation" && file.IsKnown())
            {
                return(file);
            }

            if (flags.HasFlag(IDTableFlags.Encrypted) && (game != "VenusVacation" || flags.HasFlag(IDTableFlags.Compressed)))
            {
                var key = XOREncryption.Xor(size, truth, multiplier, divisor);
                file = XOREncryption.Crypt(file, key);
            }

            // ReSharper disable once InvertIf
            if (flags.HasFlag(IDTableFlags.Compressed) && file[4] == 0x78)
            {
                try
                {
                    var decompressedData = Stream8000Compression.Decompress(file, new CompressionOptions {
                        Length = size
                    });
                    if (decompressedData.Length != 0)
                    {
                        file = decompressedData;
                    }
                }
                catch (Exception e)
                {
                    Logger.Error("PKGINFO", e);
                }
            }

            return(file);
        }
Пример #2
0
        private static void Main(string[] args)
        {
            Logger.PrintVersion("Cethleann");
            var flags = CommandLineFlags.ParseFlags <GzFlags>(CommandLineFlags.PrintHelp, args);

            if (flags == null)
            {
                return;
            }

            var files = new List <string>();

            foreach (var arg in flags.Paths)
            {
                if (!Directory.Exists(arg))
                {
                    files.Add(arg);
                    continue;
                }

                files.AddRange(Directory.GetFiles(arg, flags.Mask, SearchOption.AllDirectories));
            }

            Func <byte[], byte[]>?method = null;
            string?ext = null;

            var options = new CompressionOptions
            {
                BlockSize        = flags.BlockSize,
                Alignment        = flags.Alignment,
                CompressionLevel = flags.Level,
                Length           = flags.Length,
                ForceLastBlock   = flags.CompressLast,
                PrefixSize       = flags.PrefixedSize,
                Type             = flags.Type
            };

            if (flags.IsDz)
            {
                ext = ".dz";
                if (flags.Compress)
                {
                    method = bytes => DzCompression.Compress(bytes, options).ToArray();
                }
                else
                {
                    method = bytes => DzCompression.Decompress(bytes, options).ToArray();
                }
            }
            else if (flags.IsStream)
            {
                ext = ".zl";
                if (flags.Compress)
                {
                    method = bytes => StreamCompression.Compress(bytes, options).ToArray();
                }
                else
                {
                    method = bytes => StreamCompression.Decompress(bytes, options).ToArray();
                }
            }
            else if (flags.IsStream8000)
            {
                ext = ".z";
                if (flags.Compress)
                {
                    method = bytes => Stream8000Compression.Compress(bytes, options).ToArray();
                }
                else
                {
                    method = bytes => Stream8000Compression.Decompress(bytes, options).ToArray();
                }
            }
            else if (flags.IsTable)
            {
                ext = ".gz";
                if (flags.Compress)
                {
                    method = bytes => TableCompression.Compress(bytes, options).ToArray();
                }
                else
                {
                    method = bytes => TableCompression.Decompress(bytes, options).ToArray();
                }
            }

            if (method == null)
            {
                Logger.Error("Cethleann", "You must specify a compression method!");
                return;
            }

            foreach (var file in files)
            {
                var target     = flags.Compress ? file + ext : Path.Combine(Path.GetDirectoryName(file) ?? "", Path.GetFileNameWithoutExtension(file));
                var baseTarget = target;
                var modulo     = 0;
                while (File.Exists(target) && flags.Compress)
                {
                    target = baseTarget + $"_{++modulo}";
                }
                Logger.Info("Cethleann", $"{(flags.Compress ? "C" : "Dec")}ompressing {Path.GetFileName(file)} to {target}");

                var bytes = File.ReadAllBytes(file);
                if (bytes.Length == 0)
                {
                    Logger.Info("Cethleann", $"{Path.GetFileName(file)} is empty");
                    continue;
                }

                File.WriteAllBytes(target, method(bytes));

                if (flags.Delete)
                {
                    File.Delete(file);
                }
            }
        }