Example #1
0
        private static Hed.Entry AddFile(string inputFolder, string filename, FileStream hedStream, FileStream pkgStream, bool shouldCompressData = false, bool shouldEncryptData = false)
        {
            var completeFilePath = Path.Combine(inputFolder, ORIGINAL_FILES_FOLDER_NAME, filename);
            var offset           = pkgStream.Position;

            #region Data

            using var newFileStream = File.OpenRead(completeFilePath);

            var header = new EgsHdAsset.Header()
            {
                // CompressedLenght => -2: no compression and encryption, -1: no compression
                CompressedLength     = !shouldCompressData ? !shouldEncryptData ? -2 : -1 : 0,
                DecompressedLength   = (int)newFileStream.Length,
                RemasteredAssetCount = 0,
                CreationDate         = -1
            };

            var decompressedData = newFileStream.ReadAllBytes();
            var compressedData   = decompressedData.ToArray();

            if (shouldCompressData)
            {
                compressedData          = Helpers.CompressData(decompressedData);
                header.CompressedLength = compressedData.Length;
            }

            // Encrypt and write current file data in the PKG stream
            // The seed used for encryption is the original data header
            var seed = new MemoryStream();
            BinaryMapping.WriteObject <EgsHdAsset.Header>(seed, header);

            var encryptionSeed = seed.ReadAllBytes();
            var encryptedData  = header.CompressedLength > -2 ? EgsEncryption.Encrypt(compressedData, encryptionSeed) : compressedData;

            // Write original file header
            BinaryMapping.WriteObject <EgsHdAsset.Header>(pkgStream, header);

            // Make sure to write the original file after remastered assets headers
            pkgStream.Write(encryptedData);

            #endregion

            // Write a new entry in the HED stream
            var hedHeader = new Hed.Entry()
            {
                MD5          = Helpers.ToBytes(Helpers.CreateMD5(filename)),
                ActualLength = (int)newFileStream.Length,
                DataLength   = (int)(pkgStream.Position - offset),
                Offset       = offset
            };

            BinaryMapping.WriteObject <Hed.Entry>(hedStream, hedHeader);

            return(hedHeader);
        }
Example #2
0
        private static Hed.Entry ReplaceFile(
            string inputFolder,
            string filename,
            FileStream hedStream,
            FileStream pkgStream,
            EgsHdAsset asset,
            Hed.Entry originalHedHeader = null)
        {
            var completeFilePath = Path.Combine(inputFolder, ORIGINAL_FILES_FOLDER_NAME, filename);

            var offset         = pkgStream.Position;
            var originalHeader = asset.OriginalAssetHeader;

            // Clone the original asset header
            var header = new EgsHdAsset.Header()
            {
                CompressedLength     = originalHeader.CompressedLength,
                DecompressedLength   = originalHeader.DecompressedLength,
                RemasteredAssetCount = originalHeader.RemasteredAssetCount,
                CreationDate         = originalHeader.CreationDate
            };

            // Use the base original asset data by default
            var decompressedData = asset.OriginalData;
            var encryptedData    = asset.OriginalRawData;
            var encryptionSeed   = asset.Seed;

            // We want to replace the original file
            if (File.Exists(completeFilePath))
            {
                Console.WriteLine($"Replacing original: {filename}!");

                using var newFileStream = File.OpenRead(completeFilePath);
                decompressedData        = newFileStream.ReadAllBytes();

                var compressedData       = decompressedData.ToArray();
                var compressedDataLenght = originalHeader.CompressedLength;

                // CompressedLenght => -2: no compression and encryption, -1: no compression
                if (originalHeader.CompressedLength > -1)
                {
                    compressedData       = Helpers.CompressData(decompressedData);
                    compressedDataLenght = compressedData.Length;
                }

                header.CompressedLength   = compressedDataLenght;
                header.DecompressedLength = decompressedData.Length;

                // Encrypt and write current file data in the PKG stream

                // The seed used for encryption is the original data header
                var seed = new MemoryStream();
                BinaryMapping.WriteObject <EgsHdAsset.Header>(seed, header);

                encryptionSeed = seed.ReadAllBytes();
                encryptedData  = header.CompressedLength > -2 ? EgsEncryption.Encrypt(compressedData, encryptionSeed) : compressedData;
            }

            // Write original file header
            BinaryMapping.WriteObject <EgsHdAsset.Header>(pkgStream, header);

            var remasteredHeaders = new List <EgsHdAsset.RemasteredEntry>();

            // Is there remastered assets?
            if (header.RemasteredAssetCount > 0)
            {
                remasteredHeaders = ReplaceRemasteredAssets(inputFolder, filename, asset, pkgStream, encryptionSeed, encryptedData);
            }
            else
            {
                // Make sure to write the original file after remastered assets headers
                pkgStream.Write(encryptedData);
            }

            // Write a new entry in the HED stream
            var hedHeader = new Hed.Entry()
            {
                MD5          = Helpers.ToBytes(Helpers.CreateMD5(filename)),
                ActualLength = decompressedData.Length,
                DataLength   = (int)(pkgStream.Position - offset),
                Offset       = offset
            };

            // For unknown reason, some files have a data length of 0
            if (originalHedHeader.DataLength == 0)
            {
                Console.WriteLine($"{filename} => {originalHedHeader.ActualLength} ({originalHedHeader.DataLength})");

                hedHeader.ActualLength = originalHedHeader.ActualLength;
                hedHeader.DataLength   = originalHedHeader.DataLength;
            }

            BinaryMapping.WriteObject <Hed.Entry>(hedStream, hedHeader);

            return(hedHeader);
        }