private void loadTOCfile(string path) { FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read); int memsize = (int)fileStream.Length; memory = new byte[memsize]; int count; int sum = 0; while ((count = fileStream.Read(memory, sum, memsize - sum)) > 0) sum += count; fileStream.Close(); if (memsize > 0) { content = new List<Inventory>(); Inventory temp = new Inventory(); MemoryStream myStream = new MemoryStream(memory); if (myStream.ReadValueU32() == 0x3AB70C13) { myStream.Seek(8, SeekOrigin.Begin); uint jumpSize = myStream.ReadValueU32(); myStream.Seek(jumpSize * 8, SeekOrigin.Current); uint blockSize; do { temp = new Inventory(); long position = myStream.Position; uint value = myStream.ReadValueU32(); blockSize = value & 0xFFFF; uint offset = (uint)myStream.Position; uint fileSize = myStream.ReadValueU32(); myStream.Seek(20, SeekOrigin.Current); string filePath = myStream.ReadStringZ(); myStream.Seek(position + blockSize, SeekOrigin.Begin); temp.name = filePath; temp.offset = offset; temp.size = fileSize; content.Add(temp); } while (blockSize != 0); } myStream.Close(); } }
public GameHeader(MemoryStream stream) { var Length = stream.ReadValueU32(false); var opCode = stream.ReadValueU8(); var Flags = stream.ReadValueU8(); this.SetData(Length, opCode, Flags); }
public TextureGroup(PCCObject pccObj, byte[] data) { enumTextureGroups = new List<ByteProp>(); pccRef = pccObj; MemoryStream buffer = new MemoryStream(data); firstVal = buffer.ReadValueU32(); buffer.Seek(16, SeekOrigin.Begin); otherVal = buffer.ReadValueU32(); int numEnums = buffer.ReadValueS32(); for (int i = 0; i < numEnums; i++) { ByteProp aux = new ByteProp(pccRef.Names[buffer.ReadValueS32()], buffer.ReadValueS32()); enumTextureGroups.Add(aux); } }
private bnet.protocol.storage.ExecuteResponse GetHeroDigest(IClient client, bnet.protocol.storage.ExecuteRequest request) { var results = new List<bnet.protocol.storage.OperationResult>(); foreach(var operation in request.OperationsList) { // find the requested toons entity-id. var stream = new MemoryStream(operation.RowId.Hash.ToByteArray()); // contains ToonHandle in field form with one unknown field (which is not in message definition): // int16 unknown; uint8 realm; uint8 region; uint32 program; uint64 id; stream.ReadValueU16(); // unknown stream.ReadValueU8(); // realm stream.ReadValueU8(); // region stream.ReadValueU32(false); // program var toonId=stream.ReadValueU64(false); if(!client.Account.Toons.ContainsKey(toonId)) { Logger.Error("Can't find the requested toon: " + toonId); continue; } var toon = client.Account.Toons[toonId]; var operationResult = bnet.protocol.storage.OperationResult.CreateBuilder().SetTableId(operation.TableId); operationResult.AddData( bnet.protocol.storage.Cell.CreateBuilder() .SetColumnId(request.OperationsList[0].ColumnId) .SetRowId(request.OperationsList[0].RowId) .SetVersion(1) .SetData(toon.Digest.ToByteString()) .Build() ); results.Add(operationResult.Build()); } var builder = bnet.protocol.storage.ExecuteResponse.CreateBuilder(); foreach(var result in results) { builder.AddResults(result); } return builder.Build(); }
public ME3SaltTexture2D(ME3PCCObject pccObj, int texIdx, String pathBioGame, uint hash = 0) { allPccs = new List<string>(); hasChanged = false; Hash = hash; if (pccObj.isExport(texIdx) && (pccObj.Exports[texIdx].ClassName == className || pccObj.Exports[texIdx].ClassName == class2 || pccObj.Exports[texIdx].ClassName == class3)) { Class = pccObj.Exports[texIdx].ClassName; ME3ExportEntry expEntry = pccObj.Exports[texIdx]; properties = new Dictionary<string, SaltPropertyReader.Property>(); byte[] rawData = (byte[])expEntry.Data.Clone(); int propertiesOffset = SaltPropertyReader.detectStart(pccObj, rawData); headerData = new byte[propertiesOffset]; Buffer.BlockCopy(rawData, 0, headerData, 0, propertiesOffset); pccOffset = expEntry.DataOffset; List<SaltPropertyReader.Property> tempProperties = SaltPropertyReader.getPropList(pccObj, rawData); texName = expEntry.ObjectName; for (int i = 0; i < tempProperties.Count; i++) { SaltPropertyReader.Property property = tempProperties[i]; if (property.Name == "UnpackMin") UnpackNum++; if (!properties.ContainsKey(property.Name)) properties.Add(property.Name, property); switch (property.Name) { case "Format": texFormat = Textures.Methods.ParseFormat(pccObj.Names[property.Value.IntValue].Substring(3)); break; case "TextureFileCacheName": arcName = property.Value.NameValue.Name; break; case "LODGroup": LODGroup = property.Value.NameValue.Name; break; case "None": dataOffset = (uint)(property.offsetval + property.Size); break; } } if (!String.IsNullOrEmpty(arcName)) FullArcPath = GetTexArchive(pathBioGame); // if "None" property isn't found throws an exception if (dataOffset == 0) throw new Exception("\"None\" property not found"); else { imageData = new byte[rawData.Length - dataOffset]; Buffer.BlockCopy(rawData, (int)dataOffset, imageData, 0, (int)(rawData.Length - dataOffset)); } } else throw new Exception("Texture2D " + texIdx + " not found"); pccExpIdx = texIdx; MemoryStream dataStream = new MemoryStream(imageData); // FG: we will move forward with the memorystream (we are reading an export entry for a texture object data inside the pcc) numMipMaps = dataStream.ReadValueU32(); // FG: 1st int32 (4 bytes / 32bits) is number of mipmaps uint count = numMipMaps; privateimgList = new List<ImageInfo>(); ArcDataSize = 0; while (dataStream.Position < dataStream.Length && count > 0) { ImageInfo imgInfo = new ImageInfo(); // FG: store properties in ImageInfo struct (code at top) imgInfo.storageType = (storage)dataStream.ReadValueS32(); // FG: 2nd int32 storage type (see storage types above in enum_struct) imgInfo.uncSize = dataStream.ReadValueS32(); // FG: 3rd int32 uncompressed texture size imgInfo.cprSize = dataStream.ReadValueS32(); // FG: 4th int32 compressed texture size imgInfo.offset = dataStream.ReadValueS32(); // FG: 5th int32 texture offset if (imgInfo.storageType == storage.pccSto) { //imgInfo.offset = (int)(pccOffset + dataOffset); // saving pcc offset as relative to exportdata offset, not absolute imgInfo.offset = (int)dataStream.Position; // saving pcc offset as relative to exportdata offset, not absolute //MessageBox.Show("Pcc class offset: " + pccOffset + "\nimages data offset: " + imgInfo.offset.ToString()); dataStream.Seek(imgInfo.uncSize, SeekOrigin.Current); // FG: if local storage, texture data follows, so advance datastream to after uncompressed_size (pcc storage type only) } else if (imgInfo.storageType == storage.arcCpr || imgInfo.storageType == storage.arcUnc) { ArcDataSize += imgInfo.uncSize; } imgInfo.imgSize = new ImageSize(dataStream.ReadValueU32(), dataStream.ReadValueU32()); // FG: 6th & 7th [or nth and (nth + 1) if local] int32 are width x height privateimgList.Add(imgInfo); // FG: A salty's favorite, add the struct to a list<struct> count--; } // save what remains int remainingBytes = (int)(dataStream.Length - dataStream.Position); footerData = new byte[remainingBytes]; dataStream.Read(footerData, 0, footerData.Length); dataStream.Dispose(); }
public List<ImageInfo> imgList { get; private set; } // showable image list public Texture2D(ME3Package pccObj, int texIdx) { pccRef = pccObj; // check if texIdx is an Export index and a Texture2D class if (pccObj.isExport(texIdx) && (pccObj.Exports[texIdx].ClassName == className)) { IExportEntry expEntry = pccObj.Exports[texIdx]; properties = new Dictionary<string, PropertyReader.Property>(); byte[] rawData = expEntry.Data; int propertiesOffset = PropertyReader.detectStart(pccObj, rawData, expEntry.ObjectFlags); headerData = new byte[propertiesOffset]; Buffer.BlockCopy(rawData, 0, headerData, 0, propertiesOffset); pccOffset = (uint)expEntry.DataOffset; List<PropertyReader.Property> tempProperties = PropertyReader.getPropList(expEntry); texName = expEntry.ObjectName; for (int i = 0; i < tempProperties.Count; i++) { PropertyReader.Property property = tempProperties[i]; if (!properties.ContainsKey(pccObj.Names[property.Name])) properties.Add(pccObj.Names[property.Name], property); switch (pccObj.Names[property.Name]) { case "Format": texFormat = pccObj.Names[property.Value.IntValue].Substring(3); break; case "TextureFileCacheName": arcName = pccObj.Names[property.Value.IntValue]; break; case "LODGroup": LODGroup = pccObj.Names[property.Value.IntValue]; break; case "None": dataOffset = (uint)(property.offsetval + property.Size); break; } } // if "None" property isn't found throws an exception if (dataOffset == 0) throw new Exception("\"None\" property not found"); else { imageData = new byte[rawData.Length - dataOffset]; Buffer.BlockCopy(rawData, (int)dataOffset, imageData, 0, (int)(rawData.Length - dataOffset)); } } else throw new Exception("Texture2D " + texIdx + " not found"); pccExpIdx = texIdx; MemoryStream dataStream = new MemoryStream(imageData); numMipMaps = dataStream.ReadValueU32(); uint count = numMipMaps; imgList = new List<ImageInfo>(); while (dataStream.Position < dataStream.Length && count > 0) { ImageInfo imgInfo = new ImageInfo(); imgInfo.storageType = (storage)dataStream.ReadValueS32(); imgInfo.uncSize = dataStream.ReadValueS32(); imgInfo.cprSize = dataStream.ReadValueS32(); imgInfo.offset = dataStream.ReadValueS32(); if (imgInfo.storageType == storage.pccSto) { //imgInfo.offset = (int)(pccOffset + dataOffset); // saving pcc offset as relative to exportdata offset, not absolute imgInfo.offset = (int)dataStream.Position; // saving pcc offset as relative to exportdata offset, not absolute //MessageBox.Show("Pcc class offset: " + pccOffset + "\nimages data offset: " + imgInfo.offset.ToString()); dataStream.Seek(imgInfo.uncSize, SeekOrigin.Current); } imgInfo.imgSize = new ImageSize(dataStream.ReadValueU32(), dataStream.ReadValueU32()); imgList.Add(imgInfo); count--; } // save what remains /*int remainingBytes = (int)(dataStream.Length - dataStream.Position); footerData = new byte[remainingBytes]; dataStream.Read(footerData, 0, footerData.Length);*/ }
public ME2Texture2D(ME2PCCObject pcc, int pccExpID, String pathBioGame) { ME2ExportEntry exp = pcc.Exports[pccExpID]; if (String.Compare(exp.ClassName, className) != 0 && String.Compare(exp.ClassName, class2) != 0 && String.Compare(exp.ClassName, class3) != 0) { throw new FormatException("Export is not a texture"); } Class = exp.ClassName; exportOffset = exp.DataOffset; FullPackage = exp.PackageFullName; texName = exp.ObjectName; pccFileName = pcc.pccFileName; allPccs = new List<string>(); allPccs.Add(pcc.pccFileName); properties = new Dictionary<string, SaltPropertyReader.Property>(); byte[] rawData = (byte[])exp.Data.Clone(); Compression = "No Compression"; int propertiesOffset = SaltPropertyReader.detectStart(pcc, rawData); headerData = new byte[propertiesOffset]; Buffer.BlockCopy(rawData, 0, headerData, 0, propertiesOffset); pccOffset = (uint)exp.DataOffset; UnpackNum = 0; List<SaltPropertyReader.Property> tempProperties = SaltPropertyReader.getPropList(pcc, rawData); for (int i = 0; i < tempProperties.Count; i++) { SaltPropertyReader.Property property = tempProperties[i]; if (property.Name == "UnpackMin") UnpackNum++; if (!properties.ContainsKey(property.Name)) properties.Add(property.Name, property); switch (property.Name) { case "Format": texFormat = property.Value.StringValue; break; case "TextureFileCacheName": arcName = property.Value.StringValue; break; case "LODGroup": LODGroup = property.Value.StringValue; break; case "CompressionSettings": Compression = property.Value.StringValue; break; case "None": dataOffset = (uint)(property.offsetval + property.Size); break; } } // if "None" property isn't found throws an exception if (dataOffset == 0) throw new Exception("\"None\" property not found"); if (!String.IsNullOrEmpty(arcName)) FullArcPath = GetTexArchive(pathBioGame); imageData = new byte[rawData.Length - dataOffset]; Buffer.BlockCopy(rawData, (int)dataOffset, imageData, 0, (int)(rawData.Length - dataOffset)); //DebugOutput.PrintLn("ImageData size = " + imageData.Length); pccExpIdx = pccExpID; MemoryStream dataStream = new MemoryStream(imageData); privateimgList = new List<ImageInfo>(); dataStream.ReadValueU32(); //Current position in pcc numMipMaps = dataStream.ReadValueU32(); uint count = numMipMaps; ArcDataSize = 0; //DebugOutput.PrintLn(numMipMaps + " derp"); while (dataStream.Position < dataStream.Length && count > 0) { ImageInfo imgInfo = new ImageInfo(); imgInfo.storageType = (storage)dataStream.ReadValueS32(); imgInfo.uncSize = dataStream.ReadValueS32(); imgInfo.cprSize = dataStream.ReadValueS32(); imgInfo.offset = dataStream.ReadValueS32(); if (imgInfo.storageType == storage.pccSto) { imgInfo.offset = (int)dataStream.Position; dataStream.Seek(imgInfo.uncSize, SeekOrigin.Current); } else if (imgInfo.storageType == storage.arcCpr || imgInfo.storageType == storage.arcUnc) { ArcDataSize += imgInfo.uncSize; } imgInfo.imgSize = new ImageSize(dataStream.ReadValueU32(), dataStream.ReadValueU32()); if (privateimgList.Exists(img => img.imgSize == imgInfo.imgSize)) { uint width = imgInfo.imgSize.width; uint height = imgInfo.imgSize.height; if (width == 4 && privateimgList.Exists(img => img.imgSize.width == width)) width = privateimgList.Last().imgSize.width / 2; if (width == 0) width = 1; if (height == 4 && privateimgList.Exists(img => img.imgSize.height == height)) height = privateimgList.Last().imgSize.height / 2; if (height == 0) height = 1; imgInfo.imgSize = new ImageSize(width, height); if (privateimgList.Exists(img => img.imgSize == imgInfo.imgSize)) throw new Exception("Duplicate image size found"); } privateimgList.Add(imgInfo); count--; //DebugOutput.PrintLn("ImgInfo no: " + count + ", Storage Type = " + imgInfo.storageType + ", offset = " + imgInfo.offset); } // Grab the rest for the footer footerData = new byte[dataStream.Length - dataStream.Position]; footerData = dataStream.ReadBytes(footerData.Length); }
private void loadTOCfile(string path) { BitConverter.IsLittleEndian = true; listBox1.Items.Clear(); FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read); memsize = (int)fileStream.Length; memory = new byte[memsize]; int count; int sum = 0; while ((count = fileStream.Read(memory, sum, memsize - sum)) > 0) sum += count; fileStream.Close(); if (memsize > 0) { content = new List<Inventory>(); Inventory temp = new Inventory(); MemoryStream myStream = new MemoryStream(memory); if (myStream.ReadValueU32() == 0x3AB70C13) { myStream.Seek(8, SeekOrigin.Begin); uint jumpSize = myStream.ReadValueU32(); myStream.Seek(jumpSize * 8, SeekOrigin.Current); uint blockSize; do { temp = new Inventory(); long position = myStream.Position; uint value = myStream.ReadValueU32(); blockSize = value & 0xFFFF; uint offset = (uint)myStream.Position; uint fileSize = myStream.ReadValueU32(); myStream.Seek(20, SeekOrigin.Current); string filePath = myStream.ReadStringZ(); myStream.Seek(position + blockSize, SeekOrigin.Begin); temp.name = filePath; temp.offset = offset; temp.size = fileSize; content.Add(temp); } while (blockSize != 0); } myStream.Close(); for (int i = 0; i < content.Count(); i++) { listBox1.Items.Add(content[i].offset.ToString("X") + " : " + content[i].name + " (bytes)" + content[i].size.ToString()); } } }
private static void Main(string[] args) { var paths = Directory.GetFiles("saves", "*.sav"); var successes = 0; var failures = 0; foreach (var path in paths) { var name = Path.GetFileNameWithoutExtension(path); using (var input = File.OpenRead(path)) { var readHash = input.ReadBytes(20); using (var data = input.ReadToMemoryStream(input.Length - 20)) { byte[] computedHash; using (var sha1 = new System.Security.Cryptography.SHA1Managed()) { computedHash = sha1.ComputeHash(data); } if (readHash.SequenceEqual(computedHash) == false) { Console.WriteLine("{0}: failed (SHA1 mismatch)", name); failures++; continue; } data.Position = 0; var uncompressedSize = data.ReadValueU32(Endian.Big); var actualUncompressedSize = (int)uncompressedSize; var uncompressedBytes = new byte[uncompressedSize]; var compressedSize = (int)(data.Length - 4); var compressedBytes = data.ReadBytes(compressedSize); var result = LZO.Decompress(compressedBytes, 0, compressedSize, uncompressedBytes, 0, ref actualUncompressedSize); if (result != LZO.ErrorCode.Success) { Console.WriteLine("{0}: failed (LZO error {1})", name, result); failures++; continue; } using (var outerData = new MemoryStream(uncompressedBytes)) { var innerSize = outerData.ReadValueU32(Endian.Big); var magic = outerData.ReadString(3); if (magic != "WSG") { Console.WriteLine("{0}: failed (bad magic)", name); failures++; continue; } var version = outerData.ReadValueU32(Endian.Little); if (version != 2 && version.Swap() != 2) { Console.WriteLine("{0}: failed (bad version)", name); failures++; continue; } var endian = version == 2 ? Endian.Little : Endian.Big; var hash = outerData.ReadValueU32(endian); var innerUncompressedSize = outerData.ReadValueS32(endian); var innerCompressedBytes = outerData.ReadBytes(innerSize - 3 - 4 - 4 - 4); var innerUncompressedBytes = Huffman.Decoder.Decode(innerCompressedBytes, innerUncompressedSize); using (var innerUncompressedData = new MemoryStream(innerUncompressedBytes)) { using (var output = File.Create("temp.bin")) { output.WriteBytes(innerUncompressedBytes); } var save = Serializer.Deserialize<WillowTwoSave.WillowTwoPlayerSaveGame>(innerUncompressedData); using (var testData = new MemoryStream()) { Serializer.Serialize(testData, save); testData.Position = 0; var testBytes = testData.ReadBytes((uint)testData.Length); if (innerUncompressedBytes.SequenceEqual(testBytes) == false) { Console.WriteLine("{0}: failed (reencode mismatch)", name); using (var output = File.Create(Path.Combine("failures", name + "_before.bin"))) { output.WriteBytes(innerUncompressedBytes); } using (var output = File.Create(Path.Combine("failures", name + "_after.bin"))) { output.WriteBytes(testBytes); } failures++; continue; } successes++; } } } } } } Console.WriteLine("{0} processed ({1} failed, {2} succeeded).", paths.Length, failures, successes); }
public static SaveFile Deserialize(Stream input, DeserializeSettings settings) { if (input.Position + 20 > input.Length) { throw new SaveCorruptionException("not enough data for save header"); } var check = input.ReadValueU32(Endian.Big); if (check == 0x434F4E20) { throw new SaveFormatException("Xbox 360 save game loading is in the works"); } input.Seek(-4, SeekOrigin.Current); var readSha1Hash = input.ReadBytes(20); using (var data = input.ReadToMemoryStream(input.Length - 20)) { byte[] computedSha1Hash; using (var sha1 = new System.Security.Cryptography.SHA1Managed()) { computedSha1Hash = sha1.ComputeHash(data); } if ((settings & DeserializeSettings.IgnoreSha1Mismatch) == 0 && readSha1Hash.SequenceEqual(computedSha1Hash) == false) { throw new SaveCorruptionException("invalid SHA1 hash"); } data.Position = 0; var uncompressedSize = data.ReadValueU32(Endian.Big); var uncompressedBytes = new byte[uncompressedSize]; if (uncompressedSize <= BlockSize) { var actualUncompressedSize = (int)uncompressedSize; var compressedSize = (uint)(data.Length - 4); var compressedBytes = data.ReadBytes(compressedSize); var result = LZO.Decompress(compressedBytes, 0, (int)compressedSize, uncompressedBytes, 0, ref actualUncompressedSize); if (result != LZO.ErrorCode.Success) { throw new SaveCorruptionException(string.Format("LZO decompression failure ({0})", result)); } if (actualUncompressedSize != (int)uncompressedSize) { throw new SaveCorruptionException("LZO decompression failure (uncompressed size mismatch)"); } } else { var blockCount = data.ReadValueU32(Endian.Big); var blockInfos = new List<Tuple<uint, uint>>(); for (uint i = 0; i < blockCount; i++) { var blockCompressedSize = data.ReadValueU32(Endian.Big); var blockUncompressedSize = data.ReadValueU32(Endian.Big); blockInfos.Add(new Tuple<uint, uint>(blockCompressedSize, blockUncompressedSize)); } int uncompressedOffset = 0; int uncompressedSizeLeft = (int)uncompressedSize; foreach (var blockInfo in blockInfos) { var blockUncompressedSize = Math.Min((int)blockInfo.Item2, uncompressedSizeLeft); var actualUncompressedSize = blockUncompressedSize; var compressedSize = (int)blockInfo.Item1; var compressedBytes = data.ReadBytes(compressedSize); var result = LZO.Decompress(compressedBytes, 0, compressedSize, uncompressedBytes, uncompressedOffset, ref actualUncompressedSize); if (result != LZO.ErrorCode.Success) { throw new SaveCorruptionException(string.Format("LZO decompression failure ({0})", result)); } if (actualUncompressedSize != blockUncompressedSize) { throw new SaveCorruptionException("LZO decompression failure (uncompressed size mismatch)"); } uncompressedOffset += blockUncompressedSize; uncompressedSizeLeft -= blockUncompressedSize; } if (uncompressedSizeLeft != 0) { throw new SaveCorruptionException("LZO decompression failure (uncompressed size left != 0)"); } } using (var outerData = new MemoryStream(uncompressedBytes)) { var innerSize = outerData.ReadValueU32(Endian.Big); var magic = outerData.ReadString(3); if (magic != "WSG") { throw new SaveCorruptionException("invalid magic"); } var version = outerData.ReadValueU32(Endian.Little); if (version != 2 && version.Swap() != 2) { throw new SaveCorruptionException("invalid or unsupported version"); } var endian = version == 2 ? Endian.Little : Endian.Big; var readCRC32Hash = outerData.ReadValueU32(endian); var innerUncompressedSize = outerData.ReadValueS32(endian); var innerCompressedBytes = outerData.ReadBytes(innerSize - 3 - 4 - 4 - 4); var innerUncompressedBytes = Huffman.Decoder.Decode(innerCompressedBytes, innerUncompressedSize); if (innerUncompressedBytes.Length != innerUncompressedSize) { throw new SaveCorruptionException("huffman decompression failure"); } var computedCRC32Hash = CRC32.Hash(innerUncompressedBytes, 0, innerUncompressedBytes.Length); if ((settings & DeserializeSettings.IgnoreCrc32Mismatch) == 0 && computedCRC32Hash != readCRC32Hash) { throw new SaveCorruptionException("invalid CRC32 hash"); } using (var innerUncompressedData = new MemoryStream(innerUncompressedBytes)) { var saveGame = ProtoBuf.Serializer.Deserialize<WillowTwoSave.WillowTwoPlayerSaveGame>(innerUncompressedData); if ((settings & DeserializeSettings.IgnoreReencodeMismatch) == 0) { using (var testData = new MemoryStream()) { ProtoBuf.Serializer.Serialize(testData, saveGame); testData.Position = 0; var testBytes = testData.ReadBytes((uint)testData.Length); if (innerUncompressedBytes.SequenceEqual(testBytes) == false) { throw new SaveCorruptionException("reencode mismatch"); } } } saveGame.Decompose(); return new SaveFile() { Endian = endian, SaveGame = saveGame, }; } } } }
public static byte[] Decompress(byte[] buffer, int offset, int count) { if (buffer == null) throw new ArgumentNullException(); if (count < 0) throw new FormatException(); if (offset + count > buffer.Length) throw new IndexOutOfRangeException(); using (MemoryStream buffStream = new MemoryStream(buffer, offset, count)) { InflaterInputStream zipStream; uint magicStream = buffStream.ReadValueU32(); if (magicStream != magic && magicStream.Swap() != magic) { throw new InvalidDataException("found an invalid zlib block"); } uint buffMaxSegmentSize = buffStream.ReadValueU32(); if (buffMaxSegmentSize != maxSegmentSize) { throw new FormatException(); } uint totComprSize = buffStream.ReadValueU32(); uint totUncomprSize = buffStream.ReadValueU32(); byte[] outputBuffer = new byte[totUncomprSize]; int numOfSegm = (int)Math.Ceiling((double)totUncomprSize / (double)maxSegmentSize); int headSegm = 16; int dataSegm = headSegm + (numOfSegm * 8); int buffOff = 0; for (int i = 0; i < numOfSegm; i++) { buffStream.Seek(headSegm, SeekOrigin.Begin); int comprSegm = buffStream.ReadValueS32(); int uncomprSegm = buffStream.ReadValueS32(); headSegm = (int)buffStream.Position; buffStream.Seek(dataSegm, SeekOrigin.Begin); //Console.WriteLine("compr size: {0}, uncompr size: {1}, data offset: 0x{2:X8}", comprSegm, uncomprSegm, dataSegm); zipStream = new InflaterInputStream(buffStream); zipStream.Read(outputBuffer, buffOff, uncomprSegm); zipStream.Flush(); buffOff += uncomprSegm; dataSegm += comprSegm; } buffStream.Close(); return outputBuffer; } }
private bnet.protocol.storage.ExecuteResponse GetHeroDigest(MooNetClient client, bnet.protocol.storage.ExecuteRequest request) { var results = new List<bnet.protocol.storage.OperationResult>(); foreach(var operation in request.OperationsList) { Google.ProtocolBuffers.ByteString data = null; // find the requested toons entity-id. var stream = new MemoryStream(operation.RowId.Hash.ToByteArray()); // contains ToonHandle in field form with one unknown field (which is not in message definition): // int16 unknown; uint8 realm; uint8 region; uint32 program; uint64 id; stream.ReadValueU16(); // unknown stream.ReadValueU8(); // realm stream.ReadValueU8(); // region stream.ReadValueU32(false); // program var toonId = stream.ReadValueU64(false); if (!client.Account.CurrentGameAccount.Toons.ContainsKey(toonId)) { Logger.Error("Can't find the requested toon: {0}", toonId); continue; } var toon = client.Account.CurrentGameAccount.Toons[toonId]; if (operation.ColumnId.Hash.Equals(HeroDigestColumn)) data = toon.Digest.ToByteString(); else Logger.Warn("Unknown ColumndId requested: {0}", operation.ColumnId.Hash.ToByteArray().HexDump()); //else if (operation.ColumnId.Hash.Equals(HeroNameColumn)) // data = toon.NameText.ToByteString(); var operationResult = bnet.protocol.storage.OperationResult.CreateBuilder().SetTableId(operation.TableId); operationResult.AddData( bnet.protocol.storage.Cell.CreateBuilder() .SetColumnId(request.OperationsList[0].ColumnId) .SetRowId(request.OperationsList[0].RowId) .SetVersion(1) .SetData(data) .Build() ); results.Add(operationResult.Build()); } var builder = bnet.protocol.storage.ExecuteResponse.CreateBuilder(); foreach(var result in results) { builder.AddResults(result); } return builder.Build(); }