/// <summary> /// Returns this instance of PK2Entry as byte[] which can be used to be written back to the PK2 archive /// </summary> /// <returns></returns> public byte[] ToByteArray() { var result = new byte[128]; using (var stream = new StreamWorker(result, StreamOperation.Write)) { stream.WriteByte(Type); stream.WriteString(Name); stream.WriteByteArray(new byte[81 - Name.Length]); //Write the name padding stream.WriteLong(AccessTime.Ticks); stream.WriteLong(CreateTime.Ticks); stream.WriteLong(ModifyTime.Ticks); stream.WriteULong(Position); stream.WriteUInt(Size); stream.WriteULong(NextChain); stream.WriteByteArray(new byte[2]); //Padding to reach 128 bytes length } //If we have an encypted archive we have to encrypt this, too if (BlowfishUtilities.GetBlowfish() != null) { result = BlowfishUtilities.GetBlowfish().Encode(result); } return(result); }
/// <summary> /// Initializes a new instance of the <see cref="PK2Block" /> class. /// </summary> /// <param name="buffer">The buffer.</param> /// <param name="offset">The block offset.</param> public PK2Block(byte[] buffer, ulong offset) { Entries = new PK2Entry[20]; Offset = offset; using (var streamWorker = new StreamWorker(buffer, StreamOperation.Read)) { for (var i = 0; i < 20; i++) { var entryBuffer = streamWorker.ReadByteArray(128); if (BlowfishUtilities.GetBlowfish() != null) { entryBuffer = BlowfishUtilities.GetBlowfish().Decode(entryBuffer); } Entries[i] = new PK2Entry(entryBuffer, this, (byte)i); } } }
/// <summary> /// Initializes a new instance of the <see cref="PK2Archive"/> class. /// The key is set to the isro standard encryption key. /// Do not provide any baseKey, if you wish to use the default base key for the archive. /// </summary> /// <exception cref="System.IO.FileNotFoundException"></exception> /// <exception cref="SlimPK2.Security.BlowfishSecurityException"></exception> /// <exception cref="SlimPK2.Types.InvalidHeaderException"></exception> public PK2Archive(string path, PK2Config config = null) { if (!File.Exists(path)) { throw new FileNotFoundException(path); } //Initialize default config if (config == null) { config = PK2Config.GetDefault(); } //assign the config to this instance Config = config; //Create file reader... FileAdapter.SetInstance(new FileAdapter(path)); Path = path; //Read header... Header = new PK2Header(FileAdapter.GetInstance().ReadData(0, 256)); if (Header.Encrypted) { var blowfishKey = BlowfishUtilities.GenerateFinalBlowfishKey(Config.Key, Config.BaseKey); var blowfish = new Blowfish(); blowfish.Initialize(blowfishKey); BlowfishUtilities.SetBlowfish(blowfish); var tempChecksum = BlowfishUtilities.GetBlowfish().Encode(Encoding.ASCII.GetBytes("Joymax Pak File")); //Check if the security checksum equals the generated checksum if (tempChecksum[0] != Header.SecurityChecksum[0] || tempChecksum[1] != Header.SecurityChecksum[1] || tempChecksum[2] != Header.SecurityChecksum[2]) { throw new BlowfishSecurityException(Config.Key); } } if (Config.Mode != PK2Mode.FreeBrowse) { switch (Config.Mode) { case PK2Mode.IndexBlocks: Blocks = new List <PK2Block>(); ReadBlockAt(256); break; case PK2Mode.Index: _files = new List <PK2File>(); _directories = new List <PK2Directory>(); ReadBlockAt(256, new PK2Directory()); break; } } else { _navigator = new PK2Navigator(); } Loaded = true; }