public byte[] GetBytes(bool pSaveInMemory = false) { if (mMp3bytes != null) { return(mMp3bytes); } if (mWzReader == null) { return(null); } long currentPos = mWzReader.BaseStream.Position; mWzReader.BaseStream.Position = mOffsets; int soundDataLen = mWzReader.ReadCompressedInt(); mWzReader.ReadCompressedInt(); //mWzReader.BaseStream.Position += 82; mMp3bytes = mWzReader.ReadBytes(soundDataLen); mWzReader.BaseStream.Position = currentPos; if (pSaveInMemory) { return(mMp3bytes); } byte[] result = mMp3bytes; mMp3bytes = null; return(result); }
/// <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; }
//public byte BPS { get { return bps; } set { bps = value; } } /// <summary> /// BPS of the mp3 file /// Creates a WzSoundProperty with the specified name /// </summary> /// <param name="name">The name of the property</param> /// <param name="reader">The wz reader</param> /// <param name="parseNow">Indicating whether to parse the property now</param> public WzSoundProperty(string name, WzBinaryReader reader, bool parseNow) { this.Name = name; _wzReader = reader; reader.BaseStream.Position++; //note - soundDataLen does NOT include the length of the header. _soundDataLen = reader.ReadCompressedInt(); // 时间 _time = reader.ReadCompressedInt(); var headerOff = reader.BaseStream.Position; reader.BaseStream.Position += SoundHeader.Length; //skip GUIDs int wavFormatLen = reader.ReadByte(); reader.BaseStream.Position = headerOff; reader.ReadBytes(SoundHeader.Length + 1 + wavFormatLen); //sound file offs _offs = reader.BaseStream.Position; if (parseNow) { _mp3Bytes = reader.ReadBytes(_soundDataLen); } else { reader.BaseStream.Position += _soundDataLen; } }
/// <summary> /// BPS of the mp3 file /// </summary> //public byte BPS { get { return bps; } set { bps = value; } } /// <summary> /// Creates a WzSoundProperty with the specified name /// </summary> /// <param name="name">The name of the property</param> /// <param name="reader">The wz reader</param> /// <param name="parseNow">Indicating whether to parse the property now</param> public WzSoundProperty(string name, WzBinaryReader reader, bool parseNow) { this.name = name; wzReader = reader; reader.BaseStream.Position++; //note - soundDataLen does NOT include the length of the header. soundDataLen = reader.ReadCompressedInt(); len_ms = reader.ReadCompressedInt(); long headerOff = reader.BaseStream.Position; reader.BaseStream.Position += soundHeader.Length; //skip GUIDs int wavFormatLen = reader.ReadByte(); reader.BaseStream.Position = headerOff; header = reader.ReadBytes(soundHeader.Length + 1 + wavFormatLen); ParseHeader(); //sound file offs offs = reader.BaseStream.Position; if (parseNow) { mp3bytes = reader.ReadBytes(soundDataLen); } else { reader.BaseStream.Position += soundDataLen; } }
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; }
public byte[] GetBytes(bool saveInMemory) { if (mp3bytes != null) { return(mp3bytes); } else { if (wzReader == null) { return(null); } long currentPos = wzReader.BaseStream.Position; wzReader.BaseStream.Position = offs; int soundDataLen = wzReader.ReadCompressedInt(); wzReader.ReadCompressedInt(); wzReader.BaseStream.Position += soundHeaderMask.Length; mp3bytes = wzReader.ReadBytes(soundDataLen); wzReader.BaseStream.Position = currentPos; if (saveInMemory) { return(mp3bytes); } else { byte[] result = mp3bytes; mp3bytes = null; return(result); } } }
internal void ParseSound(WzBinaryReader reader) { reader.BaseStream.Position++; int soundDataLen = reader.ReadCompressedInt(); reader.ReadCompressedInt(); mp3bytes = reader.ReadBytes(soundDataLen); }
/// <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(); } }
internal void ParseSound(WzBinaryReader pReader) { pReader.BaseStream.Position++; mOffsets = pReader.BaseStream.Position; int soundDataLen = pReader.ReadCompressedInt(); mLenMs = pReader.ReadCompressedInt(); //mp3bytes = reader.ReadBytes(soundDataLen); Save memory pReader.BaseStream.Position += soundDataLen; mWzReader = pReader; }
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; }
/// <summary> /// BPS of the mp3 file /// </summary> //public byte BPS { get { return bps; } set { bps = value; } } /// <summary> /// Creates a WzSoundProperty with the specified name /// </summary> /// <param name="name">The name of the property</param> /// <param name="reader">The wz reader</param> /// <param name="parseNow">Indicating whether to parse the property now</param> public WzSoundProperty(string name, WzBinaryReader reader, bool parseNow) { this.name = name; wzReader = reader; reader.BaseStream.Position++; offs = reader.BaseStream.Position; //note - soundDataLen does NOT include the length of the header. int soundDataLen = reader.ReadCompressedInt(); len_ms = reader.ReadCompressedInt(); header = reader.ReadBytes(soundHeaderMask.Length); ParseHeader(); if (parseNow) { mp3bytes = reader.ReadBytes(soundDataLen); } else { reader.BaseStream.Position += soundDataLen; } }
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 .lua property /// </summary> /// <param name="offset"></param> /// <param name="reader"></param> /// <param name="parent"></param> /// <param name="parentImg"></param> /// <returns></returns> internal static WzLuaProperty ParseLuaProperty(uint offset, WzBinaryReader reader, WzObject parent, WzImage parentImg) { // 28 71 4F EF 1B 65 F9 1F A7 48 8D 11 73 E7 F0 27 55 09 DD 3C 07 32 D7 38 21 57 84 70 C1 79 9A 3F 49 F7 79 03 41 F4 9D B9 1B 5F CF 26 80 3D EC 25 5F 9C // [compressed int] [bytes] int length = reader.ReadCompressedInt(); byte[] rawEncBytes = reader.ReadBytes(length); WzLuaProperty lua = new WzLuaProperty("Script", rawEncBytes) { Parent = parent }; return(lua); }
/// <summary> /// encVer detecting: /// Since KMST1132 (GMSv230, 2022/02/09), wz removed the 2-byte encVer at 0x3C, and use a fixed encVer 777. /// Here we try to read the first 2 bytes from data part (0x3C) and guess if it looks like an encVer. /// /// Credit: WzComparerR2 project /// </summary> private void Check64BitClient(WzBinaryReader reader) { if (this.Header.FSize >= 2) { this.wzVersionHeader = reader.ReadUInt16(); if (this.wzVersionHeader > 0xff) { b64BitClient = true; } else if (this.wzVersionHeader == 0x80) { // there's an exceptional case that the first field of data part is a compressed int which determines the property count, // if the value greater than 127 and also to be a multiple of 256, the first 5 bytes will become to // 80 00 xx xx xx // so we additional check the int value, at most time the child node count in a WzFile won't greater than 65536 (0xFFFF). if (this.Header.FSize >= 5) { reader.BaseStream.Position = this.header.FStart; // go back to 0x3C int propCount = reader.ReadCompressedInt(); if (propCount > 0 && (propCount & 0xFF) == 0 && propCount <= 0xFFFF) { b64BitClient = true; } } } else if (this.wzVersionHeader == 0x21) // or 33 { b64BitClient = true; // but read the header // the latest KMS seems to include this back in again.. damn this.b64BitClient_withVerHeader = true; // ugly hack, but until i've found a better way without breaking compatibility of old WZs. } } else { // Obviously, if data part have only 1 byte, encVer must be deleted. b64BitClient = true; } // reset position reader.BaseStream.Position = this.Header.FStart; }
internal static List <AWzImageProperty> ParsePropertyList(uint pOffset, WzBinaryReader pReader, AWzObject pParent, WzImage pParentImg) { List <AWzImageProperty> properties = new List <AWzImageProperty>(); int entryCount = pReader.ReadCompressedInt(); for (int i = 0; i < entryCount; i++) { string name = pReader.ReadStringBlock(pOffset).Trim(); byte b = pReader.ReadByte(); switch (b) { case 0: properties.Add(new WzNullProperty(name) { Parent = pParent, ParentImage = pParentImg }); break; case 2: case 11: //UShort properties.Add(new WzShortProperty(name, pReader.ReadInt16()) { Parent = pParent, ParentImage = pParentImg }); break; case 3: case 19: //UInt properties.Add(new WzCompressedIntProperty(name, pReader.ReadCompressedInt()) { Parent = pParent, ParentImage = pParentImg }); break; case 4: byte type = pReader.ReadByte(); if (type == 0x80) { properties.Add(new WzByteFloatProperty(name, pReader.ReadSingle()) { Parent = pParent, ParentImage = pParentImg }); } else if (type == 0) { properties.Add(new WzByteFloatProperty(name, 0f) { Parent = pParent, ParentImage = pParentImg }); } break; case 5: properties.Add(new WzDoubleProperty(name, pReader.ReadDouble()) { Parent = pParent, ParentImage = pParentImg }); break; case 8: properties.Add(new WzStringProperty(name, pReader.ReadStringBlock(pOffset)) { Parent = pParent, ParentImage = pParentImg }); break; case 9: int eob = (int)(pReader.ReadUInt32() + pReader.BaseStream.Position); AWzImageProperty exProp = ParseExtendedProp(pReader, pOffset, eob, name, pParent, pParentImg); if (exProp != null) { properties.Add(exProp); } pReader.BaseStream.Position = eob; break; case 20: properties.Add(new WzCompressedLongProperty(name, pReader.ReadCompressedLong()) { Parent = pParent, ParentImage = pParentImg }); break; default: throw new Exception("Unknown property type at ParsePropertyList: " + b + " name: " + name + " offset: " + pReader.getCurrentOffset()); } } return(properties); }
/// <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(); } } }
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 void ExtractMore(int eob, string name, string iname) { if (iname == "") { iname = reader.ReadString(); } switch (iname) { case "Property": WzSubProperty subProp = new WzSubProperty(name) { Parent = parent, ParentImage = imgParent }; reader.BaseStream.Position += 2; subProp.AddProperties(IWzImageProperty.ParsePropertyList(offset, reader, subProp, imgParent)); extendedProperty = subProp; break; case "Canvas": WzCanvasProperty canvasProp = new WzCanvasProperty(name) { Parent = parent, ParentImage = imgParent }; reader.BaseStream.Position++; if (reader.ReadByte() == 1) { reader.BaseStream.Position += 2; canvasProp.AddProperties(IWzImageProperty.ParsePropertyList(offset, reader, canvasProp, imgParent)); } canvasProp.PngProperty = new WzPngProperty(reader) { Parent = canvasProp, ParentImage = imgParent }; extendedProperty = canvasProp; break; case "Shape2D#Vector2D": WzVectorProperty vecProp = new WzVectorProperty(name) { Parent = parent, ParentImage = imgParent }; vecProp.X = new WzCompressedIntProperty("X", reader.ReadCompressedInt()) { Parent = vecProp, ParentImage = imgParent }; vecProp.Y = new WzCompressedIntProperty("Y", reader.ReadCompressedInt()) { Parent = vecProp, ParentImage = imgParent }; extendedProperty = vecProp; break; case "Shape2D#Convex2D": WzConvexProperty convexProp = new WzConvexProperty(name) { Parent = parent, ParentImage = imgParent }; int convexEntryCount = reader.ReadCompressedInt(); for (int i = 0; i < convexEntryCount; i++) { WzExtendedProperty exProp = new WzExtendedProperty(offset, name) { Parent = convexProp, ParentImage = imgParent }; exProp.ParseExtendedProperty(reader); convexProp.AddProperty(exProp); } extendedProperty = convexProp; break; case "Sound_DX8": WzSoundProperty soundProp = new WzSoundProperty(name) { Parent = parent, ParentImage = imgParent }; soundProp.ParseSound(reader); extendedProperty = soundProp; break; case "UOL": reader.BaseStream.Position++; extendedProperty = new WzUOLProperty(name, ExtractString()) { Parent = parent, ParentImage = imgParent }; /* * switch (reader.ReadByte()) * { * case 0: * extendedProperty = new WzUOLProperty(name, reader.ReadString()) { Parent = parent, ParentImage = imgParent }; * break; * case 1: * extendedProperty = new WzUOLProperty(name, reader.ReadStringAtOffset(offset + reader.ReadInt32())) { Parent = parent, ParentImage = imgParent }; * break; * } */ break; } }
internal static List <IWzImageProperty> ParsePropertyList(uint offset, WzBinaryReader reader, IWzObject parent, WzImage parentImg) { int entryCount = reader.ReadCompressedInt(); List <IWzImageProperty> properties = new List <IWzImageProperty>(entryCount); for (int i = 0; i < entryCount; i++) { string name = reader.ReadStringBlock(offset); switch (reader.ReadByte()) { case 0: properties.Add(new WzNullProperty(name) { Parent = parent /*, ParentImage = parentImg*/ }); break; case 0x0B: case 2: properties.Add(new WzUnsignedShortProperty(name, reader.ReadUInt16()) { Parent = parent /*, ParentImage = parentImg*/ }); break; case 3: properties.Add(new WzCompressedIntProperty(name, reader.ReadCompressedInt()) { Parent = parent /*, ParentImage = parentImg*/ }); break; case 4: byte type = reader.ReadByte(); if (type == 0x80) { properties.Add(new WzByteFloatProperty(name, reader.ReadSingle()) { Parent = parent /*, ParentImage = parentImg*/ }); } else if (type == 0) { properties.Add(new WzByteFloatProperty(name, 0f) { Parent = parent /*, ParentImage = parentImg*/ }); } break; case 5: properties.Add(new WzDoubleProperty(name, reader.ReadDouble()) { Parent = parent /*, ParentImage = parentImg*/ }); break; case 8: properties.Add(new WzStringProperty(name, reader.ReadStringBlock(offset)) { Parent = parent }); break; case 9: int eob = (int)(reader.ReadUInt32() + reader.BaseStream.Position); IWzImageProperty exProp = ParseExtendedProp(reader, offset, eob, name, parent, parentImg); properties.Add(exProp); if (reader.BaseStream.Position != eob) { reader.BaseStream.Position = eob; } break; default: throw new Exception("Unknown property type at ParsePropertyList"); } } return(properties); }
/// <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(); } }
internal static IWzImageProperty[] ParsePropertyList(uint offset, WzBinaryReader reader, IWzObject parent, WzImage parentImg) { List <IWzImageProperty> properties = new List <IWzImageProperty>(); int entryCount = reader.ReadCompressedInt(); for (int i = 0; i < entryCount; i++) { string name = reader.ReadStringBlock(offset); byte ptype = reader.ReadByte(); switch (ptype) { case 0: properties.Add(new WzNullProperty(name, i) { Parent = parent, ParentImage = parentImg }); break; case 0x0B: case 2: properties.Add(new WzUnsignedShortProperty(name, reader.ReadUInt16()) { Parent = parent, ParentImage = parentImg }); break; case 3: properties.Add(new WzCompressedIntProperty(name, reader.ReadCompressedInt()) { Parent = parent, ParentImage = parentImg }); break; case 4: byte type = reader.ReadByte(); if (type == 0x80) { properties.Add(new WzByteFloatProperty(name, reader.ReadSingle()) { Parent = parent, ParentImage = parentImg }); } else if (type == 0) { properties.Add(new WzByteFloatProperty(name, 0f) { Parent = parent, ParentImage = parentImg }); } break; case 5: properties.Add(new WzDoubleProperty(name, reader.ReadDouble()) { Parent = parent, ParentImage = parentImg }); break; case 8: properties.Add(new WzStringProperty(name, reader.ReadStringBlock(offset)) { Parent = parent }); break; case 9: int eob = (int)(reader.ReadUInt32() + reader.BaseStream.Position); WzExtendedProperty exProp = new WzExtendedProperty(offset, eob, name); exProp.Parent = parent; exProp.ParentImage = parentImg; exProp.ParseExtendedProperty(reader); properties.Add(exProp); if (reader.BaseStream.Position != eob) { reader.BaseStream.Position = eob; } break; default: { Console.WriteLine("Unknown type: {0} | {1}", ptype, name); break; } } } return(properties.ToArray()); }
/// <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(); } }
/// <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(); } }
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); } }