示例#1
0
        /// <summary>
        /// Update Checksum
        /// </summary>
        /// <returns>Current Checksum</returns>
        public uint UpdateChecksum()
        {
            var checkBuffer = BitConverter.GetBytes(HeaderLength)
                              .Concat(BitConverter.GetBytes(OffsetNames))
                              .Concat(BitConverter.GetBytes(OffsetStrings))
                              .Concat(BitConverter.GetBytes(OffsetStringsData))
                              .Concat(BitConverter.GetBytes(OffsetChunkOffsets))
                              .Concat(BitConverter.GetBytes(OffsetChunkLengths))
                              .Concat(BitConverter.GetBytes(OffsetChunkData))
                              .Concat(BitConverter.GetBytes(OffsetEntries))
                              .ToArray();
            Adler32 adler32 = new Adler32();

            adler32.Update(checkBuffer);
            if (Version < 4)
            {
                Checksum = (uint)adler32.Checksum;
                return(Checksum);
            }
            checkBuffer = BitConverter.GetBytes(OffsetExtraChunkOffsets)
                          .Concat(BitConverter.GetBytes(OffsetExtraChunkLengths))
                          .Concat(BitConverter.GetBytes(OffsetExtraChunkData))
                          .ToArray();
            adler32.Update(checkBuffer);
            Checksum = (uint)adler32.Checksum;
            return(Checksum);
        }
示例#2
0
        /// <summary>
        /// Assume header is encrypted
        /// </summary>
        /// <param name="br"></param>
        /// <param name="bw"></param>
        /// <param name="context"></param>
        private static void WriteDecryptPartialHeader(BinaryReader br, BinaryWriter bw, PsbStreamContext context, PsbHeader header)
        {
            header.HeaderLength       = context.ReadUInt32(br);
            header.OffsetNames        = context.ReadUInt32(br);
            header.OffsetStrings      = context.ReadUInt32(br);
            header.OffsetStringsData  = context.ReadUInt32(br);
            header.OffsetChunkOffsets = context.ReadUInt32(br);
            header.OffsetChunkLengths = context.ReadUInt32(br);
            header.OffsetChunkData    = context.ReadUInt32(br);
            header.OffsetEntries      = context.ReadUInt32(br);
            if (header.Version > 2)
            {
                header.Checksum = context.ReadUInt32(br);
            }
            if (header.Version > 3)
            {
                header.OffsetUnknown1        = context.ReadUInt32(br);
                header.OffsetUnknown2        = context.ReadUInt32(br);
                header.OffsetResourceOffsets = context.ReadUInt32(br);
            }

            //var checksumStartPosition = bw.BaseStream.Position;
            bw.Write(header.HeaderLength);
            bw.Write(header.OffsetNames);
            bw.Write(header.OffsetStrings);
            bw.Write(header.OffsetStringsData);
            bw.Write(header.OffsetChunkOffsets);
            bw.Write(header.OffsetChunkLengths);
            bw.Write(header.OffsetChunkData);
            bw.Write(header.OffsetEntries);
            //var checksumPosition = bw.BaseStream.Position;

            if (header.Version > 2)
            {
                int checkLength = 32;
                bw.BaseStream.Seek(-checkLength, SeekOrigin.Current);
                var checkBuffer = new byte[checkLength];
                bw.BaseStream.Read(checkBuffer, 0, checkLength);
                Adler32 adler32 = new Adler32();
                adler32.Update(checkBuffer);
                header.Checksum = (uint)adler32.Checksum;
                if (header.Version == 3)
                {
                    bw.Write(header.Checksum);
                }
                else //PSBv4
                {
                    checkBuffer = BitConverter.GetBytes(header.OffsetUnknown1)
                                  .Concat(BitConverter.GetBytes(header.OffsetUnknown2))
                                  .Concat(BitConverter.GetBytes(header.OffsetResourceOffsets)).ToArray();
                    adler32.Update(checkBuffer);
                    header.Checksum = (uint)adler32.Checksum;
                    bw.Write(header.Checksum);
                    bw.Write(header.OffsetUnknown1);
                    bw.Write(header.OffsetUnknown2);
                    bw.Write(header.OffsetResourceOffsets);
                }
            }
        }
示例#3
0
        public static void CompressToMdfFile(this PsbFile psbFile, string outputPath = null, bool fast = true)
        {
            var     bytes      = File.ReadAllBytes(psbFile.Path);
            Adler32 checksumer = new Adler32();

            checksumer.Update(bytes);
            var checksum = (uint)checksumer.Checksum;

            checksumer = null;
            MemoryStream ms = new MemoryStream(bytes);

            using (FileStream fs = new FileStream(outputPath ?? psbFile.Path + ".mdf", FileMode.Create))
            {
                BinaryWriter bw = new BinaryWriter(fs);
                bw.WriteStringZeroTrim(Signature);
                bw.Write((uint)ms.Length);
                bw.Write(ZlibCompress.Compress(ms, fast));
                bw.WriteBE(checksum);
                ms.Dispose();
                bw.Flush();
            }
        }
示例#4
0
        public static Stream CompressPsbToMdfStream(Stream input, bool fast = true)
        {
            var     pos        = input.Position;
            Adler32 checksumer = new Adler32();

            checksumer.Update(input);
            var checksum = (uint)checksumer.Checksum;

            checksumer     = null;
            input.Position = pos;
            MemoryStream ms = new MemoryStream();
            BinaryWriter bw = new BinaryWriter(ms, Encoding.UTF8, true);

            bw.WriteStringZeroTrim(Signature);
            bw.Write((uint)input.Length);
            bw.Write(ZlibCompress.Compress(input, fast));
            bw.WriteBE(checksum);
            bw.Flush();
            bw.Dispose();
            ms.Seek(0, SeekOrigin.Begin);
            return(ms);
        }
示例#5
0
        /// <summary>
        /// Assume header is clean
        /// </summary>
        /// <param name="br"></param>
        /// <param name="bw"></param>
        /// <param name="context"></param>
        /// <param name="header"></param>
        private static void WriteEncryptPartialHeader(BinaryReader br, BinaryWriter bw, PsbStreamContext context,
                                                      PsbHeader header)
        {
            var checksumStartPosition = br.BaseStream.Position;

            header.HeaderLength = br.ReadUInt32();
            header.OffsetNames  = br.ReadUInt32();
            if (header.HeaderLength == 0)
            {
                header.HeaderLength = header.OffsetNames;
            }

            header.OffsetStrings      = br.ReadUInt32();
            header.OffsetStringsData  = br.ReadUInt32();
            header.OffsetChunkOffsets = br.ReadUInt32();
            header.OffsetChunkLengths = br.ReadUInt32();
            header.OffsetChunkData    = br.ReadUInt32();
            header.OffsetEntries      = br.ReadUInt32();
            if (header.Version > 2)
            {
                header.Checksum = br.ReadUInt32();
            }

            if (header.Version > 3)
            {
                header.OffsetUnknownOffsets = br.ReadUInt32();
                header.OffsetUnknownLengths = br.ReadUInt32();
                header.OffsetUnknownData    = br.ReadUInt32();
            }

            var checksumEndPosition = br.BaseStream.Position;

            context.Write(header.HeaderLength, bw);
            context.Write(header.OffsetNames, bw);
            context.Write(header.OffsetStrings, bw);
            context.Write(header.OffsetStringsData, bw);
            context.Write(header.OffsetChunkOffsets, bw);
            context.Write(header.OffsetChunkLengths, bw);
            context.Write(header.OffsetChunkData, bw);
            context.Write(header.OffsetEntries, bw);

            if (header.Version > 2)
            {
                int checkLength = 32;
                br.BaseStream.Seek(checksumStartPosition, SeekOrigin.Begin);
                var checkBuffer = new byte[checkLength];
                br.BaseStream.Read(checkBuffer, 0, checkLength);
                br.BaseStream.Seek(checksumEndPosition, SeekOrigin.Begin); //Jump back
                Adler32 adler32 = new Adler32();
                adler32.Update(checkBuffer);
                header.Checksum = (uint)adler32.Checksum;
                if (header.Version == 3)
                {
                    context.Write(header.Checksum, bw);
                }
                else //PSBv4
                {
                    checkBuffer = BitConverter.GetBytes(header.OffsetUnknownOffsets)
                                  .Concat(BitConverter.GetBytes(header.OffsetUnknownLengths))
                                  .Concat(BitConverter.GetBytes(header.OffsetUnknownData)).ToArray();
                    adler32.Update(checkBuffer);
                    header.Checksum = (uint)adler32.Checksum;
                    context.Write(header.Checksum, bw);
                    context.Write(header.OffsetUnknownOffsets, bw);
                    context.Write(header.OffsetUnknownLengths, bw);
                    context.Write(header.OffsetUnknownData, bw);
                }
            }
        }