public static int GetCharacterCountIndicatorLength(int version, EncodeMode mode)
        {
            var versionsPart = version >= CharacterCountIndicatorLength[0, 0] && version <= CharacterCountIndicatorLength[0, 1]
                                ? 0
                                : version >= CharacterCountIndicatorLength[1, 0] && version <= CharacterCountIndicatorLength[1, 1]
                                        ? 1
                                        : version >= CharacterCountIndicatorLength[2, 0] && version <= CharacterCountIndicatorLength[2, 1] ? 2 : -1; //probably throw exception?

            return(CharacterCountIndicatorLength[versionsPart, 2 + (int)mode]);
        }
Esempio n. 2
0
 /// <summary>
 /// Encode a psb byte array manually
 /// </summary>
 /// <param name="key"></param>
 /// <param name="inputBytes"></param>
 /// <param name="mode"></param>
 /// <param name="position"></param>
 /// <returns></returns>
 public static byte[] EncodeToBytes(uint key, byte[] inputBytes, EncodeMode mode = EncodeMode.Encrypt, EncodePosition position = EncodePosition.Auto)
 {
     using (var input = new MemoryStream(inputBytes))
     {
         using (var output = new MemoryStream((int)input.Length))
         {
             Encode(key, mode, position, input, output);
             return(output.ToArray());
         }
     }
 }
        /// <summary>
        /// Decrypt with private key
        /// </summary>
        /// <param name="data"></param>
        /// <param name="encryptionEncodeMode"><see cref="CryptoBase.DefaultEncryptionEncodeMode"/></param>
        /// <param name="privateKey">Private key</param>
        /// <returns></returns>
        public string Decrypt(string data, EncodeMode encryptionEncodeMode, string privateKey)
        {
            if (string.IsNullOrWhiteSpace(data))
            {
                throw new ArgumentException("Value cannot be null or whitespace.", nameof(data));
            }
            if (string.IsNullOrWhiteSpace(privateKey))
            {
                throw new ArgumentException("Value cannot be null or whitespace.", nameof(privateKey));
            }

            return(DefaultEncoding.GetString(Decrypt(encryptionEncodeMode.DecodeToBytes(data, DefaultEncoding), privateKey)));
        }
        /// <summary>
        /// Encrypt with public key
        /// </summary>
        /// <param name="data"></param>
        /// <param name="encryptionEncodeMode"><see cref="CryptoBase.DefaultEncryptionEncodeMode"/></param>
        /// <param name="publicKey">Public key</param>
        /// <returns></returns>
        public string Encrypt(string data, EncodeMode encryptionEncodeMode, string publicKey)
        {
            if (string.IsNullOrWhiteSpace(data))
            {
                throw new ArgumentException("Value cannot be null or whitespace.", nameof(data));
            }
            if (string.IsNullOrWhiteSpace(publicKey))
            {
                throw new ArgumentException("Value cannot be null or whitespace.", nameof(publicKey));
            }

            return(encryptionEncodeMode.EncodeToString(Encrypt(DefaultEncoding.GetBytes(data), publicKey), DefaultEncoding));
        }
        /// <summary>
        /// Sign with private key
        /// </summary>
        /// <param name="data"></param>
        /// <param name="signatureEncodeMode"><see cref="CryptoAndSignatureBase.DefaultSignatureEncodeMode"/></param>
        /// <param name="privateKey">Private key</param>
        /// <returns></returns>
        public string SignData(string data, EncodeMode signatureEncodeMode, string privateKey)
        {
            if (string.IsNullOrWhiteSpace(data))
            {
                throw new ArgumentException("Value cannot be null or whitespace.", nameof(data));
            }
            if (string.IsNullOrWhiteSpace(privateKey))
            {
                throw new ArgumentException("Value cannot be null or whitespace.", nameof(privateKey));
            }

            return(signatureEncodeMode.EncodeToString(SignData(DefaultEncoding.GetBytes(data), privateKey), DefaultEncoding));
        }
Esempio n. 6
0
 /// <summary>
 /// Encrypt or decrypt PSB and write to a file
 /// </summary>
 /// <param name="key"></param>
 /// <param name="savePath"></param>
 /// <param name="mode"></param>
 /// <param name="position"></param>
 public void EncodeToFile(uint key, string savePath, EncodeMode mode = EncodeMode.Encrypt, EncodePosition position = EncodePosition.Auto)
 {
     using (var input = File.OpenRead(Path))
     {
         using (var output = File.Open(savePath, FileMode.Create, FileAccess.ReadWrite))
         {
             var header = Encode(key, mode, position, input, output);
             if (header != null)
             {
                 Header = header;
             }
         }
     }
 }
Esempio n. 7
0
        private double CalFrequency(EncodeMode type, uint channel)
        {
            switch (type)
            {
            case EncodeMode.X:
                return(CalXFrequency(channel));

            case EncodeMode.Y:
                return(CalYFrequency(channel));

            default:
                throw new Exception($"错误的EncodeType类型:{type}");
            }
        }
        /// <summary>
        /// Verification with public key
        /// </summary>
        /// <param name="data"></param>
        /// <param name="signature"></param>
        /// <param name="signatureEncodeMode"><see cref="CryptoAndSignatureBase.DefaultSignatureEncodeMode"/></param>
        /// <param name="publicKey">Public key</param>
        /// <returns></returns>
        public bool VerifyData(string data, string signature, EncodeMode signatureEncodeMode, string publicKey)
        {
            if (string.IsNullOrWhiteSpace(data))
            {
                throw new ArgumentException("Value cannot be null or whitespace.", nameof(data));
            }
            if (string.IsNullOrWhiteSpace(signature))
            {
                throw new ArgumentException("Value cannot be null or whitespace.", nameof(signature));
            }
            if (string.IsNullOrWhiteSpace(publicKey))
            {
                throw new ArgumentException("Value cannot be null or whitespace.", nameof(publicKey));
            }

            return(VerifyData(DefaultEncoding.GetBytes(data), signatureEncodeMode.DecodeToBytes(signature, DefaultEncoding), publicKey));
        }
Esempio n. 9
0
        /// <summary>
        /// 解码
        /// </summary>
        /// <param name="encodeMode"></param>
        /// <param name="data"></param>
        /// <param name="encoding"></param>
        /// <returns></returns>
        public static byte[] DecodeToBytes(this EncodeMode encodeMode, string data, Encoding encoding)
        {
            switch (encodeMode)
            {
            case EncodeMode.None:
                return(encoding.GetBytes(data));

            case EncodeMode.Base64:
                return(Base64CryptoProvider.DecryptBytes(data));

            case EncodeMode.Hex:
                return(HexCryptoProvider.DecryptBytes(data));

            case EncodeMode.Base64ToHex:
                return(Base64CryptoProvider.DecryptBytes(HexCryptoProvider.Decrypt(data, encoding)));

            default:
                throw new NotSupportedException($"{string.Format(Constants.NotSupportedEncodeMode2, encodeMode.ToString())}");
            }
        }
Esempio n. 10
0
 public void SetEncodeMode(EncodeMode encodeMode)
 {
     Model.EncodeMode_ini = encodeMode == EncodeMode.X ? "x" : "y";
     Model.EncodeMode     = encodeMode;
 }
Esempio n. 11
0
 public StringKey(string key, EncodeMode keyEncodeMode = EncodeMode.None)
 {
     _key           = key;
     _keyEncodeMode = keyEncodeMode;
 }
Esempio n. 12
0
 /// <summary>
 /// Careful use (only 4 of 40 version enabled)
 /// </summary>
 /// <param name="str">string to encode</param>
 /// <param name="errorCorrection">0 - 7%;1 - 15%; 2 - 25%; 3 - 30%</param>
 /// <param name="mode">0- numeric; 1- alphanumeric;2- Byte; 3- Kanji;</param>
 /// <param name="version">varsion of </param>
 /// <param name="maxCapacity">max capasity for input string</param>
 public static void GetMaxCapacityAndVersion(string str, ErrorCorrectionLvl errorCorrection, EncodeMode mode, out int version, out int maxCapacity)
 {
     maxCapacity = 0;
     version     = 0;
     while (str.Length > maxCapacity)
     {
         maxCapacity = DataMaxCapacityAndVersion[version * 4 + (int)errorCorrection, 2 + (int)mode];
         version++;
     }
 }
Esempio n. 13
0
 public BytesKey(byte[] key, EncodeMode keyEncodeMode = EncodeMode.None)
 {
     _key           = key;
     _keyEncodeMode = keyEncodeMode;
 }
Esempio n. 14
0
        public static void Encode(Memory <byte> outputStorage, ReadOnlyMemory <byte> data, int width, int height, EncodeMode mode)
        {
            int widthInBlocks  = (width + 3) / 4;
            int heightInBlocks = (height + 3) / 4;

            bool fastMode = (mode & EncodeMode.ModeMask) == EncodeMode.Fast;

            if (mode.HasFlag(EncodeMode.Multithreaded))
            {
                Parallel.For(0, heightInBlocks, (yInBlocks) =>
                {
                    Span <ulong> output = MemoryMarshal.Cast <byte, ulong>(outputStorage.Span);
                    int y = yInBlocks * 4;

                    for (int xInBlocks = 0; xInBlocks < widthInBlocks; xInBlocks++)
                    {
                        int x       = xInBlocks * 4;
                        Block block = CompressBlock(data.Span, x, y, width, height, fastMode);

                        int offset         = (yInBlocks * widthInBlocks + xInBlocks) * 2;
                        output[offset]     = block.Low;
                        output[offset + 1] = block.High;
                    }
                });
            }
            else
            {
                Span <ulong> output = MemoryMarshal.Cast <byte, ulong>(outputStorage.Span);
                int          offset = 0;

                for (int y = 0; y < height; y += 4)
                {
                    for (int x = 0; x < width; x += 4)
                    {
                        Block block = CompressBlock(data.Span, x, y, width, height, fastMode);

                        output[offset++] = block.Low;
                        output[offset++] = block.High;
                    }
                }
            }
        }
Esempio n. 15
0
 public virtual extern void GetEncodeMode([ComAliasName("DirectEncodeNET.EncodeMode")] out EncodeMode pnValue);
Esempio n. 16
0
        public static Plugin AttachFile(Plugin p, string dirName, string fileName, Stream srcStream, EncodeMode type = EncodeMode.Compress)
        {
            if (p == null)
            {
                throw new ArgumentNullException("p");
            }

            byte[] input = new byte[srcStream.Length];
            srcStream.Read(input, 0, input.Length);
            return(Encode(p, dirName, fileName, input, type));
        }
Esempio n. 17
0
        public static Plugin AttachFile(Plugin p, string dirName, string fileName, string srcFilePath, EncodeMode type = EncodeMode.Compress)
        {
            if (p == null)
            {
                throw new ArgumentNullException("p");
            }

            byte[] input;
            using (FileStream fs = new FileStream(srcFilePath, FileMode.Open, FileAccess.Read))
            {
                input = new byte[fs.Length];
                fs.Read(input, 0, input.Length);
            }
            return(Encode(p, dirName, fileName, input, type));
        }
Esempio n. 18
0
        public static Script AttachFile(Script p, string dirName, string fileName, byte[] srcBuffer, EncodeMode type = EncodeMode.ZLib)
        {
            if (p == null)
            {
                throw new ArgumentNullException("p");
            }

            return(Encode(p, dirName, fileName, srcBuffer, type));
        }
Esempio n. 19
0
        public static int GetCharacterCountIndicatorLength(int version, EncodeMode mode)
        {
            var versionsPart = version >= CharacterCountIndicatorLength[0, 0] && version <= CharacterCountIndicatorLength[0, 1]
                ? 0
                : version >= CharacterCountIndicatorLength[1, 0] && version <= CharacterCountIndicatorLength[1, 1]
                    ? 1
                    : version >= CharacterCountIndicatorLength[2, 0] && version <= CharacterCountIndicatorLength[2, 1] ? 2 : -1; //probably throw exception?

            return CharacterCountIndicatorLength[versionsPart,2+(int)mode];
        }
Esempio n. 20
0
 /// <summary>
 /// Sign with private key
 /// </summary>
 /// <param name="data"></param>
 /// <param name="signatureEncodeMode"><see cref="CryptoAndSignatureBase.DefaultSignatureEncodeMode"/></param>
 /// <returns></returns>
 public string SignData(string data, EncodeMode signatureEncodeMode)
 {
     return(SignData(data, signatureEncodeMode, PrivatekKey));
 }
Esempio n. 21
0
 /// <summary>
 /// Encrypt with public key
 /// </summary>
 /// <param name="data"></param>
 /// <param name="encryptionEncodeMode"><see cref="CryptoBase.DefaultEncryptionEncodeMode"/></param>
 /// <returns></returns>
 public string Encrypt(string data, EncodeMode encryptionEncodeMode)
 {
     return(Encrypt(data, encryptionEncodeMode, PublickKey));
 }
Esempio n. 22
0
 /// <summary>
 /// Decrypt with private key
 /// </summary>
 /// <param name="data"></param>
 /// <param name="encryptionEncodeMode"><see cref="CryptoBase.DefaultEncryptionEncodeMode"/></param>
 /// <returns></returns>
 public string Decrypt(string data, EncodeMode encryptionEncodeMode)
 {
     return(Decrypt(data, encryptionEncodeMode, PrivatekKey));
 }
Esempio n. 23
0
        /// <summary>
        /// Careful use (only 4 of 40 version enabled)
        /// </summary>
        /// <param name="str">string to encode</param>
        /// <param name="errorCorrection">0 - 7%;1 - 15%; 2 - 25%; 3 - 30%</param>
        /// <param name="mode">0- numeric; 1- alphanumeric;2- Byte; 3- Kanji;</param>
        /// <param name="version">varsion of </param> 
        /// <param name="maxCapacity">max capasity for input string</param>
        public static void GetMaxCapacityAndVersion( string str , ErrorCorrectionLvl errorCorrection , EncodeMode mode , out int version, out int maxCapacity )
        {
            maxCapacity = 0;
            version = 0;
            while ( str.Length > maxCapacity ) {

                maxCapacity = DataMaxCapacityAndVersion[version * 4 + (int) errorCorrection , 2 + (int) mode];
                version++;
            }
        }
Esempio n. 24
0
 /// <summary>
 /// Verification with public key
 /// </summary>
 /// <param name="data"></param>
 /// <param name="signature"></param>
 /// <param name="signatureEncodeMode"><see cref="CryptoAndSignatureBase.DefaultSignatureEncodeMode"/></param>
 /// <returns></returns>
 public bool VerifyData(string data, string signature, EncodeMode signatureEncodeMode)
 {
     return(VerifyData(data, signature, signatureEncodeMode, PublickKey));
 }
Esempio n. 25
0
 private static Script Encode(Script p, string dirName, string fileName, byte[] input, EncodeMode mode)
 {
     using (MemoryStream ms = new MemoryStream(input))
     {
         return(Encode(p, dirName, fileName, ms, mode));
     }
 }
Esempio n. 26
0
 /// <summary>
 /// Generate RSA public and private key by <see cref="RSA.ToXmlString"/>
 /// </summary>
 /// <param name="xmlPublicKey">Public key</param>
 /// <param name="xmlPrivateKey">Private key</param>
 public static void GenerateXmlKey(out string xmlPublicKey, out string xmlPrivateKey, EncodeMode keyEncodeMode, Encoding encoding)
 {
     using (var rsa = CreateRSAProvider())
     {
         xmlPublicKey  = keyEncodeMode.EncodeToString(rsa.ToXmlString(false), encoding);
         xmlPrivateKey = keyEncodeMode.EncodeToString(rsa.ToXmlString(true), encoding);
     }
 }
Esempio n. 27
0
        private static Plugin Encode(Plugin p, string dirName, string fileName, byte[] input, EncodeMode mode)
        {
            byte[] fileNameUTF8 = Encoding.UTF8.GetBytes(fileName);
            if (fileName.Length == 0 || 512 <= fileNameUTF8.Length)
            {
                throw new FileDecodeFailException($"Filename's UTF8 encoded length should be shorter than 512B");
            }

            // Check Overwrite
            bool fileOverwrite = false;

            if (p.Sections.ContainsKey(dirName))
            { // [{dirName}] section exists, check if there is already same file encoded
                List <string> lines = p.Sections[dirName].GetLines();
                if (lines.FirstOrDefault(x => x.Equals(fileName, StringComparison.OrdinalIgnoreCase)) != null)
                {
                    fileOverwrite = true;
                }
            }

            string encodedStr;

            using (MemoryStream bodyStream = new MemoryStream())
                using (MemoryStream footerStream = new MemoryStream())
                    using (MemoryStream concatStream = new MemoryStream())
                    {
                        // [Stage 1] Compress file with zlib
                        switch (mode)
                        {
                        case EncodeMode.Compress:
                        {
                            using (ZLibStream zs = new ZLibStream(bodyStream, CompressionMode.Compress, CompressionLevel.Level6, true))
                            {
                                zs.Write(input, 0, input.Length);
                            }

                            bodyStream.Position = 0;
                        }
                        break;

                        case EncodeMode.Raw:
                        {
                            bodyStream.Write(input, 0, input.Length);
                            bodyStream.Position = 0;
                        }
                        break;

                        default:
                            throw new InternalException($"Wrong EncodeMode [{mode}]");
                        }

                        // [Stage 2] Generate first footer
                        byte[] rawFooter = new byte[0x226]; // 0x550
                        {
                            // 0x000 - 0x1FF : Filename and its length
                            rawFooter[0] = (byte)fileNameUTF8.Length;
                            fileNameUTF8.CopyTo(rawFooter, 1);
                            for (int i = 1 + fileNameUTF8.Length; i < 0x200; i++)
                            {
                                rawFooter[i] = 0; // Null Pad
                            }
                            // 0x200 - 0x207 : 8B -> Length of raw file, in little endian
                            BitConverter.GetBytes(input.Length).CopyTo(rawFooter, 0x200);
                            switch (mode)
                            {
                            case EncodeMode.Compress: // Type 1
                                // 0x208 - 0x20F : 8B -> Length of zlibed body, in little endian
                                BitConverter.GetBytes(bodyStream.Length).CopyTo(rawFooter, 0x208);
                                // 0x210 - 0x21F : 16B -> Null padding
                                for (int i = 0x210; i < 0x220; i++)
                                {
                                    rawFooter[i] = 0;
                                }
                                break;

                            case EncodeMode.Raw: // Type 2
                                // 0x208 - 0x21F : 16B -> Null padding
                                for (int i = 0x208; i < 0x220; i++)
                                {
                                    rawFooter[i] = 0;
                                }
                                break;

                            default:
                                throw new InternalException($"Wrong EncodeMode [{mode}]");
                            }
                            // 0x220 - 0x223 : CRC32 of raw file
                            uint crc32 = Crc32Checksum.Crc32(input);
                            BitConverter.GetBytes(crc32).CopyTo(rawFooter, 0x220);
                            // 0x224         : 1B -> Compress Mode (Type 1 : 00, Type 2 : 01)
                            rawFooter[0x224] = (byte)mode;
                            // 0x225         : 1B -> ZLib Compress Level (Type 1 : 01 ~ 09, Type 2 : 00)
                            switch (mode)
                            {
                            case EncodeMode.Compress: // Type 1
                                rawFooter[0x225] = (byte)CompressionLevel.Level6;
                                break;

                            case EncodeMode.Raw: // Type 2
                                rawFooter[0x225] = 0;
                                break;

                            default:
                                throw new InternalException($"Wrong EncodeMode [{mode}]");
                            }
                        }

                        // [Stage 3] Compress first footer
                        using (ZLibStream zs = new ZLibStream(footerStream, CompressionMode.Compress, CompressionLevel.Default, true))
                        {
                            zs.Write(rawFooter, 0, rawFooter.Length);
                        }
                        footerStream.Position = 0;

                        // [Stage 4] Concat body and footer
                        bodyStream.CopyTo(concatStream);
                        footerStream.CopyTo(concatStream);
                        bodyStream.Position   = 0;
                        footerStream.Position = 0;

                        // [Stage 5] Generate final footer
                        {
                            byte[] finalFooter = new byte[0x24];

                            // 0x00 - 0x04 : 4B -> CRC32 of compressed body and compressed footer
                            uint crc32 = Crc32Checksum.Crc32(concatStream.ToArray());
                            BitConverter.GetBytes(crc32).CopyTo(finalFooter, 0x00);
                            // 0x04 - 0x08 : 4B -> Unknown - Always 1
                            BitConverter.GetBytes((uint)1).CopyTo(finalFooter, 0x04);
                            // 0x08 - 0x0B : 4B -> ZLBArchive version (Always 2)
                            BitConverter.GetBytes((uint)2).CopyTo(finalFooter, 0x08);
                            // 0x0C - 0x0F : 4B -> Zlib Compressed Footer Length
                            BitConverter.GetBytes((int)footerStream.Length).CopyTo(finalFooter, 0x0C);
                            // 0x10 - 0x17 : 8B -> Zlib Compressed File Length
                            BitConverter.GetBytes(bodyStream.Length).CopyTo(finalFooter, 0x10);
                            // 0x18 - 0x1B : 4B -> Unknown - Always 1
                            BitConverter.GetBytes((uint)1).CopyTo(finalFooter, 0x18);
                            // 0x1C - 0x23 : 8B -> Unknown - Always 0
                            for (int i = 0x1C; i < 0x24; i++)
                            {
                                finalFooter[i] = 0;
                            }

                            concatStream.Write(finalFooter, 0, finalFooter.Length);
                        }

                        // [Stage 6] Encode body, footer and finalFooter with Base64
                        encodedStr = Convert.ToBase64String(concatStream.ToArray());
                        // Remove Base64 Padding (==, =)
                        if (encodedStr.EndsWith("==", StringComparison.Ordinal))
                        {
                            encodedStr = encodedStr.Substring(0, encodedStr.Length - 2);
                        }
                        else if (encodedStr.EndsWith("=", StringComparison.Ordinal))
                        {
                            encodedStr = encodedStr.Substring(0, encodedStr.Length - 1);
                        }
                    }

            // [Stage 7] Tokenize encoded string into 4090B.
            string        section = $"EncodedFile-{dirName}-{fileName}";
            List <IniKey> keys    = new List <IniKey>();

            for (int i = 0; i <= (encodedStr.Length / 4090); i++)
            {
                if (i < (encodedStr.Length / 4090))                                                    // 1 Line is 4090 characters
                {
                    keys.Add(new IniKey(section, i.ToString(), encodedStr.Substring(i * 4090, 4090))); // X=eJyFk0Fr20AQhe8G...
                }
                else // Last Iteration
                {
                    keys.Add(new IniKey(section, i.ToString(), encodedStr.Substring(i * 4090, encodedStr.Length - (i * 4090)))); // X=N3q8ryccAAQWuBjqA5QvAAAAAA (end)
                    keys.Insert(0, new IniKey(section, "lines", i.ToString()));                                                  // lines=X
                }
            }

            // [Stage 8] Before writing to file, backup original plugin
            string tempFile = Path.GetTempFileName();

            File.Copy(p.FullPath, tempFile, true);

            // [Stage 9] Write to file
            try
            {
                // Write folder info to [EncodedFolders]
                bool writeFolderSection = true;
                if (p.Sections.ContainsKey("EncodedFolders"))
                {
                    List <string> folders = p.Sections["EncodedFolders"].GetLines();
                    if (0 < folders.Count(x => x.Equals(dirName, StringComparison.OrdinalIgnoreCase)))
                    {
                        writeFolderSection = false;
                    }
                }

                if (writeFolderSection)
                {
                    Ini.WriteRawLine(p.FullPath, "EncodedFolders", dirName, false);
                }

                // Write file info into [{dirName}]
                Ini.SetKey(p.FullPath, dirName, fileName, $"{input.Length},{encodedStr.Length}"); // UncompressedSize,EncodedSize

                // Write encoded file into [EncodedFile-{dirName}-{fileName}]
                if (fileOverwrite)
                {
                    Ini.DeleteSection(p.FullPath, section); // Delete existing encoded file
                }
                Ini.SetKeys(p.FullPath, keys);              // Write into
            }
            catch
            { // Error -> Rollback!
                File.Copy(tempFile, p.FullPath, true);
                throw new FileDecodeFailException($"Error while writing encoded file into [{p.FullPath}]");
            }
            finally
            { // Delete temp script
                File.Delete(tempFile);
            }

            // [Stage 10] Refresh Plugin
            return(p.Project.RefreshPlugin(p));
        }
Esempio n. 28
0
 public virtual extern void SetEncodeMode([In, ComAliasName("DirectEncodeNET.EncodeMode")] EncodeMode nValue);
Esempio n. 29
0
        /// <summary>
        /// Encode (Encrypt/Decrypt) PSB file
        /// </summary>
        /// <param name="key"></param>
        /// <param name="mode"></param>
        /// <param name="position"></param>
        /// <param name="input"></param>
        /// <param name="output"></param>
        /// <returns>Unencrypted Header for reference. Usually you shouldn't use it.</returns>
        public static PsbHeader Encode(uint key, EncodeMode mode, EncodePosition position, Stream input, Stream output)
        {
            input.Seek(0, SeekOrigin.Begin);
            output.Seek(0, SeekOrigin.Begin);
            PsbHeader        header  = new PsbHeader();
            PsbStreamContext context = new PsbStreamContext(key);
            BinaryReader     br      = new BinaryReader(input);
            BinaryWriter     bw      = new BinaryWriter(output);

            header.Signature = br.ReadChars(4);
            header.Version   = br.ReadUInt16();
            bw.Write(header.Signature);             //Signature
            bw.Write(header.Version);               //Version
            header.HeaderEncrypt = br.ReadUInt16(); //headerEncrypt, sometimes we don't believe it when encoding
            header.HeaderLength  = br.ReadUInt32();
            header.OffsetNames   = br.ReadUInt32();
            br.BaseStream.Seek(-8, SeekOrigin.Current);

            void WriteOriginal()
            {
                bw.Write(header.HeaderEncrypt);
                WriteOriginalPartialHeader(br, bw, header);
                WriteOriginalBody(br, bw);
            }

            switch (position)
            {
            case EncodePosition.Auto:
                bool headerEnc = TestHeaderEncrypted(br.BaseStream, header);
                bool bodyEnc   = TestBodyEncrypted(br, header);
                if (headerEnc && bodyEnc)     //MARK: is this possible?
                {
                    mode = EncodeMode.Decrypt;
                }

                if (!headerEnc && !bodyEnc)
                {
                    mode = EncodeMode.Encrypt;
                }

                switch (mode)
                {
                case EncodeMode.Encrypt:
                    if (header.Version > 2)         //Header Encrypted; Body Clean
                    {
                        bw.Write((ushort)1);
                        if (headerEnc)
                        {
                            WriteOriginalPartialHeader(br, bw, header);
                            WriteOriginalBody(br, bw);
                            break;
                        }

                        WriteEncryptPartialHeader(br, bw, context, header);
                        WriteOriginalBody(br, bw);
                        break;
                    }
                    else                     //Header Clean; Body Encrpyted
                    {
                        bw.Write((ushort)0); //
                        if (headerEnc)
                        {
                            WriteDecryptPartialHeader(br, bw, context, header);
                            context = new PsbStreamContext(key);
                            WriteEncodeBody(br, bw, context, header);
                        }
                        else
                        {
                            WriteOriginalPartialHeader(br, bw, header);
                            WriteEncodeBody(br, bw, context, header);
                        }
                    }

                    break;

                case EncodeMode.Decrypt:
                    bw.Write((ushort)0);          //
                    if (headerEnc)
                    {
                        WriteDecryptPartialHeader(br, bw, context, header);
                    }
                    else
                    {
                        WriteOriginalPartialHeader(br, bw, header);
                    }

                    if (bodyEnc)
                    {
                        WriteEncodeBody(br, bw, context, header);
                    }
                    else
                    {
                        WriteOriginalBody(br, bw);
                    }

                    break;

                default:
                    WriteOriginal();
                    break;
                }

                break;

            case EncodePosition.Body:
                switch (mode)
                {
                case EncodeMode.Encrypt:
                case EncodeMode.Decrypt:
                    bw.Write(header.HeaderEncrypt);
                    //We believe file is clean so write original header but encrypt body
                    WriteOriginalPartialHeader(br, bw, header);
                    WriteEncodeBody(br, bw, context, header);
                    break;

                default:
                    WriteOriginal();
                    break;
                }

                break;

            case EncodePosition.Header:
                switch (mode)
                {
                case EncodeMode.Encrypt:
                    bw.Write((ushort)1);
                    WriteEncryptPartialHeader(br, bw, context, header);
                    WriteOriginalBody(br, bw);
                    break;

                case EncodeMode.Decrypt:
                    bw.Write((ushort)0);          //
                    WriteDecryptPartialHeader(br, bw, context, header);
                    WriteOriginalBody(br, bw);
                    break;

                default:
                    WriteOriginal();
                    break;
                }

                break;

            case EncodePosition.Full:
                switch (mode)
                {
                case EncodeMode.Encrypt:
                    bw.Write((ushort)1);
                    WriteEncryptPartialHeader(br, bw, context, header);
                    WriteEncodeBody(br, bw, context, header);
                    break;

                case EncodeMode.Decrypt:
                    bw.Write((ushort)1);          //
                    WriteDecryptPartialHeader(br, bw, context, header);
                    WriteEncodeBody(br, bw, context, header);
                    break;

                default:
                    WriteOriginal();
                    break;
                }

                break;

            default:
                WriteOriginal();
                break;
            }

            bw.Flush();
            output.Seek(0, SeekOrigin.Begin);
            return(header);
        }
Esempio n. 30
0
        public static List <LogInfo> Encode(EngineState s, CodeCommand cmd)
        {
            List <LogInfo> logs = new List <LogInfo>();

            CodeInfo_Encode info = cmd.Info.Cast <CodeInfo_Encode>();

            string scriptFile = StringEscaper.Preprocess(s, info.ScriptFile);
            string dirName    = StringEscaper.Preprocess(s, info.DirName);
            string filePath   = StringEscaper.Preprocess(s, info.FilePath);

            EncodeMode mode = EncodeMode.ZLib;

            if (info.Compression != null)
            {
                string encodeModeStr = StringEscaper.Preprocess(s, info.Compression);
                if (encodeModeStr.Equals("None", StringComparison.OrdinalIgnoreCase))
                {
                    mode = EncodeMode.Raw;
                }
                else if (encodeModeStr.Equals("Deflate", StringComparison.OrdinalIgnoreCase))
                {
                    mode = EncodeMode.ZLib;
                }
                else if (encodeModeStr.Equals("LZMA2", StringComparison.OrdinalIgnoreCase))
                {
                    mode = EncodeMode.XZ;
                }
                else
                {
                    return(LogInfo.LogErrorMessage(logs, $"[{encodeModeStr}] is invalid compression"));
                }
            }

            Script sc = Engine.GetScriptInstance(s, s.CurrentScript.RealPath, scriptFile, out _);

            // Check srcFileName contains wildcard
            if (filePath.IndexOfAny(new char[] { '*', '?' }) == -1)
            { // No Wildcard
                s.MainViewModel.SetBuildCommandProgress("Encode Progress", 1);
                try
                {
                    object             progressLock = new object();
                    IProgress <double> progress     = new Progress <double>(x =>
                    {
                        lock (progressLock)
                        {
                            s.MainViewModel.BuildCommandProgressValue = x;
                            if (x < EncodedFile.CompReportFactor) // [Stage 1] Compress
                            {
                                s.MainViewModel.BuildCommandProgressText = $"Compressing \"{filePath}\"\r\n({x * 100:0.0}%)";
                            }
                            else // [Stage 2] Base64
                            {
                                s.MainViewModel.BuildCommandProgressText = $"Writing \"{filePath}\" to script\r\n({x * 100:0.0}%)";
                            }
                        }
                    });

                    EncodedFile.AttachFile(sc, dirName, Path.GetFileName(filePath), filePath, mode, progress);

                    logs.Add(new LogInfo(LogState.Success, $"[{filePath}] was encoded into [{sc.RealPath}]", cmd));
                }
                finally
                {
                    s.MainViewModel.ResetBuildCommandProgress();
                }
            }
            else
            { // With Wildcard
                // Use FileHelper.GetDirNameEx to prevent ArgumentException of Directory.GetFiles
                string   srcDirToFind = FileHelper.GetDirNameEx(filePath);
                string[] files        = Directory.GetFiles(srcDirToFind, Path.GetFileName(filePath));

                // No file will be compressed
                if (files.Length == 0)
                {
                    logs.Add(new LogInfo(LogState.Warning, $"Files matching wildcard [{filePath}] were not found", cmd));
                    return(logs);
                }

                s.MainViewModel.SetBuildCommandProgress("Encode Progress", files.Length);
                try
                {
                    int                i            = 0;
                    object             progressLock = new object();
                    IProgress <double> progress     = new Progress <double>(x =>
                    {
                        lock (progressLock)
                        {
                            s.MainViewModel.BuildCommandProgressText  = $"Attaching {filePath}...\r\n({(x + i) * 100:0.0}%)";
                            s.MainViewModel.BuildCommandProgressValue = x + i;
                        }
                    });

                    // One or more file will be copied
                    logs.Add(new LogInfo(LogState.Success, $"[{filePath}] will be encoded into [{sc.RealPath}]", cmd));
                    foreach (string f in files)
                    {
                        EncodedFile.AttachFile(sc, dirName, Path.GetFileName(f), f, mode, progress);
                        logs.Add(new LogInfo(LogState.Success, $"[{f}] encoded ({i + 1}/{files.Length})", cmd));

                        i += 1;
                    }

                    logs.Add(new LogInfo(LogState.Success, $"[{files.Length}] files copied", cmd));
                }
                finally
                {
                    s.MainViewModel.ResetBuildCommandProgress();
                }
            }

            return(logs);
        }