예제 #1
0
        // same as ResourceBuilder.Build but with support NG encrypting after compressing
        private static byte[] Build(ResourceFileBase fileBase, int version, string name, bool compress = true, bool encrypt = true)
        {
            fileBase.FilePagesInfo = new ResourcePagesInfo();

            IList <IResourceBlock> systemBlocks;
            IList <IResourceBlock> graphicBlocks;

            ResourceBuilder.GetBlocks(fileBase, out systemBlocks, out graphicBlocks);

            RpfResourcePageFlags systemPageFlags;

            ResourceBuilder.AssignPositions(systemBlocks, 0x50000000, out systemPageFlags);

            RpfResourcePageFlags graphicsPageFlags;

            ResourceBuilder.AssignPositions(graphicBlocks, 0x60000000, out graphicsPageFlags);


            fileBase.FilePagesInfo.SystemPagesCount   = (byte)systemPageFlags.Count;
            fileBase.FilePagesInfo.GraphicsPagesCount = (byte)graphicsPageFlags.Count;


            var systemStream   = new MemoryStream();
            var graphicsStream = new MemoryStream();
            var resourceWriter = new ResourceDataWriter(systemStream, graphicsStream);

            resourceWriter.Position = 0x50000000;
            foreach (var block in systemBlocks)
            {
                resourceWriter.Position = block.FilePosition;

                var pos_before = resourceWriter.Position;
                block.Write(resourceWriter);
                var pos_after = resourceWriter.Position;

                if ((pos_after - pos_before) != block.BlockLength)
                {
                    throw new Exception("error in system length");
                }
            }

            resourceWriter.Position = 0x60000000;
            foreach (var block in graphicBlocks)
            {
                resourceWriter.Position = block.FilePosition;

                var pos_before = resourceWriter.Position;
                block.Write(resourceWriter);
                var pos_after = resourceWriter.Position;

                if ((pos_after - pos_before) != block.BlockLength)
                {
                    throw new Exception("error in graphics length");
                }
            }



            var sysDataSize = (int)systemPageFlags.Size;
            var sysData     = new byte[sysDataSize];

            systemStream.Flush();
            systemStream.Position = 0;
            systemStream.Read(sysData, 0, (int)systemStream.Length);


            var gfxDataSize = (int)graphicsPageFlags.Size;
            var gfxData     = new byte[gfxDataSize];

            graphicsStream.Flush();
            graphicsStream.Position = 0;
            graphicsStream.Read(gfxData, 0, (int)graphicsStream.Length);



            uint uv = (uint)version;
            uint sv = (uv >> 4) & 0xF;
            uint gv = (uv >> 0) & 0xF;
            uint sf = systemPageFlags.Value + (sv << 28);
            uint gf = graphicsPageFlags.Value + (gv << 28);


            var tdatasize = sysDataSize + gfxDataSize;
            var tdata     = new byte[tdatasize];

            Buffer.BlockCopy(sysData, 0, tdata, 0, sysDataSize);
            Buffer.BlockCopy(gfxData, 0, tdata, sysDataSize, gfxDataSize);


            var cdata = compress ? ResourceBuilder.Compress(tdata) : tdata;

            cdata = encrypt ? GTACrypto.EncryptNG(cdata, name, (uint)cdata.Length + 0x10) : cdata;

            var dataSize = 16 + cdata.Length;
            var data     = new byte[dataSize];

            byte[] h1 = BitConverter.GetBytes((uint)0x37435352);
            byte[] h2 = BitConverter.GetBytes((int)version);
            byte[] h3 = BitConverter.GetBytes(sf);
            byte[] h4 = BitConverter.GetBytes(gf);
            Buffer.BlockCopy(h1, 0, data, 0, 4);
            Buffer.BlockCopy(h2, 0, data, 4, 4);
            Buffer.BlockCopy(h3, 0, data, 8, 4);
            Buffer.BlockCopy(h4, 0, data, 12, 4);
            Buffer.BlockCopy(cdata, 0, data, 16, cdata.Length);

            return(data);
        }