private void SaveData(IStream stream) { // Create a memory buffer and write the strings there using (var buffer = new MemoryStream()) using (var bufferWriter = new EndianWriter(buffer, stream.Endianness)) { // Write the strings to the buffer foreach (string str in _strings) { if (str != null) { bufferWriter.WriteAscii(str); } } // Align the buffer's length if encryption is necessary if (_key != null) { buffer.SetLength(AES.AlignSize((int)buffer.Length)); } byte[] data = buffer.ToArray(); // Encrypt the buffer if necessary if (_key != null) { data = AES.Encrypt(data, 0, (int)buffer.Length, _key.Key, _key.IV); } // Resize the data area and write it in _data.Resize((int)buffer.Length, stream); stream.SeekTo(_data.Offset); stream.WriteBlock(data, 0, (int)buffer.Length); } }
public int InjectPage(IStream cacheStream, ResourcePage page, byte[] data) { const int pageSize = 0x1000; // Calculate how many pages we need to add to the raw table var pagesNeeded = (int)(Math.Ceiling(page.CompressedSize / (double)pageSize)); // calculate sizes, positions and resize the raw table var injectSize = pagesNeeded * pageSize; var offsetInCache = (_rawTable.Offset + _rawTable.Size); var offsetInRaw = (_rawTable.Size); _rawTable.Resize(_rawTable.Size + injectSize, cacheStream); // write the raw page into the table cacheStream.SeekTo(offsetInCache); cacheStream.WriteBlock(data); return(offsetInRaw); }
private void SaveOffsets(IStream stream) { // I'm assuming here that the official cache files don't intern strings // Doing that might be a possibility even if they don't, but, meh _indexTable.Resize(_strings.Count * 4, stream); stream.SeekTo(_indexTable.Offset); int currentOffset = 0; foreach (string str in _strings) { if (str != null) { stream.WriteInt32(currentOffset); currentOffset += str.Length + 1; // + 1 is for the null terminator } else { stream.WriteInt32(-1); } } }