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 PatchPck(string pckFilename, string filename, byte[] data) { FileStream fs = new FileStream(FwInstallPath+pckFilename, 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[] hdata = br.ReadBytes(entrySize); // if(entrySize < 276) { fileTable[i] = readTableEntry(hdata, entrySize, true); t++; } // no zlib else { fileTable[i] = readTableEntry(hdata, entrySize, 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 ( fileTable[i].filePath != filename ) continue; nb++; int newFileDataDecompressedSize = (int)data.Length; 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++) { 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"; }