/// <summary> /// Opens the PKX extension and reads the file table entries. /// </summary> /// <param name="fs">FileStream</param> /// <param name="br">BinaryReader</param> /// <param name="algoId">AlgorithmId</param> private void OpenPkx(FileStream fs, BinaryReader br, uint algoId) { // *****NOTE TO SELF****** // This CAN be cleaned up! using (FileStream f = new FileStream(PkxName, FileMode.Open)) { using (BinaryReader b = new BinaryReader(f)) { if (IsVersion23) { f.Seek(-16, SeekOrigin.End); _header23.GuardByte1 = b.ReadUInt32(); f.Seek(-(Marshal.SizeOf(typeof(FileHeaderV23)) + 8), SeekOrigin.End); _header23.GuardByte0 = b.ReadUInt32(); _header23.Version = b.ReadInt32(); } else { f.Seek(-12, SeekOrigin.End); _header22.GuardByte1 = b.ReadUInt32(); f.Seek(-(Marshal.SizeOf(typeof(FileHeaderV22)) + 8), SeekOrigin.End); _header22.GuardByte0 = b.ReadUInt32(); _header22.Version = b.ReadInt32(); } AlgorithmId id = new AlgorithmId(AutoDetect()); uint offset = b.ReadUInt32() ^ id.PckMaskDword; if (offset <= TwoGb) { if (IsVersion23) { fs.Seek(-16, SeekOrigin.End); _header23.GuardByte1 = br.ReadUInt64() >> 0x20; fs.Seek(-(Marshal.SizeOf(typeof(FileHeaderV23)) + 8), SeekOrigin.End); _header23.GuardByte0 = br.ReadUInt32(); _header23.Version = br.ReadInt32(); } else { fs.Seek(-12, SeekOrigin.End); _header22.GuardByte1 = br.ReadUInt32(); fs.Seek(-(Marshal.SizeOf(typeof(FileHeaderV22)) + 8), SeekOrigin.End); _header22.GuardByte0 = br.ReadUInt32(); _header22.Version = br.ReadInt32(); } id = new AlgorithmId(AutoDetect()); uint code = br.ReadUInt32() ^ id.PckMaskDword; fs.Seek(code, SeekOrigin.Begin); } else { long pos = Convert.ToInt64(offset) - TwoGb; f.Seek(pos, SeekOrigin.Begin); offset -= TwoGb; } FileTable = new TableEntry[EntryCount]; for (int i = 0; i < EntryCount; i++) { uint size = b.ReadUInt32() ^ id.PckMaskDword; size = b.ReadUInt32() ^ id.PckMaskDword ^ id.PckCheckMask; byte[] buffer = b.ReadBytes((int)size); FileTable[i] = new TableEntry(); int flags = size < 0x114 ? 1 : 0; FileTable[i] = FileTable[i].ReadTableEntry(buffer, (int)offset, Version, flags != 0); FileTable[i].FilePath = FileTable[i].FilePath.Replace("/", "\\"); } // Sort array by data offset. FileTable = FileTable.OrderBy(x => x.DataOffset).ToArray(); } } }
// Open Methods #region Open Methods /// <summary> /// Open PCK less than 0x7FFFFF00 in size. /// </summary> /// <param name="fs">FileStream</param> /// <param name="br">BinaryReader</param> /// <param name="algoId">AlgorithmId</param> /// <returns>Returns -1 on error.</returns> private int OpenPck(FileStream fs, BinaryReader br, uint algoId) { if (IsSwordsman) { IsPck = true; IsPkx = false; } else { switch (Version) { case 0x20002: IsPck = true; IsPkx = false; fs.Seek(-12, SeekOrigin.End); _header22.GuardByte1 = br.ReadUInt32(); fs.Seek(-(Marshal.SizeOf(typeof(FileHeaderV22)) + 8), SeekOrigin.End); _header22.GuardByte0 = br.ReadUInt32(); _header22.Version = br.ReadInt32(); break; case 0x20003: IsPck = true; IsPkx = false; fs.Seek(-16, SeekOrigin.End); _header23.GuardByte1 = (uint)(br.ReadUInt64() >> 0x20); fs.Seek(-(Marshal.SizeOf(typeof(FileHeaderV23)) + 8), SeekOrigin.End); _header23.GuardByte0 = br.ReadUInt32(); _header23.Version = br.ReadInt32(); break; default: IsPck = false; IsPkx = false; return(-1); } } AlgorithmId id = IsSwordsman ? new AlgorithmId(161) : new AlgorithmId(AutoDetect()); if (IsSwordsman) { GameName = IdToGameName(161); } ulong offset; if (IsSwordsman) { ulong tmp = _header23s.TableOffset; offset = tmp ^ 0x49AB7F1D33C3EDDB; } else { offset = br.ReadUInt32() ^ id.PckMaskDword; } if (IsVersion23) { _header23.TableOffset = (uint)offset; } else { _header22.TableOffset = (uint)offset; } fs.Seek((long)offset, SeekOrigin.Begin); FileTable = new TableEntry[EntryCount]; for (int i = 0; i < EntryCount; i++) { uint size = br.ReadUInt32() ^ id.PckMaskDword; size = br.ReadUInt32() ^ id.PckMaskDword ^ id.PckCheckMask; byte[] buffer = br.ReadBytes((int)size); FileTable[i] = new TableEntry(); int flags = size < 0x114 ? 1 : 0; FileTable[i] = FileTable[i].ReadTableEntry(buffer, (int)offset, Version, flags != 0); FileTable[i].FilePath = FileTable[i].FilePath.Replace("/", "\\"); } return(0); }