internal void DumpBlock(int endOfBlock, string name) { switch (reader.ReadByte()) { case 0x1B: ExtractMore(endOfBlock, name, reader.ReadStringAtOffset(offset + reader.ReadInt32())); return; case 0x73: ExtractMore(endOfBlock, name, ""); return; } }
/// <summary> /// Parses the wz list file /// </summary> public void ParseWzFile() { //WzTools.CreateWzKey(WzMapleVersion.GMS);//what? WzBinaryReader wzParser = new WzBinaryReader(new MemoryStream(wzFileBytes), WzIv); while (wzParser.PeekChar() != -1) { int Len = wzParser.ReadInt32(); char[] List = new char[Len]; for (int i = 0; i < Len; i++) { List[i] = (char)wzParser.ReadInt16(); } wzParser.ReadUInt16(); string Decrypted = wzParser.DecryptString(List); if (wzParser.PeekChar() == -1) { if (Decrypted[Decrypted.Length - 1] == '/') { Decrypted = Decrypted.TrimEnd("/".ToCharArray()) + "g"; // Last char should always be a g (.img) } } listEntries.Add(Decrypted); } wzParser.Close(); }
/// <summary> /// Parses a wz list file on the disk /// </summary> /// <param name="filePath">Path to the wz file</param> /// <param name="wzIv"></param> public static List <string> ParseListFile(string filePath, byte[] wzIv) { var listEntries = new List <string>(); var wzFileBytes = File.ReadAllBytes(filePath); var wzParser = new WzBinaryReader(new MemoryStream(wzFileBytes), wzIv); while (wzParser.PeekChar() != -1) { var len = wzParser.ReadInt32(); var strChrs = new char[len]; for (var i = 0; i < len; i++) { strChrs[i] = (char)wzParser.ReadInt16(); } wzParser.ReadUInt16(); //encrypted null var decryptedStr = wzParser.DecryptString(strChrs); listEntries.Add(decryptedStr); } wzParser.Close(); var lastIndex = listEntries.Count - 1; var lastEntry = listEntries[lastIndex]; listEntries[lastIndex] = lastEntry.Substring(0, lastEntry.Length - 1) + "g"; return(listEntries); }
internal WzPngProperty(WzBinaryReader reader, bool parseNow) { // Read compressed bytes width = reader.ReadCompressedInt(); height = reader.ReadCompressedInt(); format = reader.ReadCompressedInt(); format2 = reader.ReadByte(); reader.BaseStream.Position += 4; offs = reader.BaseStream.Position; int len = reader.ReadInt32() - 1; reader.BaseStream.Position += 1; if (len > 0) { if (parseNow) { compressedBytes = wzReader.ReadBytes(len); ParsePng(); } else { reader.BaseStream.Position += len; } } wzReader = reader; }
/// <summary> /// Creates a blank WzPngProperty /// </summary> /// <param name="reader"></param> /// <param name="parseNow"></param> internal WzPngProperty(WzBinaryReader reader, bool parseNow) { // Read compressed bytes width = reader.ReadCompressedInt(); height = reader.ReadCompressedInt(); format = reader.ReadCompressedInt(); format2 = reader.ReadByte(); reader.BaseStream.Position += 4; offs = reader.BaseStream.Position; int len = reader.ReadInt32() - 1; reader.BaseStream.Position += 1; if (len > 0) { if (parseNow) { if (wzReader == null) // when saving the WZ file to a new encryption { compressedImageBytes = reader.ReadBytes(len); } else // when opening the Wz property { compressedImageBytes = wzReader.ReadBytes(len); } ParsePng(); } else { reader.BaseStream.Position += len; } } this.wzReader = reader; }
/// <summary> /// Parses the WzDirectory /// </summary> internal void ParseDirectory() { int entryCount = reader.ReadCompressedInt(); for (int i = 0; i < entryCount; i++) { byte type = reader.ReadByte(); string fname = null; int fsize; int checksum; uint offset; long rememberPos = 0; if (type == 2) { int stringOffset = reader.ReadInt32(); rememberPos = reader.BaseStream.Position; reader.BaseStream.Position = reader.Header.FStart + stringOffset; type = reader.ReadByte(); fname = reader.ReadString(); } else if (type == 3 || type == 4) { fname = reader.ReadString(); rememberPos = reader.BaseStream.Position; } reader.BaseStream.Position = rememberPos; fsize = reader.ReadCompressedInt(); checksum = reader.ReadCompressedInt(); offset = reader.ReadOffset(); if (type == 3) { WzDirectory subDir = new WzDirectory(reader, fname, hash, WzIv); subDir.BlockSize = fsize; subDir.Checksum = checksum; subDir.Offset = offset; subDir.Parent = this; subDirs.Add(subDir); } else { WzImage img = new WzImage(fname, reader); img.BlockSize = fsize; img.Checksum = checksum; img.Offset = offset; img.Parent = this; images.Add(img); } } foreach (WzDirectory subdir in subDirs) { reader.BaseStream.Position = subdir.offset; subdir.ParseDirectory(); } }
public byte[] GetCompressedBytes(bool pSaveInMemory = false) { if (mCompressedBytes == null) { long pos = mWzReader.BaseStream.Position; mWzReader.BaseStream.Position = mOffsets; int len = mWzReader.ReadInt32() - 1; mWzReader.BaseStream.Position += 1; if (len > 0) { mCompressedBytes = mWzReader.ReadBytes(len); } mWzReader.BaseStream.Position = pos; if (!pSaveInMemory) { mCompressedBytes = null; return(mCompressedBytes); } } return(mCompressedBytes); }
public byte[] GetCompressedBytes(bool saveInMemory) { if (compressedBytes == null) { long pos = wzReader.BaseStream.Position; wzReader.BaseStream.Position = offs; int len = wzReader.ReadInt32() - 1; wzReader.BaseStream.Position += 1; if (len > 0) { compressedBytes = wzReader.ReadBytes(len); } wzReader.BaseStream.Position = pos; if (!saveInMemory) { //were removing the referance to compressedBytes, so a backup for the ret value is needed byte[] returnBytes = compressedBytes; compressedBytes = null; return(returnBytes); } } return(compressedBytes); }
internal WzPngProperty(WzBinaryReader reader) { // Read compressed bytes width = reader.ReadCompressedInt(); height = reader.ReadCompressedInt(); format = reader.ReadCompressedInt(); format2 = reader.ReadByte(); reader.BaseStream.Position += 4; int len = reader.ReadInt32() - 1; reader.BaseStream.Position += 1; if (len > 0) { compressedBytes = reader.ReadBytes(len); } }
internal WzPngProperty(WzBinaryReader pReader) { // Read compressed bytes mWidth = pReader.ReadCompressedInt(); mHeight = pReader.ReadCompressedInt(); mFormat = pReader.ReadCompressedInt(); mFormat2 = pReader.ReadByte(); pReader.BaseStream.Position += 4; mOffsets = pReader.BaseStream.Position; int len = pReader.ReadInt32() - 1; pReader.BaseStream.Position += 1; if (len > 0) { pReader.BaseStream.Position += len; } mWzReader = pReader; }
internal WzPngProperty(WzBinaryReader reader, bool parseNow) { this.wzReader = reader; // Width Height width = reader.ReadCompressedInt(); height = reader.ReadCompressedInt(); if (this.width >= 0x10000 || this.height >= 0x10000) // copy pasta eric <3 { throw new ArgumentException(string.Format("Invalid WzPngProperty in Wz. Width: {0}, Height: {1}", width, height)); } // Image format nPixFormat = reader.ReadCompressedInt(); nMagLevel = reader.ReadByte(); // Other crap reader.BaseStream.Position += 4; offs = reader.BaseStream.Position; int len = reader.ReadInt32() - 1; reader.BaseStream.Position += 1; if (len > 0) { if (parseNow) { compressedBytes = wzReader.ReadBytes(len); ParsePng(); } else { reader.BaseStream.Position += len; } } wzReader = reader; }
/// <summary> /// Parses the wz list file /// </summary> public void ParseWzFile() { using (WzBinaryReader wzParser = new WzBinaryReader(new MemoryStream(mWzFileBytes), mWzIv)) { while (wzParser.PeekChar() != -1) { int Len = wzParser.ReadInt32(); char[] List = new char[Len]; for (int i = 0; i < Len; i++) { List[i] = (char)wzParser.ReadInt16(); } wzParser.ReadUInt16(); string Decrypted = wzParser.DecryptString(List); if (wzParser.PeekChar() == -1) { if (Decrypted[Decrypted.Length - 1] == '/') { Decrypted = Decrypted.TrimEnd("/".ToCharArray()) + "g"; // Last char should always be a g (.img) } } mListEntries.Add(Decrypted); } } }
/// <summary> /// Parses the WzDirectory /// </summary> internal void ParseDirectory(WzFile parent = null) { //Array.Copy(mReader.WzKey, keyCopy, mReader.WzKey.Length); int entryCount = mReader.ReadCompressedInt(); for (int i = 0; i < entryCount; i++) { byte type = mReader.ReadByte(); string fname = null; int fsize; int checksum; uint offset; long rememberPos = 0; switch (type) { case 1: { mReader.ReadInt32(); mReader.ReadInt16(); mReader.ReadOffset(); continue; } case 2: { int stringOffset = mReader.ReadInt32(); rememberPos = mReader.BaseStream.Position; mReader.BaseStream.Position = mReader.Header.FStart + stringOffset; type = mReader.ReadByte(); fname = mReader.ReadString().Trim(); } break; case 3: case 4: fname = mReader.ReadString().Trim(); rememberPos = mReader.BaseStream.Position; break; } mReader.BaseStream.Position = rememberPos; fsize = mReader.ReadCompressedInt(); checksum = mReader.ReadCompressedInt(); offset = mReader.ReadOffset(); if (type == 3) { WzDirectory subDir = new WzDirectory(mReader, fname, mHash, mWzIv) { BlockSize = fsize, Checksum = checksum, Offset = offset, Parent = parent ?? this }; if (parent != null) { parent.mSubDirs.Add(subDir); } mSubDirs.Add(subDir); } else { WzImage img = new WzImage(fname, mReader) { BlockSize = fsize, Checksum = checksum, Offset = offset, Parent = parent ?? this }; if (parent != null) { parent.mImages.Add(img); } mImages.Add(img); } } foreach (WzDirectory subdir in mSubDirs) { mReader.BaseStream.Position = subdir.mOffset; subdir.ParseDirectory(); } }
internal static AWzImageProperty ParseExtendedProp(WzBinaryReader pReader, uint pOffset, int pEndOfBlock, string pName, AWzObject pParent, WzImage pImgParent) { byte b = pReader.ReadByte(); switch (b) { case 0x1B: return(ExtractMore(pReader, pOffset, pEndOfBlock, pName, pReader.ReadStringAtOffset(pOffset + pReader.ReadInt32()), pParent, pImgParent)); case 0x73: return(ExtractMore(pReader, pOffset, pEndOfBlock, pName, pReader.ReadString(), pParent, pImgParent)); default: return(null); //throw new Exception("Invlid type at ParseExtendedProp: " + b); } }
internal static AWzImageProperty ExtractMore(WzBinaryReader pReader, uint pOffset, int pEndOfBlock, string pName, string pImageName, AWzObject pParent, WzImage pImgParent) { switch (pImageName) { case "Property": WzSubProperty subProp = new WzSubProperty(pName) { Parent = pParent, ParentImage = pImgParent }; pReader.BaseStream.Position += 2; subProp.AddProperties(ParsePropertyList(pOffset, pReader, subProp, pImgParent)); return(subProp); case "Canvas": WzCanvasProperty canvasProp = new WzCanvasProperty(pName) { Parent = pParent, ParentImage = pImgParent }; pReader.BaseStream.Position++; if (pReader.ReadByte() == 1) { pReader.BaseStream.Position += 2; canvasProp.AddProperties(ParsePropertyList(pOffset, pReader, canvasProp, pImgParent)); } canvasProp.PngProperty = new WzPngProperty(pReader) { Parent = canvasProp, ParentImage = pImgParent }; return(canvasProp); case "Shape2D#Vector2D": WzVectorProperty vecProp = new WzVectorProperty(pName) { Parent = pParent, ParentImage = pImgParent }; vecProp.X = new WzCompressedIntProperty("X", pReader.ReadCompressedInt()) { Parent = vecProp, ParentImage = pImgParent }; vecProp.Y = new WzCompressedIntProperty("Y", pReader.ReadCompressedInt()) { Parent = vecProp, ParentImage = pImgParent }; return(vecProp); case "Shape2D#Convex2D": WzConvexProperty convexProp = new WzConvexProperty(pName) { Parent = pParent, ParentImage = pImgParent }; int convexEntryCount = pReader.ReadCompressedInt(); for (int i = 0; i < convexEntryCount; i++) { AWzImageProperty imgProp = ParseExtendedProp(pReader, pOffset, 0, pName, convexProp, pImgParent); if (imgProp != null) { convexProp.AddProperty(imgProp); } } return(convexProp); case "Sound_DX8": WzSoundProperty soundProp = new WzSoundProperty(pName) { Parent = pParent, ParentImage = pImgParent }; soundProp.ParseSound(pReader); return(soundProp); case "UOL": pReader.BaseStream.Position++; byte b = pReader.ReadByte(); switch (b) { case 0: return(new WzUOLProperty(pName, pReader.ReadString()) { Parent = pParent, ParentImage = pImgParent }); case 1: return(new WzUOLProperty(pName, pReader.ReadStringAtOffset(pOffset + pReader.ReadInt32())) { Parent = pParent, ParentImage = pImgParent }); default: throw new Exception("Unsupported UOL type: " + b); } default: throw new Exception("Unknown image name: " + pImageName); } }
internal static IExtended ExtractMore(WzBinaryReader reader, uint offset, int eob, string name, string iname, IWzObject parent, WzImage imgParent) { if (iname == "") { iname = reader.ReadString(); } switch (iname) { case "Property": WzSubProperty subProp = new WzSubProperty(name) { Parent = parent }; reader.BaseStream.Position += 2; subProp.AddProperties(IWzImageProperty.ParsePropertyList(offset, reader, subProp, imgParent)); return(subProp); case "Canvas": WzCanvasProperty canvasProp = new WzCanvasProperty(name) { Parent = parent }; reader.BaseStream.Position++; if (reader.ReadByte() == 1) { reader.BaseStream.Position += 2; canvasProp.AddProperties(IWzImageProperty.ParsePropertyList(offset, reader, canvasProp, imgParent)); } canvasProp.PngProperty = new WzPngProperty(reader, imgParent.parseEverything) { Parent = canvasProp }; return(canvasProp); case "Shape2D#Vector2D": WzVectorProperty vecProp = new WzVectorProperty(name) { Parent = parent }; vecProp.X = new WzCompressedIntProperty("X", reader.ReadCompressedInt()) { Parent = vecProp }; vecProp.Y = new WzCompressedIntProperty("Y", reader.ReadCompressedInt()) { Parent = vecProp }; return(vecProp); case "Shape2D#Convex2D": WzConvexProperty convexProp = new WzConvexProperty(name) { Parent = parent }; int convexEntryCount = reader.ReadCompressedInt(); convexProp.WzProperties.Capacity = convexEntryCount; //performance thing for (int i = 0; i < convexEntryCount; i++) { convexProp.AddProperty(ParseExtendedProp(reader, offset, 0, name, convexProp, imgParent)); } return(convexProp); case "Sound_DX8": WzSoundProperty soundProp = new WzSoundProperty(name, reader, imgParent.parseEverything) { Parent = parent }; return(soundProp); case "UOL": reader.BaseStream.Position++; switch (reader.ReadByte()) { case 0: return(new WzUOLProperty(name, reader.ReadString()) { Parent = parent }); case 1: return(new WzUOLProperty(name, reader.ReadStringAtOffset(offset + reader.ReadInt32())) { Parent = parent }); } throw new Exception("Unsupported UOL type"); default: throw new Exception("Unknown iname: " + iname); } }
internal static IExtended ParseExtendedProp(WzBinaryReader reader, uint offset, int endOfBlock, string name, IWzObject parent, WzImage imgParent) { switch (reader.ReadByte()) { case 0x1B: return(ExtractMore(reader, offset, endOfBlock, name, reader.ReadStringAtOffset(offset + reader.ReadInt32()), parent, imgParent)); case 0x73: return(ExtractMore(reader, offset, endOfBlock, name, "", parent, imgParent)); default: throw new System.Exception("Invlid byte read at ParseExtendedProp"); } }
/// <summary> /// Parses the WzDirectory /// <paramref name="lazyParse">Only parses the first directory</paramref> /// </summary> internal void ParseDirectory(bool lazyParse = false) { //Debug.WriteLine(HexTool.ToString( reader.ReadBytes(20))); //reader.BaseStream.Position = reader.BaseStream.Position - 20; int entryCount = reader.ReadCompressedInt(); for (int i = 0; i < entryCount; i++) { byte type = reader.ReadByte(); string fname = null; int fsize; int checksum; uint offset; long rememberPos = 0; switch (type) { case 1: //01 XX 00 00 00 00 00 OFFSET (4 bytes) { int unknown = reader.ReadInt32(); reader.ReadInt16(); uint offs = reader.ReadOffset(); continue; } case 2: { int stringOffset = reader.ReadInt32(); rememberPos = reader.BaseStream.Position; reader.BaseStream.Position = reader.Header.FStart + stringOffset; type = reader.ReadByte(); fname = reader.ReadString(); break; } case 3: case 4: { fname = reader.ReadString(); rememberPos = reader.BaseStream.Position; break; } default: { break; } } reader.BaseStream.Position = rememberPos; fsize = reader.ReadCompressedInt(); checksum = reader.ReadCompressedInt(); offset = reader.ReadOffset(); if (type == 3) { WzDirectory subDir = new WzDirectory(reader, fname, hash, WzIv, wzFile); subDir.BlockSize = fsize; subDir.Checksum = checksum; subDir.Offset = offset; subDir.Parent = this; subDirs.Add(subDir); if (lazyParse) { break; } } else { WzImage img = new WzImage(fname, reader); img.BlockSize = fsize; img.Checksum = checksum; img.Offset = offset; img.Parent = this; images.Add(img); if (lazyParse) { break; } } } foreach (WzDirectory subdir in subDirs) { reader.BaseStream.Position = subdir.offset; subdir.ParseDirectory(); } }
/// <summary> /// Parses the WzDirectory /// </summary> internal void ParseDirectory() { var entryCount = _reader.ReadCompressedInt(); for (var i = 0; i < entryCount; i++) { var type = _reader.ReadByte(); string fname = null; long rememberPos = 0; switch (type) { case 1: var unknown = _reader.ReadInt32(); _reader.ReadInt16(); var offs = _reader.ReadOffset(); continue; case 2: var stringOffset = _reader.ReadInt32(); rememberPos = _reader.BaseStream.Position; _reader.BaseStream.Position = _reader.Header.FStart + stringOffset; type = _reader.ReadByte(); fname = _reader.ReadString(); break; case 3: case 4: fname = _reader.ReadString(); rememberPos = _reader.BaseStream.Position; break; } _reader.BaseStream.Position = rememberPos; var fsize = _reader.ReadCompressedInt(); var dirChecksum = _reader.ReadCompressedInt(); var dirOffset = _reader.ReadOffset(); if (type == 3) { var subDir = new WzDirectory(_reader, fname, _hash, WzIv, _wzFile) { BlockSize = fsize, Checksum = dirChecksum, Offset = dirOffset, Parent = this }; WzDirectories.Add(subDir); } else { var img = new WzImage(fname, _reader) { BlockSize = fsize, Checksum = dirChecksum, Offset = dirOffset, Parent = this }; WzImages.Add(img); } } foreach (var subdir in WzDirectories) { _reader.BaseStream.Position = subdir.Offset; subdir.ParseDirectory(); } }
/// <summary> /// Parses the WzDirectory /// <paramref name="lazyParse">Only parses the first directory</paramref> /// </summary> internal void ParseDirectory(bool lazyParse = false) { //Debug.WriteLine(HexTool.ToString( reader.ReadBytes(20))); //reader.BaseStream.Position = reader.BaseStream.Position - 20; long available = reader.Available(); if (available == 0) { return; } int entryCount = reader.ReadCompressedInt(); if (entryCount < 0 || entryCount > 100000) // probably nothing > 100k folders for now. { throw new Exception("Invalid wz version used for decryption, try parsing other version numbers."); } for (int i = 0; i < entryCount; i++) { byte type = reader.ReadByte(); string fname = null; int fsize; int checksum; uint offset; long rememberPos = 0; switch (type) { case 1: //01 XX 00 00 00 00 00 OFFSET (4 bytes) { int unknown = reader.ReadInt32(); reader.ReadInt16(); uint offs = reader.ReadOffset(); continue; } case 2: { int stringOffset = reader.ReadInt32(); rememberPos = reader.BaseStream.Position; reader.BaseStream.Position = reader.Header.FStart + stringOffset; type = reader.ReadByte(); fname = reader.ReadString(); break; } case 3: case 4: { fname = reader.ReadString(); rememberPos = reader.BaseStream.Position; break; } default: { throw new Exception("[WzDirectory] Unknown directory. type = " + type); } } reader.BaseStream.Position = rememberPos; fsize = reader.ReadCompressedInt(); checksum = reader.ReadCompressedInt(); offset = reader.ReadOffset(); // IWzArchive::Getposition(pArchive) if (type == 3) { WzDirectory subDir = new WzDirectory(reader, fname, hash, WzIv, wzFile) { BlockSize = fsize, Checksum = checksum, Offset = offset, Parent = this }; subDirs.Add(subDir); if (lazyParse) { break; } } else { WzImage img = new WzImage(fname, reader, checksum) { BlockSize = fsize, Offset = offset, Parent = this }; images.Add(img); if (lazyParse) { break; } } } foreach (WzDirectory subdir in subDirs) { if (subdir.Checksum != 0) { reader.BaseStream.Position = subdir.offset; subdir.ParseDirectory(); } } }