Exemple #1
0
        /// <summary>
        /// Decompresses LZMA. Uses native code if non-streamed (produced by lzma.exe), uses managed code if streamed (which can be done by things such as PHP)
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static byte[] DecompressLZMA(MemoryStream input)
        {
            input.Position = 5;
            var lzmaLen = input.ReadInt32();

            input.Position = 0;
            if (lzmaLen > 0)
            {
                // Non streamed LZMA
                return(LZMA.DecompressLZMAFile(input.ToArray()));
            }
            else
            {
                // It's streaming lzma. MEM code can't handle streamed so we have to fallback
                var lzmads = new LzmaDecodeStream(input);
                using var decompressedStream = new MemoryStream();
                int    bufSize = 24576, count;
                byte[] buf = new byte[bufSize];
                while (/*lzmads.Position < lzmaFile.Length && */ (count = lzmads.Read(buf, 0, bufSize)) > 0)
                {
                    decompressedStream.Write(buf, 0, count);
                }
                return(decompressedStream.ToArray());
            }
        }
Exemple #2
0
        internal static byte[] DecompressLZMAFile(byte[] lzmaFile)
        {
            int len = (int)BitConverter.ToInt32(lzmaFile, 5); //this is technically a 32-bit but since MEM code can't handle 64 bit sizes we are just going to use 32bit.

            if (len >= 0)
            {
                byte[] strippedData = new byte[lzmaFile.Length - 8];
                //Non-Streamed (made from disk)
                Buffer.BlockCopy(lzmaFile, 0, strippedData, 0, 5);
                Buffer.BlockCopy(lzmaFile, 13, strippedData, 5, lzmaFile.Length - 13);
                return(Decompress(strippedData, (uint)len));
            }
            else if (len == -1)
            {
                //Streamed. MEM code can't handle streamed so we have to fallback
                var lzmads = new LzmaDecodeStream(new MemoryStream(lzmaFile));
                using var decompressedStream = new MemoryStream();
                int    bufSize = 24576, count;
                byte[] buf = new byte[bufSize];
                while (/*lzmads.Position < lzmaFile.Length && */ (count = lzmads.Read(buf, 0, bufSize)) > 0)
                {
                    decompressedStream.Write(buf, 0, count);
                }
                return(decompressedStream.ToArray());
            }
            else
            {
                Debug.WriteLine("Cannot decompress LZMA array: Length is not positive or -1 (" + len + ")! This is not an LZMA array");
                return(null); //Not LZMA!
            }
        }
Exemple #3
0
        public static Vector <int>[,] Load(DctParameters parameters)
        {
            using (var fileStream = File.Open(parameters.SavePath, FileMode.Open))
                using (var decodeStream = new LzmaDecodeStream(fileStream))
                    using (var reader = new BinaryReader(decodeStream))
                    {
                        parameters.DecimationType   = (DecimationType)reader.ReadByte();
                        parameters.QuantizationType = (QuantizationType)reader.ReadByte();
                        switch (parameters.QuantizationType)
                        {
                        case QuantizationType.LargestN:
                            parameters.Ny = reader.ReadInt32();
                            parameters.Nc = reader.ReadInt32();
                            break;

                        case QuantizationType.QuantizationMatrix:
                            var a = reader.ReadInt32();
                            var b = reader.ReadInt32();
                            var c = reader.ReadInt32();
                            var d = reader.ReadInt32();
                            parameters.GeneratorsY = new MatrixGenerators
                            {
                                Alpha = a,
                                Gamma = b,
                            };
                            parameters.GeneratorsC = new MatrixGenerators
                            {
                                Alpha = c,
                                Gamma = d,
                            };
                            break;

                        case QuantizationType.DefaultJpegMatrix:
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }
                        var n = reader.ReadInt32();
                        var m = reader.ReadInt32();

                        var result = new Vector <int> [n, m];
                        for (var i = 0; i < n; ++i)
                        {
                            for (var j = 0; j < m; ++j)
                            {
                                var a = reader.ReadInt32();
                                var b = reader.ReadInt32();
                                var c = reader.ReadInt32();
                                result[i, j] = new Vector <int>(new [] { a, b, c });
                            }
                        }
                        return(result);
                    }
        }
Exemple #4
0
        /// <summary>
        /// 使用Lzma算法从字节流解压缩为集合
        /// </summary>
        /// <typeparam name="Data"></typeparam>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public static List <Data> Decodes <Data>(byte[] buffer) where Data : class
        {
            if (buffer == null || buffer.Length == 0)
            {
                return(null);
            }
            List <Data> lstData = new List <Data>();

            using (var input = new MemoryStream())
            {
                input.Write(buffer, 0, buffer.Length);
                input.Position = 0;
                var decoder = new LzmaDecodeStream(input);
                using (MemoryStream output = new MemoryStream())
                {
                    int    bufSize = 24576, count;
                    byte[] buf = new byte[bufSize];
                    while ((count = decoder.Read(buf, 0, bufSize)) > 0)
                    {
                        output.Write(buf, 0, count);
                    }
                    output.Position = 0;
                    BinaryFormatter formatter = new BinaryFormatter();
                    while (true)
                    {
                        if (output.Position == output.Length)
                        {
                            break;
                        }
                        Data data = null;
                        try
                        {
                            data = formatter.Deserialize(output) as Data;
                        }
                        catch (SerializationException ex)
                        {
                            LogHelper.GetInstance().Write("反序列化失败!");
                        }
                        if (data == null)
                        {
                            break;
                        }
                        lstData.Add(data);
                    }
                }
                decoder.Close();
            }
            return(lstData);
        }
Exemple #5
0
        public void LzmaEncodeDecodeTest()
        {
            using (var output = new FileStream(TemporaryFile, FileMode.Create))
            {
                var encoder = new LzmaEncodeStream(output);
                using (var inputSample = new FileStream(@"TestData\zip.zip", FileMode.Open))
                {
                    int bufSize = 24576, count;
                    var buf = new byte[bufSize];

                    while ((count = inputSample.Read(buf, 0, bufSize)) > 0)
                    {
                        encoder.Write(buf, 0, count);
                    }
                }

                encoder.Close();
            }

            var newZip = Path.Combine(OutputDirectory, "new.zip");

            using (var input = new FileStream(TemporaryFile, FileMode.Open))
            {
                var decoder = new LzmaDecodeStream(input);
                using (var output = new FileStream(newZip, FileMode.Create))
                {
                    int bufSize = 24576, count;
                    var buf = new byte[bufSize];

                    while ((count = decoder.Read(buf, 0, bufSize)) > 0)
                    {
                        output.Write(buf, 0, count);
                    }
                }
            }

            Assert.IsTrue(File.Exists(newZip));

            using (var extractor = new SevenZipExtractor(newZip))
            {
                Assert.AreEqual(1, extractor.FilesCount);
                Assert.AreEqual("zip.txt", extractor.ArchiveFileNames[0]);
            }
        }
Exemple #6
0
 public EncodedBitSequenceReader(Stream s, string compression)
 {
     if (compression == "none")
     {
         bits = new ReadBitShepherd(s);
     }
     else if (compression == "gzip")
     {
         GZipInputStream zipReader = new GZipInputStream(s);
         bits = new ReadBitShepherd(zipReader);
     }
     else if (compression == "lzma")
     {
         LzmaDecodeStream zipReader = new LzmaDecodeStream(s);
         bits = new ReadBitShepherd(zipReader);
     }
     else
     {
         throw new InvalidOperationException("Wrong compression method given");
     }
 }
Exemple #7
0
 public static BitmapSource OpenWavelet(string path)
 {
     using (var inputStream = File.OpenRead(path))
         using (var decodeStream = new LzmaDecodeStream(inputStream))
             using (var reader = new BinaryReader(decodeStream))
             {
                 var pixelHeight     = reader.ReadInt32();
                 var pixelWidth      = reader.ReadInt32();
                 var dpiX            = reader.ReadDouble();
                 var dpiY            = reader.ReadDouble();
                 var waveletType     = (WaveletType)reader.ReadByte();
                 var iterationsCount = reader.ReadInt32();
                 var channelsCount   = reader.ReadInt32();
                 var channels        = new Vector <double[, ]>(channelsCount);
                 for (var i = 0; i < channelsCount; ++i)
                 {
                     channels[i] = DecodeChannel(ReadChannel(reader), waveletType, iterationsCount);
                 }
                 var pixels = GetBytes(channels);
                 return(BitmapSource.Create(pixelWidth, pixelHeight, dpiX, dpiY, channelsCount == 1 ? PixelFormats.Gray8 : PixelFormats.Bgr32, null, pixels, pixels.Length / pixelHeight));
             }
 }
Exemple #8
0
        public bool unzipFile(string filePath, out string result)
        {
            FileInfo fileInfo = new FileInfo(filePath);

            // Step 1. Fix file
            fixFile(filePath, fileInfo);

            // Step 2. Unzip file
            string outputPath = fileInfo.FullName.Replace(".csv", "_r.csv");

            try
            {
                using (var input = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite))
                {
                    var decoder = new LzmaDecodeStream(input);
                    using (var output = new FileStream(outputPath, FileMode.Create))
                    {
                        int    bufSize = 24576, count;
                        byte[] buf = new byte[bufSize];
                        while ((count = decoder.Read(buf, 0, bufSize)) > 0)
                        {
                            output.Write(buf, 0, count);
                        }
                    }
                    decoder.Close();
                }
            }
            catch (Exception)
            {
                result = "[Broken file]\t" + fileInfo.Name;
                File.Delete(outputPath);
                return(false);
            }
            result = "[Unzip file]\t" + fileInfo.Name;
            return(true);
        }
Exemple #9
0
        public static LTBFile Read(FileInfo info)
        {
            var bFlip = info.Name.StartsWith("PV");

            var ltbFile = new LTBFile();

            var br = new ExtendedBinaryReader(info.OpenRead());

            #region Header

            var header = br.ReadUInt16();
            if (header > 20)
            {
                br.Close();
                var lzmaStream = new LzmaDecodeStream(info.OpenRead());
                var ms         = new MemoryStream();

                lzmaStream.CopyTo(ms);

                if (ms.Length == 0)
                {
                    Console.WriteLine($"{info.Name} is not a vaild LTB file.");

                    return(null);
                }

                br = new ExtendedBinaryReader(ms);
                br.Skip(0, true);
            }

            // Skip header
            br.Skip(0x14, true);

            uint version = br.ReadUInt32();

            uint nKeyFrame        = br.ReadUInt32();
            uint nAnim            = br.ReadUInt32();
            uint numBones         = br.ReadUInt32();
            uint nPieces          = br.ReadUInt32();
            uint nChildModels     = br.ReadUInt32();
            uint nTris            = br.ReadUInt32();
            uint nVerts           = br.ReadUInt32();
            uint nVertexWeights   = br.ReadUInt32();
            uint nLODs            = br.ReadUInt32();
            uint nSockets         = br.ReadUInt32();
            uint nWeightSets      = br.ReadUInt32();
            uint nStrings         = br.ReadUInt32();
            uint StringLengths    = br.ReadUInt32();
            uint VertAnimDataSize = br.ReadUInt32();
            uint nAnimData        = br.ReadUInt32();

            string cmdString    = br.ReadStringWithUInt16Length();
            float  globalRadius = br.ReadSingle();

            uint iNumEnabledOBBs = br.ReadUInt32();

            if (iNumEnabledOBBs != 0)
            {
                throw new Exception("LTB with OBB infomations are not supported");
            }

            uint numMesh = br.ReadUInt32();

            #endregion

            var romanisation = new McCuneReischauerRomanisation {
                PreserveNonKoreanText = true
            };

            #region Mesh nodes
            for (int i = 0; i < numMesh; i++)
            {
                string meshName = br.ReadStringWithUInt16Length(ltbEncode);

                meshName = romanisation.RomaniseText(meshName);

                foreach (var kvp in replaceDictionary)
                {
                    meshName = meshName.Replace(kvp.Key, kvp.Value);
                }

                meshName = meshName.ToLower();

                uint numLod = br.ReadUInt32();

                Console.WriteLine($"{meshName} - {numLod} Lods");

                meshName = meshName.ToLower();

                br.Skip((int)numLod * 4 + 8);

                int materialIndex = -1;

                if (!ltbFile.Materials.Any(material => material.Name == meshName))
                {
                    ltbFile.Materials.Add(new SEModelMaterial
                    {
                        Name         = "mtl_" + meshName,
                        MaterialData = new SEModelSimpleMaterial
                        {
                            DiffuseMap = meshName + ".png"
                        }
                    });

                    materialIndex = ltbFile.Materials.Count - 1;
                }
                else
                {
                    materialIndex = ltbFile.Materials.FindIndex(mtl => mtl.Name == meshName);
                }

                for (int iLod = 0; iLod < numLod; iLod++)
                {
                    var mesh = new SEModelMesh();
                    mesh.AddMaterialIndex(materialIndex);

                    var       nNumTex            = br.ReadUInt32();
                    const int MAX_PIECE_TEXTURES = 4;

                    for (int iTex = 0; iTex < MAX_PIECE_TEXTURES; iTex++)
                    {
                        // Texture index
                        br.ReadUInt32();
                    }

                    var renderStyle     = br.ReadUInt32();
                    var nRenderPriority = br.ReadByte();

                    var lodType = (PieceType)br.ReadUInt32();

                    var lodSize = br.ReadUInt32();

                    if (lodSize != 0)
                    {
                        uint numVerts = br.ReadUInt32();
                        uint numTris  = br.ReadUInt32();

                        uint iMaxBonesPerTri  = br.ReadUInt32();
                        uint iMaxBonesPerVert = br.ReadUInt32();

                        Console.WriteLine($"    Lod {iLod}: \n        Vertex count: {numVerts}\n        Triangle count: {numTris}");

                        bool bReIndexBones = false, bUseMatrixPalettes = false;

                        if (lodType == PieceType.SkelMesh)
                        {
                            bReIndexBones = br.ReadBoolean();
                        }

                        DataType[] streamData = { (DataType)br.ReadUInt32(), (DataType)br.ReadUInt32(), (DataType)br.ReadUInt32(), (DataType)br.ReadUInt32() };

                        uint rigidBone = uint.MaxValue;

                        if (lodType == PieceType.RigidMesh)
                        {
                            rigidBone = br.ReadUInt32();
                        }
                        else if (lodType == PieceType.SkelMesh)
                        {
                            bUseMatrixPalettes = br.ReadBoolean();
                        }
                        else
                        {
                            throw new Exception("Unsupported lod type");
                        }

                        if (bUseMatrixPalettes)
                        {
                            uint iMinBone = br.ReadUInt32();
                            uint iMaxBone = br.ReadUInt32();
                        }

                        var boneMap = new List <uint>();

                        if (bReIndexBones)
                        {
                            uint reindexBoneMapSize = br.ReadUInt32();

                            for (int iMap = 0; iMap < reindexBoneMapSize; iMap++)
                            {
                                boneMap.Add(br.ReadUInt32());
                            }
                        }

                        for (int iStream = 0; iStream < 4; ++iStream)
                        {
                            if (!streamData[iStream].HasFlag(DataType.Position))
                            {
                                continue;
                            }

                            for (int iVert = 0; iVert < numVerts; iVert++)
                            {
                                var v = new SEModelVertex();

                                if (streamData[iStream].HasFlag(DataType.Position))
                                {
                                    v.Position = new Vector3
                                    {
                                        X = br.ReadSingle(),
                                        Y = br.ReadSingle(),
                                        Z = br.ReadSingle(),
                                    };

                                    if (bFlip)
                                    {
                                        v.Position.X *= -1;
                                    }

                                    if (rigidBone == uint.MaxValue)
                                    {
                                        var weightSum = 0.0f;

                                        var maxWeight = bUseMatrixPalettes ? iMaxBonesPerVert : iMaxBonesPerTri;

                                        for (int iWeight = 0; iWeight < maxWeight - 1; iWeight++)
                                        {
                                            var weight = br.ReadSingle();

                                            if (weight > 1)
                                            {
                                                throw new Exception("wtf");
                                            }

                                            weightSum += weight;

                                            v.Weights.Add(new SEModelWeight
                                            {
                                                BoneIndex  = uint.MaxValue,
                                                BoneWeight = weight
                                            });
                                        }

                                        if (1.0f - weightSum > float.Epsilon)
                                        {
                                            v.Weights.Add(new SEModelWeight
                                            {
                                                BoneIndex  = uint.MaxValue,
                                                BoneWeight = 1.0f - weightSum
                                            });
                                        }

                                        if (bUseMatrixPalettes)
                                        {
                                            for (int iWeight = 0; iWeight < 4; iWeight++)
                                            {
                                                var boneIndex = br.ReadByte();

                                                if (bReIndexBones)
                                                {
                                                    boneIndex = (byte)boneMap[boneIndex];
                                                }

                                                if (v.Weights.Count > iWeight)
                                                {
                                                    v.Weights[iWeight].BoneIndex = boneIndex;
                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        if (rigidBone >= numBones || rigidBone < 0)
                                        {
                                            throw new Exception("wtf");
                                        }

                                        v.Weights.Add(new SEModelWeight
                                        {
                                            BoneIndex  = rigidBone,
                                            BoneWeight = 1.0f
                                        });
                                    }
                                }

                                if (streamData[iStream].HasFlag(DataType.Normal))
                                {
                                    v.VertexNormal = new Vector3
                                    {
                                        X = br.ReadSingle(),
                                        Y = br.ReadSingle(),
                                        Z = br.ReadSingle(),
                                    };

                                    if (bFlip)
                                    {
                                        v.VertexNormal.X *= -1;
                                    }
                                }

                                if (streamData[iStream].HasFlag(DataType.Color))
                                {
                                    br.Skip(4);
                                }

                                if (streamData[iStream].HasFlag(DataType.UVSets1))
                                {
                                    v.UVSets.Add(new Vector2
                                    {
                                        X = br.ReadSingle(),
                                        Y = br.ReadSingle()
                                    });

                                    if (v.UVSets[0].X > 1.0f)
                                    {
                                        v.UVSets[0].X -= 1.0f;
                                    }
                                }

                                if (streamData[iStream].HasFlag(DataType.UVSets2))
                                {
                                    br.Skip(8);
                                }
                                if (streamData[iStream].HasFlag(DataType.UVSets3))
                                {
                                    br.Skip(8);
                                }
                                if (streamData[iStream].HasFlag(DataType.UVSets4))
                                {
                                    br.Skip(8);
                                }
                                if (streamData[iStream].HasFlag(DataType.BasisVectors))
                                {
                                    br.Skip(24);
                                }

                                if (v.Position == null || v.WeightCount == 0)
                                {
                                    throw new Exception("wtf");
                                }

                                mesh.AddVertex(v);
                            }
                        }

                        for (uint iTriangle = 0; iTriangle < numTris; iTriangle++)
                        {
                            mesh.AddFace(br.ReadUInt16(), br.ReadUInt16(), br.ReadUInt16());
                        }

                        if (lodType == PieceType.SkelMesh && !bUseMatrixPalettes)
                        {
                            var boneComboCount = br.ReadUInt32();

                            for (int iCombo = 0; iCombo < boneComboCount; iCombo++)
                            {
                                int m_BoneIndex_Start = br.ReadUInt16();
                                int m_BoneIndex_End   = m_BoneIndex_Start + br.ReadUInt16();

                                Console.WriteLine($"        Weight Combo: {m_BoneIndex_Start} to {m_BoneIndex_End}");

                                var bones = br.ReadBytes(4);

                                uint m_iIndexIndex = br.ReadUInt32();

                                for (int iVertex = m_BoneIndex_Start; iVertex < m_BoneIndex_End; iVertex++)
                                {
                                    for (int iBone = 0; iBone < 4 && bones[iBone] != 0xFF; iBone++)
                                    {
                                        if (mesh.Verticies[iVertex].Weights.Count <= iBone)
                                        {
                                            break;
                                        }

                                        mesh.Verticies[iVertex].Weights[iBone].BoneIndex = bones[iBone];
                                    }
                                }
                            }
                        }

                        ltbFile.Meshes.Add(mesh);
                        br.Skip(br.ReadByte());
                    }
                }
            }
            #endregion

            #region Bones
            uint[] boneTree = new uint[numBones];

            for (int i = 0; i < numBones; i++)
            {
                var boneName = br.ReadStringWithUInt16Length();
                var boneId   = br.ReadByte();
                var num2     = br.ReadUInt16();

                Matrix4x4 transformMatrix = new Matrix4x4();

                for (int j = 0; j < 4; j++)
                {
                    for (int k = 0; k < 4; k++)
                    {
                        transformMatrix[j, k] = br.ReadSingle();
                    }
                }

                boneTree[i] = br.ReadUInt32();

                var bone = new SEModelBone
                {
                    BoneName       = boneName.Replace('.', '_').Replace('-', '_').Replace(' ', '_'),
                    GlobalRotation = new Quaternion(transformMatrix),
                    GlobalPosition = new Vector3(transformMatrix)
                };

                if (bFlip)
                {
                    bone.GlobalPosition.X *= -1;

                    bone.GlobalRotation.Y *= -1;
                    bone.GlobalRotation.Z *= -1;
                }

                // rotate root bone;
                if (boneId == 0)
                {
                    bone.GlobalRotation *= globalRotation;
                }

                ltbFile.Bones[boneId] = bone;
            }

            uint[] nSubbone = new uint[numBones];
            nSubbone[0] = boneTree[0];

            ltbFile.Bones[0].BoneParent = -1;

            // Build bone tree
            for (byte i = 1; i < numBones; i++)
            {
                nSubbone[i] = boneTree[i];
                for (int j = i - 1; j >= 0; j--)
                {
                    if (nSubbone[j] > 0)
                    {
                        nSubbone[j]--;
                        ltbFile.Bones[i].BoneParent = j;
                        break;
                    }
                }
            }

            #endregion

            #region Random stuff
            Console.WriteLine("\nInternal filenames:");
            var childModelCount = br.ReadUInt32();

            for (int i = 0; i < childModelCount; i++)
            {
                Console.WriteLine(br.ReadStringWithUInt16Length());

                br.Skip((int)br.ReadUInt32() * 4);
            }

            br.Skip(4);
            #endregion

            #region Animations
            if (nAnim > 0)
            {
                var animationCount = br.ReadUInt32();

                Console.WriteLine($"\nAnimation count: {animationCount}\n");

                for (int i = 0; i < animationCount; i++)
                {
                    var seanim = new SEAnim();

                    var dim = new Vector3
                    {
                        X = br.ReadSingle(),
                        Y = br.ReadSingle(),
                        Z = br.ReadSingle(),
                    };

                    var animName = br.ReadStringWithUInt16Length();
                    Console.Write(animName);

                    var compressionType = (AnimCompressionType)br.ReadUInt32();
                    var interpolationMS = br.ReadUInt32();

                    var keyFrameCount = br.ReadUInt32();
                    Console.WriteLine($" has {keyFrameCount} keyframes");

                    for (int iKeyFrame = 0; iKeyFrame < keyFrameCount; iKeyFrame++)
                    {
                        var time       = br.ReadUInt32();
                        var animString = br.ReadStringWithUInt16Length();

                        if (!string.IsNullOrEmpty(animString))
                        {
                            seanim.AddNoteTrack(animString, iKeyFrame);
                        }
                    }

                    for (byte iBone = 0; iBone < numBones; iBone++)
                    {
                        if (compressionType != AnimCompressionType.None)
                        {
                            uint pFrames = br.ReadUInt32();

                            for (int iKeyFrame = 0; iKeyFrame < pFrames; iKeyFrame++)
                            {
                                var v = new Vector3(br.ReadInt16() / 16.0, br.ReadInt16() / 16.0, br.ReadInt16() / 16.0);

                                if (bFlip)
                                {
                                    v.X *= -1;
                                }

                                seanim.AddTranslationKey(ltbFile.Bones[iBone].BoneName, iKeyFrame, v.X, v.Y, v.Z);
                            }

                            uint rFrames = br.ReadUInt32();

                            for (int iKeyFrame = 0; iKeyFrame < rFrames; iKeyFrame++)
                            {
                                var q = new Quaternion(br.ReadInt16() / 16.0, -br.ReadInt16() / 16.0, -br.ReadInt16() / 16.0, br.ReadInt16() / 16.0);

                                if (bFlip)
                                {
                                    q.Y *= -1;
                                    q.Z *= -1;
                                }

                                // rotate root bone;
                                if (iBone == 0)
                                {
                                    q *= globalRotation;
                                }

                                seanim.AddRotationKey(ltbFile.Bones[iBone].BoneName, iKeyFrame, q.X, q.Y, q.Z, q.W);
                            }
                        }
                        else if (compressionType == AnimCompressionType.None)
                        {
                            bool isVertexAnim = br.ReadBoolean();

                            if (isVertexAnim)
                            {
                                throw new Exception("Vertex animation not supported!");
                            }
                            else
                            {
                                for (int iKeyFrame = 0; iKeyFrame < keyFrameCount; iKeyFrame++)
                                {
                                    var v = new Vector3(-br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                                    seanim.AddTranslationKey(ltbFile.Bones[iBone].BoneName, iKeyFrame, v.X, v.Y, v.Z);
                                }

                                for (int iKeyFrame = 0; iKeyFrame < keyFrameCount; iKeyFrame++)
                                {
                                    var q = new Quaternion(br.ReadSingle(), -br.ReadSingle(), -br.ReadSingle(), br.ReadSingle());

                                    // rotate root bone;
                                    if (iBone == 0)
                                    {
                                        q *= globalRotation;
                                    }

                                    seanim.AddRotationKey(ltbFile.Bones[iBone].BoneName, iKeyFrame, q.X, q.Y, q.Z, q.W);
                                }
                            }
                        }
                    }

                    ltbFile.Animations.Add(animName + ".seanim", seanim);
                }
            }

            #endregion

            return(ltbFile);
        }
Exemple #10
0
        public bool PatchBsa(CompressionOptions bsaOptions, string oldBSA, string newBSA, bool simulate = false)
        {
            var Op = new InstallStatus(Progress, Token) { ItemsTotal = 7 };

            var outBsaFilename = Path.GetFileNameWithoutExtension(newBSA);

            BSA bsa;
            try
            {
                Op.CurrentOperation = "Opening " + Path.GetFileName(oldBSA);

                bsa = new BSA(oldBSA, bsaOptions);
            }
            finally
            {
                Op.Step();
            }

            IDictionary<string, string> renameDict;
            try
            {
                Op.CurrentOperation = "Opening rename database";

#if LEGACY
                var renamePath = Path.Combine(Installer.PatchDir, outBsaFilename, "RenameFiles.dict");
#else
                var renamePath = Path.Combine(Installer.PatchDir, Path.ChangeExtension(outBsaFilename, ".ren"));
#endif
                if (File.Exists(renamePath))
                {
#if LEGACY
                    renameDict = new Dictionary<string, string>(Util.ReadOldDatabase(renamePath));
#else
                    using (var fileStream = File.OpenRead(renamePath))
                    using (var lzmaStream = new LzmaDecodeStream(fileStream))
                    using (var reader = new BinaryReader(lzmaStream))
                    {
                        var numPairs = reader.ReadInt32();
                        renameDict = new Dictionary<string, string>(numPairs);

                        while (numPairs-- > 0)
                            renameDict.Add(reader.ReadString(), reader.ReadString());
                    }
#endif
                }
                else
                    renameDict = new Dictionary<string, string>();
            }
            finally
            {
                Op.Step();
            }

            PatchDict patchDict;
            try
            {
                Op.CurrentOperation = "Opening patch database";

#if LEGACY
                var chkPrefix = Path.Combine(Installer.PatchDir, outBsaFilename);
                var chkPath = Path.Combine(chkPrefix, "CheckSums.dict");
                patchDict = PatchDict.FromOldDatabase(Util.ReadOldDatabase(chkPath), chkPrefix, b => b);
#else
                var patchPath = Path.Combine(Installer.PatchDir, Path.ChangeExtension(outBsaFilename, ".pat"));
                if (File.Exists(patchPath))
                {
                    patchDict = new PatchDict(patchPath);
                }
                else
                {
                    Log.Dual("\tNo patch database is available for: " + oldBSA);
                    return false;
                }
#endif
            }
            finally
            {
                Op.Step();
            }

            using (bsa)
            {
                try
                {
                    RenameFiles(bsa, renameDict);

                    if (renameDict.Count > 0)
                    {
                        foreach (var kvp in renameDict)
                        {
                            Log.Dual("File not found: " + kvp.Value);
                            Log.Dual("\tCannot create: " + kvp.Key);
                        }
                    }
                }
                finally
                {
                    Op.Step();
                }

                var allFiles = bsa.SelectMany(folder => folder).ToList();
                try
                {
                    var opChk = new InstallStatus(Progress, Token) { ItemsTotal = patchDict.Count };

                    var joinedPatches = from patKvp in patchDict
                                        //if the join is not grouped, this will exclude missing files, and we can't find and fail on them
                                        join oldFile in allFiles on patKvp.Key equals oldFile.Filename into foundOld
                                        join bsaFile in allFiles on patKvp.Key equals bsaFile.Filename
                                        select new PatchJoin(bsaFile, foundOld.SingleOrDefault(), patKvp.Value);

#if DEBUG
                    var watch = new Stopwatch();
                    try
                    {
                        watch.Start();
#endif
#if PARALLEL
                        Parallel.ForEach(joinedPatches, join =>
#else
                        foreach (var join in joinedPatches)
#endif
 HandleFile(opChk, join)
#if PARALLEL
)
#endif
;
#if DEBUG
                    }
                    finally
                    {
                        watch.Stop();
                        Debug.WriteLine(outBsaFilename + " HandleFile loop finished in " + watch.Elapsed);
                    }
#endif
                }
                finally
                {
                    Op.Step();
                }

                try
                {
                    Op.CurrentOperation = "Removing unnecessary files";

                    var notIncluded = allFiles.Where(file => !patchDict.ContainsKey(file.Filename));
                    var filesToRemove = new HashSet<BSAFile>(notIncluded);

                    foreach (BSAFolder folder in bsa)
                        folder.RemoveWhere(filesToRemove.Contains);

                    var emptyFolders = bsa.Where(folder => folder.Count == 0).ToList();
                    emptyFolders.ForEach(folder => bsa.Remove(folder));
                }
                finally
                {
                    Op.Step();
                }

                try
                {
                    Op.CurrentOperation = "Saving " + Path.GetFileName(newBSA);

                    if (!simulate)
                        bsa.Save(newBSA.ToLowerInvariant());
                }
                finally
                {
                    Op.Step();
                }
            }

            Op.Finish();

            return true;
        }
Exemple #11
0
        public async Task LoadFromStream(Stream stream, bool lzma = false)
        {
            var br = new ExtendedBinaryReader(stream);

            // DTX Header

            iResType = br.ReadUInt32();

            iVersion = br.ReadInt32();

            width  = br.ReadUInt16();
            height = br.ReadUInt16();

            nMipmap  = br.ReadUInt16();
            nSection = br.ReadUInt16();

            flags     = br.ReadInt32();
            userFlags = br.ReadInt32();

            extra = br.ReadBytes(12);

            cmdStr = br.ReadBytes(128);

            if (iResType != 0 || iVersion != -5 || nMipmap == 0)
            {
                if (lzma)
                {
                    throw new Exception("Unsupported DTX Type");
                }
                else
                {
                    stream.Position = 0;

                    var lzmaStream = new LzmaDecodeStream(stream);
                    var ms         = new MemoryStream();

                    lzmaStream.CopyTo(ms);

                    await LoadFromStream(ms, true);

                    return;
                }
            }

            DXTDecoder decoder = null;

            if (storeType == 4)
            {
                decoder = new DXT1Decoder();
            }
            else if (storeType == 5)
            {
                decoder = new DXT3Decoder();
            }
            else if (storeType == 6)
            {
                decoder = new DXT5Decoder();
            }

            if (decoder != null)
            {
                rawBuffer = await decoder.DecodeFrame(stream, width, height);
            }
            else
            {
                rawBuffer = br.ReadBytes(width * height * 4);
            }

            br.Close();
        }