fileTableEntry readTableEntry(byte[] data, int size, bool compressed) { fileTableEntry fte = new fileTableEntry(); MemoryStream ms = new MemoryStream(data,0,data.Length); byte[] filePath = new byte[260]; if(compressed) { Stream s2 = new ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream(ms); byte[] dataDec = new byte[276]; s2.Read(dataDec,0,276); ms = new MemoryStream(dataDec,0,dataDec.Length); //ms = mms; /* wxByte* pBuffer = buffer; buffer = deflate(buffer, size, 276); wxDELETEA(pBuffer); */ } ms.Read(filePath, 0, 260); byte[] fileDataOffset = new byte[4]; byte[] fileDataDecompressedSize = new byte[4]; byte[] fileDataCompressedSize = new byte[4]; ms.Read(fileDataOffset, 0, 4); ms.Read(fileDataDecompressedSize, 0, 4); ms.Read(fileDataCompressedSize, 0, 4); //wxMemoryInputStream mis(buffer, 276); //wxDataInputStream bis(mis); //ms.Read(fte.filePath, 260); //fte.filePath = BitConverter.ToString(filePath, 0, 260); int length = 0; for (int i = 0; i < 260; i++) { if ( filePath[i] == (byte)0 ){ length = i; break; } } byte[] filePathOk = new byte[length]; Array.Copy(filePath, filePathOk, length); //fte.filePath = Encoding.UTF8.GetString(filePathOk); fte.filePath = Encoding.GetEncoding(936).GetString(filePathOk); fte.fileDataOffset = BitConverter.ToInt32(fileDataOffset, 0); fte.fileDataDecompressedSize = BitConverter.ToInt32(fileDataDecompressedSize, 0); fte.fileDataCompressedSize = BitConverter.ToInt32(fileDataCompressedSize, 0); //if ( fte.fileDataDecompressedSize < fte.fileDataCompressedSize) //textBox1.Text += "\r\n__"+fte.fileDataDecompressedSize.ToString()+" -- "+fte.filePath+" -- "; return fte; }
void ExtractPck() { //openFileDialog1.ShowDialog(); string pckFile = textBox2.Text; //folderBrowserDialog1.ShowDialog(); string pckFolder = textBox3.Text + "\\"; FileStream fs = File.OpenRead(pckFile); BinaryReader br = new BinaryReader(fs); fs.Seek(-8,SeekOrigin.End); int entryCount = br.ReadInt32(); fs.Seek(-272,SeekOrigin.End); int fileTableOffset = br.ReadInt32() ^ KEY_1; fs.Seek(fileTableOffset,SeekOrigin.Begin); UpdateLeftText("Reading files..."); int entrySize; fileTableEntry[] fileTable = new fileTableEntry[entryCount]; int t = 0; for (int i = 0; i < entryCount; i++) { entrySize = br.ReadInt32() ^ KEY_1; entrySize = br.ReadInt32() ^ KEY_2; byte[] data = br.ReadBytes(entrySize); // textBox1.Text += entrySize.ToString()+"\r\n"; if(entrySize < 276) { fileTable[i] = readTableEntry(data, entrySize, true); t++; } // no zlib else { fileTable[i] = readTableEntry(data, entrySize, false); } ShowProgress(entryCount, i+1); } //UpdateLeftText("Extracting files..."); //textBox1.Text += fileTable[0].filePath+"\r\n"+fileTableOffset.ToString()+"\r\n"+t.ToString(); for (int i = 0; i < entryCount; i++) { string path = Path.GetDirectoryName(pckFolder+fileTable[i].filePath); if ( !Directory.Exists(path) ) Directory.CreateDirectory(path); BinaryWriter bw = new BinaryWriter(File.Create(pckFolder+fileTable[i].filePath)); fs.Seek(fileTable[i].fileDataOffset,SeekOrigin.Begin); byte[] data = br.ReadBytes(fileTable[i].fileDataCompressedSize); if(fileTable[i].fileDataCompressedSize < fileTable[i].fileDataDecompressedSize) { MemoryStream ms = new MemoryStream(data,0,data.Length); Stream s2 = new ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream(ms); byte[] dataDec = new byte[fileTable[i].fileDataDecompressedSize]; s2.Read(dataDec,0,fileTable[i].fileDataDecompressedSize); data = dataDec; } bw.Write(data); bw.Close(); ShowProgress(entryCount, i+1); //UpdateRightText((i+1).ToString() + "/" + entryCount.ToString()); } //UpdateLeftText(entryCount.ToString()+" file(s) extracted"); label4.Text = entryCount.ToString()+" file(s) extracted"; br.Close(); fs.Close(); }
void PatchPck() { string mainPath = textBox3.Text+"\\"; string[] files = Directory.GetFiles(mainPath, "*.*", SearchOption.AllDirectories); for (int i = 0; i < files.Length; i++) { files[i] = files[i].Substring(mainPath.Length); textBox1.Text += files[i]+"\r\n"; } FileStream fs = new FileStream(textBox2.Text, FileMode.OpenOrCreate, FileAccess.ReadWrite); BinaryWriter bw = new BinaryWriter(fs); BinaryReader br = new BinaryReader(fs); fs.Seek(-8,SeekOrigin.End); int entryCount = br.ReadInt32(); fs.Seek(-272,SeekOrigin.End); int fileTableOffset = br.ReadInt32() ^ KEY_1; fs.Seek(fileTableOffset,SeekOrigin.Begin); int entrySize; fileTableEntry[] fileTable = new fileTableEntry[entryCount]; bool[] toEdit = new bool[entryCount]; int t = 0; int editedFiles = 0; for (int i = 0; i < entryCount; i++) { entrySize = br.ReadInt32() ^ KEY_1; entrySize = br.ReadInt32() ^ KEY_2; byte[] data = br.ReadBytes(entrySize); // if(entrySize < 276) { fileTable[i] = readTableEntry(data, entrySize, true); t++; } // no zlib else { fileTable[i] = readTableEntry(data, entrySize, false); } if ( Array.IndexOf(files, fileTable[i].filePath) >= 0 ){ toEdit[i] = true; editedFiles++; } else { toEdit[i] = false; } } textBox1.Text += entryCount.ToString()+"\r\n"; fs.Seek(fileTableOffset,SeekOrigin.Begin); // useless ?? int lastEntryPosition = fileTableOffset; int filesCount = (int)files.Length; for (int i = 0; i < entryCount; i++) { if ( toEdit[i] == false ) continue; //fileTable[i].filePath = files[i].Substring(6); //fileTable[i].fileDataOffset = (int)BinaryFile.Position; FileStream tfs = File.OpenRead(mainPath+fileTable[i].filePath); BinaryReader tbr = new BinaryReader(tfs); int newFileDataDecompressedSize = (int)tfs.Length; byte[] data = tbr.ReadBytes(newFileDataDecompressedSize); tbr.Close(); tfs.Close(); MemoryStream ms = new MemoryStream(); ICSharpCode.SharpZipLib.Zip.Compression.Deflater defl = new ICSharpCode.SharpZipLib.Zip.Compression.Deflater(1,false); Stream s = new ICSharpCode.SharpZipLib.Zip.Compression.Streams.DeflaterOutputStream(ms,defl); s.Write(data, 0, data.Length); s.Close(); byte[] dataComp = (byte[])ms.ToArray(); ms.Close(); int newFileDataCompressedSize = (int)dataComp.Length; // test de remplacer un gros png par un truc tout petit incompresible if ( newFileDataCompressedSize <= fileTable[i].fileDataCompressedSize ){ fs.Seek(fileTable[i].fileDataOffset,SeekOrigin.Begin); bw.Write(dataComp); textBox1.Text += fileTable[i].filePath+" Replaced\r\n"; } else { fileTable[i].fileDataOffset = lastEntryPosition; fs.Seek(fileTable[i].fileDataOffset,SeekOrigin.Begin); bw.Write(dataComp); lastEntryPosition = (int)fs.Position; textBox1.Text += fileTable[i].filePath+" Moved to end\r\n"; } fileTable[i].fileDataCompressedSize = newFileDataCompressedSize; fileTable[i].fileDataDecompressedSize = newFileDataDecompressedSize; ShowProgress(entryCount, i+1); } fs.Seek(lastEntryPosition,SeekOrigin.Begin); fileTableOffset = (int)fs.Position; for (int i = 0; i < entryCount; i++) { byte[] data = new byte[276]; byte[] name = System.Text.Encoding.GetEncoding(936).GetBytes(fileTable[i].filePath); Array.Copy(name, data, name.Length); BitConverter.GetBytes(Convert.ToInt32(fileTable[i].fileDataOffset)).CopyTo(data, 260); BitConverter.GetBytes(Convert.ToInt32(fileTable[i].fileDataDecompressedSize)).CopyTo(data, 264); BitConverter.GetBytes(Convert.ToInt32(fileTable[i].fileDataCompressedSize)).CopyTo(data, 268); MemoryStream ms = new MemoryStream(); ICSharpCode.SharpZipLib.Zip.Compression.Deflater defl = new ICSharpCode.SharpZipLib.Zip.Compression.Deflater(1,false); Stream s = new ICSharpCode.SharpZipLib.Zip.Compression.Streams.DeflaterOutputStream(ms,defl); s.Write(data, 0, data.Length); s.Close(); byte[] dataComp = (byte[])ms.ToArray(); entrySize = (int)dataComp.Length; bw.Write(entrySize ^ KEY_1); bw.Write(entrySize ^ KEY_2); bw.Write(dataComp); ShowProgress(entryCount, i+1); } bw.Write((int)-1526153788); bw.Write((short)2); bw.Write((short)2); bw.Write(fileTableOffset ^ KEY_1); bw.Write((int)0); bw.Write(System.Text.Encoding.GetEncoding(936).GetBytes("Angelica File Package, Perfect World.")); for (int i = 0; i < 215; i++) { bw.Write((byte)0); } bw.Write((int)-2060097592); bw.Write((int)entryCount); bw.Write((short)2); bw.Write((short)2); fs.SetLength(fs.Position); int fileSize = (int)fs.Position; fs.Seek(4, SeekOrigin.Begin); bw.Write(fileSize); br.Close(); bw.Close(); fs.Close(); textBox1.Text += editedFiles.ToString()+" File(s) patched"; label4.Text = filesCount.ToString()+" file(s) patched"; }
void CompressPck() { string pckFile = textBox2.Text; string pckFolder = textBox3.Text + "\\"; int pckFolderLength = pckFolder.Length; //string[] files = Directory.GetFiles("C:\\fw\\", "*.*", SearchOption.AllDirectories); string[] files = Directory.GetFiles(pckFolder, "*.*", SearchOption.AllDirectories); int entryCount = files.Length; int fileTableOffset; fileTableEntry[] fileTable = new fileTableEntry[entryCount]; int entrySize; FileStream BinaryFile = new FileStream(pckFile, FileMode.Create, FileAccess.ReadWrite); BinaryWriter bw = new BinaryWriter(BinaryFile); bw.Write(1305093103); bw.Write((int)0); // placeholder for filesize bw.Write(1453361591); for (int i = 0; i < entryCount; i++) { fileTable[i].filePath = files[i].Substring(pckFolderLength); fileTable[i].fileDataOffset = (int)BinaryFile.Position; FileStream fs = File.OpenRead(pckFolder+fileTable[i].filePath); BinaryReader br = new BinaryReader(fs); fileTable[i].fileDataDecompressedSize = (int)fs.Length; //textBox1.Text += "\r\n__"+fileTable[i].fileDataDecompressedSize.ToString(); byte[] data = br.ReadBytes(fileTable[i].fileDataDecompressedSize); //byte[] bytData = System.Text.Encoding.UTF8.GetBytes(strInput); MemoryStream ms = new MemoryStream(); ICSharpCode.SharpZipLib.Zip.Compression.Deflater defl = new ICSharpCode.SharpZipLib.Zip.Compression.Deflater(1,false); Stream s = new ICSharpCode.SharpZipLib.Zip.Compression.Streams.DeflaterOutputStream(ms,defl); s.Write(data, 0, data.Length); s.Close(); byte[] dataComp = (byte[])ms.ToArray(); fileTable[i].fileDataCompressedSize = (int)dataComp.Length; if(fileTable[i].fileDataCompressedSize < fileTable[i].fileDataDecompressedSize) { bw.Write(dataComp); if ( i == 0){ //textBox1.Text += "\r\n--"+BitConverter.ToString(dataComp); } } // no zlib else { bw.Write(data); } br.Close(); fs.Close(); for (int m = 0; m < 215; m++) { bw.Write((byte)0); } ShowProgress(entryCount, i+1); } fileTableOffset = (int)BinaryFile.Position; for (int i = 0; i < entryCount; i++) { byte[] data = new byte[276]; byte[] name = System.Text.Encoding.GetEncoding(936).GetBytes(fileTable[i].filePath); Array.Copy(name, data, name.Length); BitConverter.GetBytes(Convert.ToInt32(fileTable[i].fileDataOffset)).CopyTo(data, 260); BitConverter.GetBytes(Convert.ToInt32(fileTable[i].fileDataDecompressedSize)).CopyTo(data, 264); BitConverter.GetBytes(Convert.ToInt32(fileTable[i].fileDataCompressedSize)).CopyTo(data, 268); MemoryStream ms = new MemoryStream(); ICSharpCode.SharpZipLib.Zip.Compression.Deflater defl = new ICSharpCode.SharpZipLib.Zip.Compression.Deflater(1,false); Stream s = new ICSharpCode.SharpZipLib.Zip.Compression.Streams.DeflaterOutputStream(ms,defl); s.Write(data, 0, data.Length); s.Close(); byte[] dataComp = (byte[])ms.ToArray(); if ( dataComp.Length >= data.Length ) dataComp = data; entrySize = (int)dataComp.Length; bw.Write(entrySize ^ KEY_1); bw.Write(entrySize ^ KEY_2); bw.Write(dataComp); ShowProgress(entryCount, i+1); } bw.Write((int)-1526153788); bw.Write((short)2); bw.Write((short)2); bw.Write(fileTableOffset ^ KEY_1); bw.Write((int)0); bw.Write(System.Text.Encoding.GetEncoding(936).GetBytes("Angelica File Package, Perfect World.")); for (int i = 0; i < 215; i++) { bw.Write((byte)0); } bw.Write((int)-2060097592); bw.Write((int)entryCount); bw.Write((short)2); bw.Write((short)2); int fileSize = (int)BinaryFile.Position; BinaryFile.Seek(4, SeekOrigin.Begin); bw.Write(fileSize); //textBox1.Text += "\r\n__"+BinaryFile.Position.ToString(); bw.Close(); BinaryFile.Close(); label4.Text = entryCount.ToString()+" file(s) compressed"; }