diff --git a/MapleLib/WzLib/Util/WzTool.cs b/MapleLib/WzLib/Util/WzTool.cs index 1e7aeb4..c3030b7 100644 --- a/MapleLib/WzLib/Util/WzTool.cs +++ b/MapleLib/WzLib/Util/WzTool.cs @@ -114,7 +114,7 @@ public static double GetDecryptionSuccessRate(string wzPath, WzMapleVersion encV else wzf = new WzFile(wzPath, (short)version, encVersion); wzf.ParseWzFile(); - if (version == null) version = wzf.Version; + if (version == null) version = wzf.FileVersion; int recognizedChars = 0; int totalChars = 0; foreach (WzDirectory wzdir in wzf.WzDirectory.WzDirectories) diff --git a/MapleLib/WzLib/WzDirectory.cs b/MapleLib/WzLib/WzDirectory.cs index 027c54c..d6c2e50 100644 --- a/MapleLib/WzLib/WzDirectory.cs +++ b/MapleLib/WzLib/WzDirectory.cs @@ -58,10 +58,14 @@ public override /*I*/WzFile WzFileParent get { return wzFile; } } - /// - /// Disposes the obejct - /// - public override void Dispose() + public override string ToString() { + return string.Format("WzDirectory('{0}')", Name); + } + + /// + /// Disposes the obejct + /// + public override void Dispose() { name = null; reader = null; @@ -107,12 +111,12 @@ public override void Dispose() get { foreach (WzImage i in images) - if (i.Name.ToLower() == name.ToLower()) + if (i.Name.ToLower() == name.ToLower() + || Path.GetFileNameWithoutExtension(i.Name.ToLower()) == Path.GetFileNameWithoutExtension(name.ToLower())) return i; foreach (WzDirectory d in subDirs) if (d.Name.ToLower() == name.ToLower()) return d; - //throw new KeyNotFoundException("No wz image or directory was found with the specified name"); return null; } set diff --git a/MapleLib/WzLib/WzFile.cs b/MapleLib/WzLib/WzFile.cs index 91f4997..5b70147 100644 --- a/MapleLib/WzLib/WzFile.cs +++ b/MapleLib/WzLib/WzFile.cs @@ -21,586 +21,493 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the using MapleLib.WzLib.Util; using MapleLib.WzLib.WzProperties; -namespace MapleLib.WzLib -{ - /// - /// A class that contains all the information of a wz file - /// - public class WzFile : WzObject - { - #region Fields - internal string path; - internal WzDirectory wzDir; - internal WzHeader header; - internal string name = ""; - internal short version = 0; - internal uint versionHash = 0; - internal short fileVersion = 0; - internal WzMapleVersion mapleVersion; - internal byte[] WzIv; - #endregion - - /// - /// The parsed IWzDir after having called ParseWzDirectory(), this can either be a WzDirectory or a WzListDirectory - /// - public WzDirectory WzDirectory - { - get { return wzDir; } - set { wzDir = value; } - } - - /// - /// Name of the WzFile - /// - public override string Name - { - get { return name; } - set { name = value; } - } - - /// - /// The WzObjectType of the file - /// - public override WzObjectType ObjectType - { - get { return WzObjectType.File; } - } - - /// - /// Returns WzDirectory[name] - /// - /// Name - /// WzDirectory[name] - public new WzObject this[string name] - { - get { return WzDirectory[name]; } - } - - public WzHeader Header { get { return header; } set { header = value; } } - - public short Version { get { return fileVersion; } set { fileVersion = value; } } - - public string FilePath { get { return path; } } - - public WzMapleVersion MapleVersion { get { return mapleVersion; } set { mapleVersion = value; } } - - public override WzObject Parent { get { return null; } internal set { } } +namespace MapleLib.WzLib { + /// + /// A class that contains all the information of a wz file + /// + public class WzFile : WzObject { + #region Fields + private short version = 0; + private uint versionHash = 0; + private byte[] WzIv; + #endregion + + /// + /// The parsed IWzDir after having called ParseWzDirectory(), this can either be a WzDirectory or a WzListDirectory + /// + public WzDirectory WzDirectory { get; set; } + + /// + /// Name of the WzFile + /// + public override string Name { get; set; } + + /// + /// The WzObjectType of the file + /// + public override WzObjectType ObjectType { get { return WzObjectType.File; } } + + /// + /// Returns WzDirectory[name] + /// + /// Name + /// WzDirectory[name] + public new WzObject this[string name] { get { return WzDirectory[name]; } } + + public WzHeader Header { get; set; } + + public short FileVersion { get; set; } + + public string FilePath { get; private set; } + + public WzMapleVersion MapleVersion { get; set; } + + public override WzObject Parent { get { return null; } internal set { } } public override WzFile WzFileParent { get { return this; } } - public override void Dispose() - { - if (wzDir == null || wzDir.reader == null) return; - wzDir.reader.Close(); - Header = null; - path = null; - name = null; - WzDirectory.Dispose(); - GC.Collect(); - GC.WaitForPendingFinalizers(); - } - - public WzFile(short gameVersion, WzMapleVersion version) - { - wzDir = new WzDirectory(); - this.Header = WzHeader.GetDefault(); - fileVersion = gameVersion; - mapleVersion = version; - WzIv = version.EncryptionKey(); - wzDir.WzIv = WzIv; - } - - /// - /// Open a wz file from a file on the disk - /// - /// Path to the wz file - public WzFile(string filePath, WzMapleVersion version) - { - name = Path.GetFileName(filePath); - path = filePath; - fileVersion = -1; - mapleVersion = version; - if (version == WzMapleVersion.GETFROMZLZ) - { + public override void Dispose() { + if (WzDirectory == null || WzDirectory.reader == null) return; + WzDirectory.reader.Close(); + Header = null; + FilePath = null; + Name = null; + WzDirectory.Dispose(); + GC.Collect(); + GC.WaitForPendingFinalizers(); + } + + public WzFile(short gameVersion, WzMapleVersion version) { + WzDirectory = new WzDirectory(); + this.Header = WzHeader.GetDefault(); + FileVersion = gameVersion; + MapleVersion = version; + WzIv = version.EncryptionKey(); + WzDirectory.WzIv = WzIv; + } + + /// + /// Open a wz file from a file on the disk + /// + /// Path to the wz file + public WzFile(string filePath, WzMapleVersion version) { + Name = Path.GetFileName(filePath); + FilePath = filePath; + FileVersion = -1; + MapleVersion = version; + if (version == WzMapleVersion.GETFROMZLZ) { FileStream zlzStream = File.OpenRead(Path.Combine(Path.GetDirectoryName(filePath), "ZLZ.dll")); WzIv = Util.WzKeyGenerator.GetIvFromZlz(zlzStream); zlzStream.Close(); - } - else WzIv = version.EncryptionKey(); - } - - /// - /// Open a wz file from a file on the disk - /// - /// Path to the wz file - public WzFile(string filePath, short gameVersion, WzMapleVersion version) - { - name = Path.GetFileName(filePath); - path = filePath; - fileVersion = gameVersion; - mapleVersion = version; - if (version == WzMapleVersion.GETFROMZLZ) - { + } else WzIv = version.EncryptionKey(); + } + + /// + /// Open a wz file from a file on the disk + /// + /// Path to the wz file + public WzFile(string filePath, short gameVersion, WzMapleVersion version) { + Name = Path.GetFileName(filePath); + FilePath = filePath; + FileVersion = gameVersion; + MapleVersion = version; + if (version == WzMapleVersion.GETFROMZLZ) { FileStream zlzStream = File.OpenRead(Path.Combine(Path.GetDirectoryName(filePath), "ZLZ.dll")); WzIv = Util.WzKeyGenerator.GetIvFromZlz(zlzStream); zlzStream.Close(); + } else WzIv = version.EncryptionKey(); + } + + /// + /// Parses the wz file, if the wz file is a list.wz file, WzDirectory will be a WzListDirectory, if not, it'll simply be a WzDirectory + /// + public void ParseWzFile() { + if (MapleVersion == WzMapleVersion.GENERATE) + throw new InvalidOperationException("Cannot call ParseWzFile() if WZ file type is GENERATE"); + ParseMainWzDirectory(); + GC.Collect(); + GC.WaitForPendingFinalizers(); + } + + public void ParseWzFile(byte[] WzIv) { + if (MapleVersion != WzMapleVersion.GENERATE) + throw new InvalidOperationException( + "Cannot call ParseWzFile(byte[] generateKey) if WZ file type is not GENERATE"); + this.WzIv = WzIv; + ParseMainWzDirectory(); + GC.Collect(); + GC.WaitForPendingFinalizers(); + } + + internal void ParseMainWzDirectory() { + if (FilePath == null) { + Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Path is null"); + return; + } + + WzBinaryReader reader = new WzBinaryReader(File.Open(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read), WzIv); + + this.Header = new WzHeader(); + this.Header.Ident = reader.ReadString(4); + this.Header.FSize = reader.ReadUInt64(); + this.Header.FStart = reader.ReadUInt32(); + this.Header.Copyright = reader.ReadNullTerminatedString(); + reader.ReadBytes((int)(Header.FStart - reader.BaseStream.Position)); + reader.Header = this.Header; + this.version = reader.ReadInt16(); + if (FileVersion == -1) { + for (int j = 0; j < short.MaxValue; j++) { + this.FileVersion = (short)j; + this.versionHash = GetVersionHash(version, FileVersion); + if (this.versionHash != 0) { + reader.Hash = this.versionHash; + long position = reader.BaseStream.Position; + WzDirectory testDirectory = null; + try { + testDirectory = new WzDirectory(reader, this.Name, this.versionHash, this.WzIv, this); + testDirectory.ParseDirectory(); + } catch { + reader.BaseStream.Position = position; + continue; + } + WzImage testImage = testDirectory.GetChildImages()[0]; + + try { + reader.BaseStream.Position = testImage.Offset; + byte checkByte = reader.ReadByte(); + reader.BaseStream.Position = position; + testDirectory.Dispose(); + switch (checkByte) { + case 0x73: + case 0x1b: { + WzDirectory directory = new WzDirectory(reader, this.Name, this.versionHash, this.WzIv, this); + directory.ParseDirectory(); + this.WzDirectory = directory; + return; + } + } + reader.BaseStream.Position = position; + } catch { + reader.BaseStream.Position = position; + } + } + } + throw new Exception("Error with game version hash : The specified game version is incorrect and WzLib was unable to determine the version itself"); + } else { + this.versionHash = GetVersionHash(version, FileVersion); + reader.Hash = this.versionHash; + WzDirectory directory = new WzDirectory(reader, this.Name, this.versionHash, this.WzIv, this); + directory.ParseDirectory(); + this.WzDirectory = directory; + } + } + + private uint GetVersionHash(int encver, int realver) { + int EncryptedVersionNumber = encver; + int VersionNumber = realver; + int VersionHash = 0; + int DecryptedVersionNumber = 0; + string VersionNumberStr; + int a = 0, b = 0, c = 0, d = 0, l = 0; + + VersionNumberStr = VersionNumber.ToString(); + + l = VersionNumberStr.Length; + for (int i = 0; i < l; i++) { + VersionHash = (32 * VersionHash) + (int)VersionNumberStr[i] + 1; + } + a = (VersionHash >> 24) & 0xFF; + b = (VersionHash >> 16) & 0xFF; + c = (VersionHash >> 8) & 0xFF; + d = VersionHash & 0xFF; + DecryptedVersionNumber = (0xff ^ a ^ b ^ c ^ d); + + if (EncryptedVersionNumber == DecryptedVersionNumber) { + return Convert.ToUInt32(VersionHash); + } else { + return 0; + } + } + + private void CreateVersionHash() { + versionHash = 0; + foreach (char ch in FileVersion.ToString()) { + versionHash = (versionHash * 32) + (byte)ch + 1; + } + uint a = (versionHash >> 24) & 0xFF, + b = (versionHash >> 16) & 0xFF, + c = (versionHash >> 8) & 0xFF, + d = versionHash & 0xFF; + version = (byte)~(a ^ b ^ c ^ d); + } + + /// + /// Saves a wz file to the disk, AKA repacking. + /// + /// Path to the output wz file + public void SaveToDisk(string path) { + WzIv = MapleVersion.EncryptionKey(); + CreateVersionHash(); + WzDirectory.SetHash(versionHash); + string tempFile = Path.GetFileNameWithoutExtension(path) + ".TEMP"; + File.Create(tempFile).Close(); + WzDirectory.GenerateDataFile(tempFile); + WzTool.StringCache.Clear(); + uint totalLen = WzDirectory.GetImgOffsets(WzDirectory.GetOffsets(Header.FStart + 2)); + WzBinaryWriter wzWriter = new WzBinaryWriter(File.Create(path), WzIv); + wzWriter.Hash = (uint)versionHash; + Header.FSize = totalLen - Header.FStart; + for (int i = 0; i < 4; i++) + wzWriter.Write((byte)Header.Ident[i]); + wzWriter.Write((long)Header.FSize); + wzWriter.Write(Header.FStart); + wzWriter.WriteNullTerminatedString(Header.Copyright); + long extraHeaderLength = Header.FStart - wzWriter.BaseStream.Position; + if (extraHeaderLength > 0) { + wzWriter.Write(new byte[(int)extraHeaderLength]); } - else WzIv = version.EncryptionKey(); - } - - /// - /// Parses the wz file, if the wz file is a list.wz file, WzDirectory will be a WzListDirectory, if not, it'll simply be a WzDirectory - /// - public void ParseWzFile() - { - if (mapleVersion == WzMapleVersion.GENERATE) - throw new InvalidOperationException("Cannot call ParseWzFile() if WZ file type is GENERATE"); - ParseMainWzDirectory(); - GC.Collect(); - GC.WaitForPendingFinalizers(); - } - - public void ParseWzFile(byte[] WzIv) - { - if (mapleVersion != WzMapleVersion.GENERATE) - throw new InvalidOperationException( - "Cannot call ParseWzFile(byte[] generateKey) if WZ file type is not GENERATE"); - this.WzIv = WzIv; - ParseMainWzDirectory(); - GC.Collect(); - GC.WaitForPendingFinalizers(); - } - - internal void ParseMainWzDirectory() - { - if (this.path == null) - { - Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Path is null"); - return; - } - - WzBinaryReader reader = new WzBinaryReader(File.Open(this.path, FileMode.Open, FileAccess.Read, FileShare.Read), WzIv); - - this.Header = new WzHeader(); - this.Header.Ident = reader.ReadString(4); - this.Header.FSize = reader.ReadUInt64(); - this.Header.FStart = reader.ReadUInt32(); - this.Header.Copyright = reader.ReadNullTerminatedString(); - reader.ReadBytes((int)(Header.FStart - reader.BaseStream.Position)); - reader.Header = this.Header; - this.version = reader.ReadInt16(); - if (fileVersion == -1) - { - for (int j = 0; j < short.MaxValue; j++) - { - this.fileVersion = (short)j; - this.versionHash = GetVersionHash(version, fileVersion); - if (this.versionHash != 0) - { - reader.Hash = this.versionHash; - long position = reader.BaseStream.Position; - WzDirectory testDirectory = null; - try - { - testDirectory = new WzDirectory(reader, this.name, this.versionHash, this.WzIv, this); - testDirectory.ParseDirectory(); - } - catch - { - reader.BaseStream.Position = position; - continue; - } - WzImage testImage = testDirectory.GetChildImages()[0]; - - try - { - reader.BaseStream.Position = testImage.Offset; - byte checkByte = reader.ReadByte(); - reader.BaseStream.Position = position; - testDirectory.Dispose(); - switch (checkByte) - { - case 0x73: - case 0x1b: - { - WzDirectory directory = new WzDirectory(reader, this.name, this.versionHash, this.WzIv, this); - directory.ParseDirectory(); - this.wzDir = directory; - return; - } - } - reader.BaseStream.Position = position; - } - catch - { - reader.BaseStream.Position = position; - } - } - } - throw new Exception("Error with game version hash : The specified game version is incorrect and WzLib was unable to determine the version itself"); - } - else - { - this.versionHash = GetVersionHash(version, fileVersion); - reader.Hash = this.versionHash; - WzDirectory directory = new WzDirectory(reader, this.name, this.versionHash, this.WzIv, this); - directory.ParseDirectory(); - this.wzDir = directory; - } - } - - private uint GetVersionHash(int encver, int realver) - { - int EncryptedVersionNumber = encver; - int VersionNumber = realver; - int VersionHash = 0; - int DecryptedVersionNumber = 0; - string VersionNumberStr; - int a = 0, b = 0, c = 0, d = 0, l = 0; - - VersionNumberStr = VersionNumber.ToString(); - - l = VersionNumberStr.Length; - for (int i = 0; i < l; i++) - { - VersionHash = (32 * VersionHash) + (int)VersionNumberStr[i] + 1; - } - a = (VersionHash >> 24) & 0xFF; - b = (VersionHash >> 16) & 0xFF; - c = (VersionHash >> 8) & 0xFF; - d = VersionHash & 0xFF; - DecryptedVersionNumber = (0xff ^ a ^ b ^ c ^ d); - - if (EncryptedVersionNumber == DecryptedVersionNumber) - { - return Convert.ToUInt32(VersionHash); - } - else - { - return 0; - } - } - - private void CreateVersionHash() - { - versionHash = 0; - foreach (char ch in fileVersion.ToString()) - { - versionHash = (versionHash * 32) + (byte)ch + 1; - } - uint a = (versionHash >> 24) & 0xFF, - b = (versionHash >> 16) & 0xFF, - c = (versionHash >> 8) & 0xFF, - d = versionHash & 0xFF; - version = (byte)~(a ^ b ^ c ^ d); - } - - /// - /// Saves a wz file to the disk, AKA repacking. - /// - /// Path to the output wz file - public void SaveToDisk(string path) - { - WzIv = mapleVersion.EncryptionKey(); - CreateVersionHash(); - wzDir.SetHash(versionHash); - string tempFile = Path.GetFileNameWithoutExtension(path) + ".TEMP"; - File.Create(tempFile).Close(); - wzDir.GenerateDataFile(tempFile); - WzTool.StringCache.Clear(); - uint totalLen = wzDir.GetImgOffsets(wzDir.GetOffsets(Header.FStart + 2)); - WzBinaryWriter wzWriter = new WzBinaryWriter(File.Create(path), WzIv); - wzWriter.Hash = (uint)versionHash; - Header.FSize = totalLen - Header.FStart; - for (int i = 0; i < 4; i++) - wzWriter.Write((byte)Header.Ident[i]); - wzWriter.Write((long)Header.FSize); - wzWriter.Write(Header.FStart); - wzWriter.WriteNullTerminatedString(Header.Copyright); - long extraHeaderLength = Header.FStart - wzWriter.BaseStream.Position; - if (extraHeaderLength > 0) - { - wzWriter.Write(new byte[(int)extraHeaderLength]); - } - wzWriter.Write(version); - wzWriter.Header = Header; - wzDir.SaveDirectory(wzWriter); - wzWriter.StringCache.Clear(); - FileStream fs = File.OpenRead(tempFile); - wzDir.SaveImages(wzWriter, fs); - fs.Close(); - File.Delete(tempFile); - wzWriter.StringCache.Clear(); - wzWriter.Close(); + wzWriter.Write(version); + wzWriter.Header = Header; + WzDirectory.SaveDirectory(wzWriter); + wzWriter.StringCache.Clear(); + FileStream fs = File.OpenRead(tempFile); + WzDirectory.SaveImages(wzWriter, fs); + fs.Close(); + File.Delete(tempFile); + wzWriter.StringCache.Clear(); + wzWriter.Close(); GC.Collect(); GC.WaitForPendingFinalizers(); - } - - public void ExportXml(string path, bool oneFile) - { - if (oneFile) - { - FileStream fs = File.Create(path + "/" + this.name + ".xml"); - StreamWriter writer = new StreamWriter(fs); - - int level = 0; - writer.WriteLine(XmlUtil.Indentation(level) + XmlUtil.OpenNamedTag("WzFile", this.name, true)); - this.wzDir.ExportXml(writer, oneFile, level, false); - writer.WriteLine(XmlUtil.Indentation(level) + XmlUtil.CloseTag("WzFile")); - - writer.Close(); - } - else - { - throw new Exception("Under Construction"); - } - } - - /// - /// Returns an array of objects from a given path. Wild cards are supported - /// For example : - /// GetObjectsFromPath("Map.wz/Map0/*"); - /// Would return all the objects (in this case images) from the sub directory Map0 - /// - /// The path to the object(s) - /// An array of IWzObjects containing the found objects - public List GetObjectsFromWildcardPath(string path) - { - if (path.ToLower() == name.ToLower()) + } + + public void ExportXml(string path, bool oneFile) { + if (oneFile) { + FileStream fs = File.Create(path + "/" + this.Name + ".xml"); + StreamWriter writer = new StreamWriter(fs); + + int level = 0; + writer.WriteLine(XmlUtil.Indentation(level) + XmlUtil.OpenNamedTag("WzFile", this.Name, true)); + this.WzDirectory.ExportXml(writer, oneFile, level, false); + writer.WriteLine(XmlUtil.Indentation(level) + XmlUtil.CloseTag("WzFile")); + + writer.Close(); + } else { + throw new Exception("Under Construction"); + } + } + + /// + /// Returns an array of objects from a given path. Wild cards are supported + /// For example : + /// GetObjectsFromPath("Map.wz/Map0/*"); + /// Would return all the objects (in this case images) from the sub directory Map0 + /// + /// The path to the object(s) + /// An array of IWzObjects containing the found objects + public List GetObjectsFromWildcardPath(string path) { + if (path.ToLower() == Name.ToLower()) return new List { WzDirectory }; - else if (path == "*") - { + else if (path == "*") { List fullList = new List(); fullList.Add(WzDirectory); fullList.AddRange(GetObjectsFromDirectory(WzDirectory)); return fullList; - } - else if (!path.Contains("*")) + } else if (!path.Contains("*")) return new List { GetObjectFromPath(path) }; - string[] seperatedNames = path.Split("/".ToCharArray()); - if (seperatedNames.Length == 2 && seperatedNames[1] == "*") - return GetObjectsFromDirectory(WzDirectory); - List objList = new List(); - foreach (WzImage img in WzDirectory.WzImages) - foreach (string spath in GetPathsFromImage(img, name + "/" + img.Name)) - if (strMatch(path, spath)) - objList.Add(GetObjectFromPath(spath)); - foreach (WzDirectory dir in wzDir.WzDirectories) - foreach (string spath in GetPathsFromDirectory(dir, name + "/" + dir.Name)) - if (strMatch(path, spath)) - objList.Add(GetObjectFromPath(spath)); - GC.Collect(); - GC.WaitForPendingFinalizers(); - return objList; - } - - public List GetObjectsFromRegexPath(string path) - { - if (path.ToLower() == name.ToLower()) + string[] seperatedNames = path.Split("/".ToCharArray()); + if (seperatedNames.Length == 2 && seperatedNames[1] == "*") + return GetObjectsFromDirectory(WzDirectory); + List objList = new List(); + foreach (WzImage img in WzDirectory.WzImages) + foreach (string spath in GetPathsFromImage(img, Name + "/" + img.Name)) + if (strMatch(path, spath)) + objList.Add(GetObjectFromPath(spath)); + foreach (WzDirectory dir in WzDirectory.WzDirectories) + foreach (string spath in GetPathsFromDirectory(dir, Name + "/" + dir.Name)) + if (strMatch(path, spath)) + objList.Add(GetObjectFromPath(spath)); + GC.Collect(); + GC.WaitForPendingFinalizers(); + return objList; + } + + public List GetObjectsFromRegexPath(string path) { + if (path.ToLower() == Name.ToLower()) return new List { WzDirectory }; - List objList = new List(); - foreach (WzImage img in WzDirectory.WzImages) - foreach (string spath in GetPathsFromImage(img, name + "/" + img.Name)) - if (Regex.Match(spath, path).Success) - objList.Add(GetObjectFromPath(spath)); - foreach (WzDirectory dir in wzDir.WzDirectories) - foreach (string spath in GetPathsFromDirectory(dir, name + "/" + dir.Name)) - if (Regex.Match(spath, path).Success) - objList.Add(GetObjectFromPath(spath)); - GC.Collect(); - GC.WaitForPendingFinalizers(); - return objList; - } - - public List GetObjectsFromDirectory(WzDirectory dir) - { - List objList = new List(); - foreach (WzImage img in dir.WzImages) - { - objList.Add(img); - objList.AddRange(GetObjectsFromImage(img)); - } - foreach (WzDirectory subdir in dir.WzDirectories) - { - objList.Add(subdir); - objList.AddRange(GetObjectsFromDirectory(subdir)); - } - return objList; - } - - public List GetObjectsFromImage(WzImage img) - { - List objList = new List(); - foreach (WzImageProperty prop in img.WzProperties) - { - objList.Add(prop); - objList.AddRange(GetObjectsFromProperty(prop)); - } - return objList; - } - - public List GetObjectsFromProperty(WzImageProperty prop) - { - List objList = new List(); - switch (prop.PropertyType) - { - case WzPropertyType.Canvas: - foreach (WzImageProperty canvasProp in ((WzCanvasProperty)prop).WzProperties) - objList.AddRange(GetObjectsFromProperty(canvasProp)); - objList.Add(((WzCanvasProperty)prop).PngProperty); - break; - case WzPropertyType.Convex: + List objList = new List(); + foreach (WzImage img in WzDirectory.WzImages) + foreach (string spath in GetPathsFromImage(img, Name + "/" + img.Name)) + if (Regex.Match(spath, path).Success) + objList.Add(GetObjectFromPath(spath)); + foreach (WzDirectory dir in WzDirectory.WzDirectories) + foreach (string spath in GetPathsFromDirectory(dir, Name + "/" + dir.Name)) + if (Regex.Match(spath, path).Success) + objList.Add(GetObjectFromPath(spath)); + GC.Collect(); + GC.WaitForPendingFinalizers(); + return objList; + } + + public List GetObjectsFromDirectory(WzDirectory dir) { + List objList = new List(); + foreach (WzImage img in dir.WzImages) { + objList.Add(img); + objList.AddRange(GetObjectsFromImage(img)); + } + foreach (WzDirectory subdir in dir.WzDirectories) { + objList.Add(subdir); + objList.AddRange(GetObjectsFromDirectory(subdir)); + } + return objList; + } + + public List GetObjectsFromImage(WzImage img) { + List objList = new List(); + foreach (WzImageProperty prop in img.WzProperties) { + objList.Add(prop); + objList.AddRange(GetObjectsFromProperty(prop)); + } + return objList; + } + + public List GetObjectsFromProperty(WzImageProperty prop) { + List objList = new List(); + switch (prop.PropertyType) { + case WzPropertyType.Canvas: + foreach (WzImageProperty canvasProp in ((WzCanvasProperty)prop).WzProperties) + objList.AddRange(GetObjectsFromProperty(canvasProp)); + objList.Add(((WzCanvasProperty)prop).PngProperty); + break; + case WzPropertyType.Convex: foreach (WzImageProperty exProp in ((WzConvexProperty)prop).WzProperties) - objList.AddRange(GetObjectsFromProperty(exProp)); - break; - case WzPropertyType.SubProperty: - foreach (WzImageProperty subProp in ((WzSubProperty)prop).WzProperties) - objList.AddRange(GetObjectsFromProperty(subProp)); - break; - case WzPropertyType.Vector: - objList.Add(((WzVectorProperty)prop).X); - objList.Add(((WzVectorProperty)prop).Y); - break; - } - return objList; - } - - internal List GetPathsFromDirectory(WzDirectory dir, string curPath) - { - List objList = new List(); - foreach (WzImage img in dir.WzImages) - { - objList.Add(curPath + "/" + img.Name); - - objList.AddRange(GetPathsFromImage(img, curPath + "/" + img.Name)); - } - foreach (WzDirectory subdir in dir.WzDirectories) - { - objList.Add(curPath + "/" + subdir.Name); - objList.AddRange(GetPathsFromDirectory(subdir, curPath + "/" + subdir.Name)); - } - return objList; - } - - internal List GetPathsFromImage(WzImage img, string curPath) - { - List objList = new List(); - foreach (WzImageProperty prop in img.WzProperties) - { - objList.Add(curPath + "/" + prop.Name); - objList.AddRange(GetPathsFromProperty(prop, curPath + "/" + prop.Name)); - } - return objList; - } - - internal List GetPathsFromProperty(WzImageProperty prop, string curPath) - { - List objList = new List(); - switch (prop.PropertyType) - { - case WzPropertyType.Canvas: - foreach (WzImageProperty canvasProp in ((WzCanvasProperty)prop).WzProperties) - { - objList.Add(curPath + "/" + canvasProp.Name); - objList.AddRange(GetPathsFromProperty(canvasProp, curPath + "/" + canvasProp.Name)); - } - objList.Add(curPath + "/PNG"); - break; - case WzPropertyType.Convex: - foreach (WzImageProperty exProp in ((WzConvexProperty)prop).WzProperties) - { - objList.Add(curPath + "/" + exProp.Name); - objList.AddRange(GetPathsFromProperty(exProp, curPath + "/" + exProp.Name)); - } - break; - case WzPropertyType.SubProperty: - foreach (WzImageProperty subProp in ((WzSubProperty)prop).WzProperties) - { - objList.Add(curPath + "/" + subProp.Name); - objList.AddRange(GetPathsFromProperty(subProp, curPath + "/" + subProp.Name)); - } - break; - case WzPropertyType.Vector: - objList.Add(curPath + "/X"); - objList.Add(curPath + "/Y"); - break; - } - return objList; - } - - public WzObject GetObjectFromPath(string path) - { - string[] seperatedPath = path.Split("/".ToCharArray()); - if (seperatedPath[0].ToLower() != wzDir.name.ToLower() && seperatedPath[0].ToLower() != wzDir.name.Substring(0, wzDir.name.Length - 3).ToLower()) + objList.AddRange(GetObjectsFromProperty(exProp)); + break; + case WzPropertyType.SubProperty: + foreach (WzImageProperty subProp in ((WzSubProperty)prop).WzProperties) + objList.AddRange(GetObjectsFromProperty(subProp)); + break; + case WzPropertyType.Vector: + objList.Add(((WzVectorProperty)prop).X); + objList.Add(((WzVectorProperty)prop).Y); + break; + } + return objList; + } + + internal List GetPathsFromDirectory(WzDirectory dir, string curPath) { + List objList = new List(); + foreach (WzImage img in dir.WzImages) { + objList.Add(curPath + "/" + img.Name); + + objList.AddRange(GetPathsFromImage(img, curPath + "/" + img.Name)); + } + foreach (WzDirectory subdir in dir.WzDirectories) { + objList.Add(curPath + "/" + subdir.Name); + objList.AddRange(GetPathsFromDirectory(subdir, curPath + "/" + subdir.Name)); + } + return objList; + } + + internal List GetPathsFromImage(WzImage img, string curPath) { + List objList = new List(); + foreach (WzImageProperty prop in img.WzProperties) { + objList.Add(curPath + "/" + prop.Name); + objList.AddRange(GetPathsFromProperty(prop, curPath + "/" + prop.Name)); + } + return objList; + } + + internal List GetPathsFromProperty(WzImageProperty prop, string curPath) { + List objList = new List(); + switch (prop.PropertyType) { + case WzPropertyType.Canvas: + foreach (WzImageProperty canvasProp in ((WzCanvasProperty)prop).WzProperties) { + objList.Add(curPath + "/" + canvasProp.Name); + objList.AddRange(GetPathsFromProperty(canvasProp, curPath + "/" + canvasProp.Name)); + } + objList.Add(curPath + "/PNG"); + break; + case WzPropertyType.Convex: + foreach (WzImageProperty exProp in ((WzConvexProperty)prop).WzProperties) { + objList.Add(curPath + "/" + exProp.Name); + objList.AddRange(GetPathsFromProperty(exProp, curPath + "/" + exProp.Name)); + } + break; + case WzPropertyType.SubProperty: + foreach (WzImageProperty subProp in ((WzSubProperty)prop).WzProperties) { + objList.Add(curPath + "/" + subProp.Name); + objList.AddRange(GetPathsFromProperty(subProp, curPath + "/" + subProp.Name)); + } + break; + case WzPropertyType.Vector: + objList.Add(curPath + "/X"); + objList.Add(curPath + "/Y"); + break; + } + return objList; + } + + public WzObject GetObjectFromPath(string path) { + string[] seperatedPath = path.Split("/".ToCharArray()); + if (seperatedPath[0].ToLower() != WzDirectory.name.ToLower() && seperatedPath[0].ToLower() != WzDirectory.name.Substring(0, WzDirectory.name.Length - 3).ToLower()) return null; - if (seperatedPath.Length == 1) - return WzDirectory; - WzObject curObj = WzDirectory; - for (int i = 1; i < seperatedPath.Length; i++) - { - if (curObj == null) - { - return null; - } - switch (curObj.ObjectType) - { - case WzObjectType.Directory: - curObj = ((WzDirectory)curObj)[seperatedPath[i]]; - continue; - case WzObjectType.Image: - curObj = ((WzImage)curObj)[seperatedPath[i]]; - continue; - case WzObjectType.Property: - switch (((WzImageProperty)curObj).PropertyType) - { - case WzPropertyType.Canvas: - curObj = ((WzCanvasProperty)curObj)[seperatedPath[i]]; - continue; - case WzPropertyType.Convex: - curObj = ((WzConvexProperty)curObj)[seperatedPath[i]]; - continue; - case WzPropertyType.SubProperty: - curObj = ((WzSubProperty)curObj)[seperatedPath[i]]; - continue; - case WzPropertyType.Vector: - if (seperatedPath[i] == "X") - return ((WzVectorProperty)curObj).X; - else if (seperatedPath[i] == "Y") - return ((WzVectorProperty)curObj).Y; - else - return null; - default: // Wut? - return null; - } - } - } - if (curObj == null) - { - return null; - } - return curObj; - } - - internal bool strMatch(string strWildCard, string strCompare) - { - if (strWildCard.Length == 0) return strCompare.Length == 0; - if (strCompare.Length == 0) return false; - if (strWildCard[0] == '*' && strWildCard.Length > 1) - for (int index = 0; index < strCompare.Length; index++) - { - if (strMatch(strWildCard.Substring(1), strCompare.Substring(index))) - return true; - } - else if (strWildCard[0] == '*') - return true; - else if (strWildCard[0] == strCompare[0]) - return strMatch(strWildCard.Substring(1), strCompare.Substring(1)); - return false; - } - - public override void Remove() - { + if (seperatedPath.Length == 1) + return WzDirectory; + WzObject curObj = WzDirectory; + for (int i = 1; i < seperatedPath.Length; i++) { + if (curObj == null) { + return null; + } + switch (curObj.ObjectType) { + case WzObjectType.Directory: + curObj = ((WzDirectory)curObj)[seperatedPath[i]]; + continue; + case WzObjectType.Image: + curObj = ((WzImage)curObj)[seperatedPath[i]]; + continue; + case WzObjectType.Property: + switch (((WzImageProperty)curObj).PropertyType) { + case WzPropertyType.Canvas: + curObj = ((WzCanvasProperty)curObj)[seperatedPath[i]]; + continue; + case WzPropertyType.Convex: + curObj = ((WzConvexProperty)curObj)[seperatedPath[i]]; + continue; + case WzPropertyType.SubProperty: + curObj = ((WzSubProperty)curObj)[seperatedPath[i]]; + continue; + case WzPropertyType.Vector: + if (seperatedPath[i] == "X") + return ((WzVectorProperty)curObj).X; + else if (seperatedPath[i] == "Y") + return ((WzVectorProperty)curObj).Y; + else + return null; + default: // Wut? + return null; + } + } + } + return curObj; + } + + internal bool strMatch(string strWildCard, string strCompare) { + if (strWildCard.Length == 0) return strCompare.Length == 0; + if (strCompare.Length == 0) return false; + if (strWildCard[0] == '*' && strWildCard.Length > 1) + for (int index = 0; index < strCompare.Length; index++) { + if (strMatch(strWildCard.Substring(1), strCompare.Substring(index))) + return true; + } + else if (strWildCard[0] == '*') + return true; + else if (strWildCard[0] == strCompare[0]) + return strMatch(strWildCard.Substring(1), strCompare.Substring(1)); + return false; + } + + public override void Remove() { Dispose(); } - } + } } \ No newline at end of file diff --git a/MapleLib/WzLib/WzImage.cs b/MapleLib/WzLib/WzImage.cs index 20869e2..f2b0f9a 100644 --- a/MapleLib/WzLib/WzImage.cs +++ b/MapleLib/WzLib/WzImage.cs @@ -14,35 +14,31 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * You should have received a copy of the GNU General Public License along with this program. If not, see .*/ -using System.Collections.Generic; -using System.IO; -using System; using MapleLib.WzLib.Util; using MapleLib.WzLib.WzProperties; +using System; +using System.Collections.Generic; +using System.IO; -namespace MapleLib.WzLib -{ - /// - /// A .img contained in a wz directory - /// - public class WzImage : WzObject, IPropertyContainer - { - //TODO: nest wzproperties in a wzsubproperty inside of WzImage - - #region Fields - internal bool parsed = false; - internal string name; - internal int size, checksum; - internal uint offset = 0; - internal WzBinaryReader reader; - internal List properties = new List(); - internal WzObject parent; - internal int blockStart = 0; - internal long tempFileStart = 0; - internal long tempFileEnd = 0; +namespace MapleLib.WzLib { + /// + /// A .img contained in a wz directory + /// + public class WzImage : WzObject, IPropertyContainer { + //TODO: nest wzproperties in a wzsubproperty inside of WzImage + #region Fields + internal bool parsed = false; + internal string name; + internal int size, checksum; + internal uint offset = 0; + internal WzBinaryReader reader; + internal WzObject parent; + internal int blockStart = 0; + internal long tempFileStart = 0; + internal long tempFileEnd = 0; internal bool changed = false; internal bool parseEverything = false; - #endregion + #endregion #region Constructors\Destructors /// @@ -53,32 +49,27 @@ public WzImage() { } /// Creates a WzImage with the given name /// /// The name of the image - public WzImage(string name) - { + public WzImage(string name) { this.name = name; } - public WzImage(string name, Stream dataStream, WzMapleVersion mapleVersion) - { + public WzImage(string name, Stream dataStream, WzMapleVersion mapleVersion) { this.name = name; this.reader = new WzBinaryReader(dataStream, mapleVersion.EncryptionKey()); } - internal WzImage(string name, WzBinaryReader reader) - { + internal WzImage(string name, WzBinaryReader reader) { this.name = name; this.reader = reader; this.blockStart = (int)reader.BaseStream.Position; } - public override void Dispose() - { + public override void Dispose() { name = null; reader = null; - if (properties != null) - { - foreach (WzImageProperty prop in properties) + if (Properties != null) { + foreach (WzImageProperty prop in Properties) prop.Dispose(); - properties.Clear(); - properties = null; + Properties.Clear(); + Properties = null; } } #endregion @@ -88,85 +79,77 @@ public override void Dispose() /// The parent of the object /// public override WzObject Parent { get { return parent; } internal set { parent = value; } } - /// - /// The name of the image - /// - public override string Name { get { return name; } set { name = value; } } + /// + /// The name of the image + /// + public override string Name { get { return name; } set { name = value; } } public override WzFile WzFileParent { get { return Parent != null ? Parent.WzFileParent : null; } } - /// - /// Is the object parsed - /// + /// + /// Is the object parsed + /// public bool Parsed { get { return parsed; } set { parsed = value; } } /// /// Was the image changed /// public bool Changed { get { return changed; } set { changed = value; } } - /// - /// The size in the wz file of the image - /// - public int BlockSize { get { return size; } set { size = value; } } - /// - /// The checksum of the image - /// - public int Checksum { get { return checksum; } set { checksum = value; } } - /// - /// The offset of the image - /// - public uint Offset { get { return offset; } set { offset = value; } } - public int BlockStart { get { return blockStart; } } + /// + /// The size in the wz file of the image + /// + public int BlockSize { get { return size; } set { size = value; } } + /// + /// The checksum of the image + /// + public int Checksum { get { return checksum; } set { checksum = value; } } + /// + /// The offset of the image + /// + public uint Offset { get { return offset; } set { offset = value; } } + public int BlockStart { get { return blockStart; } } /// /// The WzObjectType of the image /// public override WzObjectType ObjectType { get { if (reader != null) if (!parsed) ParseImage(); return WzObjectType.Image; } } - /// - /// The properties contained in the image - /// - public List WzProperties - { - get - { - if (reader != null && !parsed) - { - ParseImage(); - } - return properties; - } - } + /// + /// The properties contained in the image + /// + public List WzProperties { + get { + if (reader != null && !parsed) { + ParseImage(); + } + return Properties; + } + } - public WzImage DeepClone() - { + public WzImage DeepClone() { if (reader != null && !parsed) ParseImage(); WzImage clone = new WzImage(name); clone.changed = true; - foreach (WzImageProperty prop in properties) + foreach (WzImageProperty prop in Properties) clone.AddProperty(prop.DeepClone()); return clone; } - /// - /// Gets a wz property by it's name - /// - /// The name of the property - /// The wz property with the specified name - public new WzImageProperty this[string name] - { - get - { - if (reader != null) if (!parsed) ParseImage(); - foreach (WzImageProperty iwp in properties) + /// + /// Gets a wz property by it's name + /// + /// The name of the property + /// The wz property with the specified name + public new WzImageProperty this[string name] { + get { + if (reader != null) if (!parsed) ParseImage(true); + foreach (WzImageProperty iwp in Properties) if (iwp.Name.ToLower() == name.ToLower()) return iwp; - return null; - } - set - { - if (value != null) - { + return null; + } + set { + if (value != null) { value.Name = name; AddProperty(value); } } - } + } #endregion #region Custom Members @@ -175,31 +158,25 @@ public WzImage DeepClone() /// /// path to object /// the selected WzImageProperty - public WzImageProperty GetFromPath(string path) - { + public WzImageProperty GetFromPath(string path) { if (reader != null) if (!parsed) ParseImage(); string[] segments = path.Split(new char[1] { '/' }, System.StringSplitOptions.RemoveEmptyEntries); - if (segments[0] == "..") - { + if (segments[0] == "..") { return null; } WzImageProperty ret = null; - for (int x = 0; x < segments.Length; x++) - { + for (int x = 0; x < segments.Length; x++) { bool foundChild = false; - foreach (WzImageProperty iwp in (ret == null ? this.properties : ret.WzProperties)) - { - if (iwp.Name == segments[x]) - { + foreach (WzImageProperty iwp in (ret == null ? this.Properties : ret.WzProperties)) { + if (iwp.Name == segments[x]) { ret = iwp; foundChild = true; break; } } - if (!foundChild) - { + if (!foundChild) { return null; } } @@ -210,16 +187,13 @@ public WzImageProperty GetFromPath(string path) /// Adds a property to the image /// /// Property to add - public void AddProperty(WzImageProperty prop) - { + public void AddProperty(WzImageProperty prop) { prop.Parent = this; if (reader != null && !parsed) ParseImage(); - properties.Add(prop); + Properties.Add(prop); } - public void AddProperties(List props) - { - foreach (WzImageProperty prop in props) - { + public void AddProperties(List props) { + foreach (WzImageProperty prop in props) { AddProperty(prop); } } @@ -227,20 +201,21 @@ public void AddProperties(List props) /// Removes a property by name /// /// The name of the property to remove - public void RemoveProperty(WzImageProperty prop) - { + public void RemoveProperty(WzImageProperty prop) { if (reader != null && !parsed) ParseImage(); prop.Parent = null; - properties.Remove(prop); + Properties.Remove(prop); + } + public void ClearProperties() { + foreach (WzImageProperty prop in Properties) prop.Parent = null; + Properties.Clear(); } - public void ClearProperties() - { - foreach (WzImageProperty prop in properties) prop.Parent = null; - properties.Clear(); + + public override string ToString() { + return string.Format("WzSubProperty('{0}')", Name); } - public override void Remove() - { + public override void Remove() { ((WzDirectory)Parent).RemoveImage(this); } #endregion @@ -250,62 +225,38 @@ public override void Remove() /// Parses the image from the wz filetod /// /// The BinaryReader that is currently reading the wz file - public void ParseImage(bool parseEverything) - { + public void ParseImage(bool parseEverything = false) { if (Parsed) return; else if (Changed) { Parsed = true; return; } this.parseEverything = parseEverything; - long originalPos = reader.BaseStream.Position; reader.BaseStream.Position = offset; byte b = reader.ReadByte(); if (b != 0x73 || reader.ReadString() != "Property" || reader.ReadUInt16() != 0) return; - properties.AddRange(WzImageProperty.ParsePropertyList(offset, reader, this, this)); + Properties.AddRange(WzImageProperty.ParsePropertyList(offset, reader, this, this)); parsed = true; } - /// - /// Parses the image from the wz filetod - /// - /// The BinaryReader that is currently reading the wz file - public void ParseImage() - { - if (Parsed) return; - else if (Changed) { Parsed = true; return; } - this.parseEverything = false; - long originalPos = reader.BaseStream.Position; - reader.BaseStream.Position = offset; - byte b = reader.ReadByte(); - if (b != 0x73 || reader.ReadString() != "Property" || reader.ReadUInt16() != 0) - return; - properties.AddRange(WzImageProperty.ParsePropertyList(offset, reader, this, this)); - parsed = true; - } + public byte[] DataBlock { + get { + byte[] blockData = null; + if (reader != null && size > 0) { + blockData = reader.ReadBytes(size); + reader.BaseStream.Position = blockStart; + } + return blockData; + } + } - public byte[] DataBlock - { - get - { - byte[] blockData = null; - if (reader != null && size > 0) - { - blockData = reader.ReadBytes(size); - reader.BaseStream.Position = blockStart; - } - return blockData; - } - } + internal List Properties { get; set; } = new List(); - public void UnparseImage() - { - parsed = false; - this.properties = new List(); - } + public void UnparseImage() { + parsed = false; + this.Properties = new List(); + } - internal void SaveImage(WzBinaryWriter writer) - { - if (changed) - { + internal void SaveImage(WzBinaryWriter writer) { + if (changed) { if (reader != null && !parsed) ParseImage(); WzSubProperty imgProp = new WzSubProperty(); long startPos = writer.BaseStream.Position; @@ -313,29 +264,23 @@ internal void SaveImage(WzBinaryWriter writer) imgProp.WriteValue(writer); writer.StringCache.Clear(); size = (int)(writer.BaseStream.Position - startPos); - } - else - { + } else { long pos = reader.BaseStream.Position; reader.BaseStream.Position = offset; writer.Write(reader.ReadBytes(size)); reader.BaseStream.Position = pos; } - } + } - public void ExportXml(StreamWriter writer, bool oneFile, int level) - { - if (oneFile) - { - writer.WriteLine(XmlUtil.Indentation(level) + XmlUtil.OpenNamedTag("WzImage", this.name, true)); - WzImageProperty.DumpPropertyList(writer, level, WzProperties); - writer.WriteLine(XmlUtil.Indentation(level) + XmlUtil.CloseTag("WzImage")); - } - else - { - throw new Exception("Under Construction"); - } - } + public void ExportXml(StreamWriter writer, bool oneFile, int level) { + if (oneFile) { + writer.WriteLine(XmlUtil.Indentation(level) + XmlUtil.OpenNamedTag("WzImage", this.name, true)); + WzImageProperty.DumpPropertyList(writer, level, WzProperties); + writer.WriteLine(XmlUtil.Indentation(level) + XmlUtil.CloseTag("WzImage")); + } else { + throw new Exception("Under Construction"); + } + } #endregion - } + } } \ No newline at end of file diff --git a/MapleLib/WzLib/WzObject.cs b/MapleLib/WzLib/WzObject.cs index b7dbec2..4beb40a 100644 --- a/MapleLib/WzLib/WzObject.cs +++ b/MapleLib/WzLib/WzObject.cs @@ -18,72 +18,51 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the using System.Drawing; using MapleLib.WzLib.WzProperties; -namespace MapleLib.WzLib -{ - /// - /// An abstract class for wz objects - /// - public abstract class WzObject : IDisposable - { - private object tag = null; - private object tag2 = null; - private object tag3 = null; - - public abstract void Dispose(); - - /// - /// The name of the object - /// - public abstract string Name { get; set; } - /// - /// The WzObjectType of the object - /// - public abstract WzObjectType ObjectType { get; } - /// - /// Returns the parent object - /// - public abstract WzObject Parent { get; internal set; } +namespace MapleLib.WzLib { + /// + /// An abstract class for wz objects + /// + public abstract class WzObject : IDisposable { + /// + /// The name of the object + /// + public abstract string Name { get; set; } + /// + /// The WzObjectType of the object + /// + public abstract WzObjectType ObjectType { get; } + /// + /// Returns the parent object + /// + public abstract WzObject Parent { get; internal set; } /// /// Returns the parent WZ File /// public abstract WzFile WzFileParent { get; } - public WzObject this[string name] - { - get - { - if (this is WzFile) - { - return ((WzFile)this)[name]; - } - else if (this is WzDirectory) - { - return ((WzDirectory)this)[name]; - } - else if (this is WzImage) - { - return ((WzImage)this)[name]; - } - else if (this is WzImageProperty) - { - return ((WzImageProperty)this)[name]; - } - else - { - throw new NotImplementedException(); + public WzObject this[string name] { + get { + switch (this) { + case WzFile f: + return f[name]; + case WzDirectory d: + return d[name]; + case WzImage i: + return i[name]; + case WzImageProperty p: + return p[name]; + default: + throw new NotImplementedException(string.Format("cannot index WzObject of type: '{0}'", GetType().ToString())); } } } - public string FullPath - { - get - { + public string FullPath { + get { if (this is WzFile) return ((WzFile)this).WzDirectory.Name; string result = this.Name; WzObject currObj = this; - while (currObj.Parent != null) - { + while (currObj.Parent != null) { currObj = currObj.Parent; result = currObj.Name + @"\" + result; } @@ -94,82 +73,59 @@ public string FullPath /// /// Used in HaCreator to save already parsed images /// - public virtual object HCTag - { - get { return tag; } - set { tag = value; } - } + public virtual object HCTag { get; set; } /// /// Used in HaCreator's MapSimulator to save already parsed textures /// - public virtual object MSTag - { - get { return tag2; } - set { tag2 = value; } - } + public virtual object MSTag { get; set; } /// /// Used in HaRepacker to save WzNodes /// - public virtual object HRTag - { - get { return tag3; } - set { tag3 = value; } - } - + public virtual object HRTag { get; set; } public virtual object WzValue { get { return null; } } - + public abstract void Dispose(); public abstract void Remove(); //Credits to BluePoop for the idea of using cast overriding //2015 - That is the worst idea ever, removed and replaced with Get* methods #region Cast Values - public virtual int GetInt() - { + public virtual int GetInt() { throw new NotImplementedException(); } - public virtual short GetShort() - { + public virtual short GetShort() { throw new NotImplementedException(); } - public virtual long GetLong() - { + public virtual long GetLong() { throw new NotImplementedException(); } - public virtual float GetFloat() - { + public virtual float GetFloat() { throw new NotImplementedException(); } - public virtual double GetDouble() - { + public virtual double GetDouble() { throw new NotImplementedException(); } - public virtual string GetString() - { + public virtual string GetString() { throw new NotImplementedException(); } - public virtual Point GetPoint() - { + public virtual Point GetPoint() { throw new NotImplementedException(); } - public virtual Bitmap GetBitmap() - { + public virtual Bitmap GetBitmap() { throw new NotImplementedException(); } - public virtual byte[] GetBytes() - { + public virtual byte[] GetBytes() { throw new NotImplementedException(); } #endregion - - } + } } \ No newline at end of file diff --git a/MapleLib/WzLib/WzProperties/WzCanvasProperty.cs b/MapleLib/WzLib/WzProperties/WzCanvasProperty.cs index 41edee9..0fe3775 100644 --- a/MapleLib/WzLib/WzProperties/WzCanvasProperty.cs +++ b/MapleLib/WzLib/WzProperties/WzCanvasProperty.cs @@ -20,29 +20,25 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the using System; using System.Drawing; -namespace MapleLib.WzLib.WzProperties -{ - /// - /// A property that can contain sub properties and has one png image - /// - public class WzCanvasProperty : WzExtended, IPropertyContainer - { - #region Fields - internal List properties = new List(); - internal WzPngProperty imageProp; - internal string name; - internal WzObject parent; - //internal WzImage imgParent; - #endregion +namespace MapleLib.WzLib.WzProperties { + /// + /// A property that can contain sub properties and has one png image + /// + public class WzCanvasProperty : WzExtended, IPropertyContainer { + #region Fields + internal List properties = new List(); + internal WzPngProperty imageProp; + internal string name; + internal WzObject parent; + //internal WzImage imgParent; + #endregion - #region Inherited Members - public override void SetValue(object value) - { + #region Inherited Members + public override void SetValue(object value) { imageProp.SetValue(value); } - public override WzImageProperty DeepClone() - { + public override WzImageProperty DeepClone() { WzCanvasProperty clone = new WzCanvasProperty(name); foreach (WzImageProperty prop in properties) clone.AddProperty(prop.DeepClone()); @@ -50,51 +46,44 @@ public override WzImageProperty DeepClone() return clone; } - public override object WzValue { get { return PngProperty; } } - /// - /// The parent of the object - /// - public override WzObject Parent { get { return parent; } internal set { parent = value; } } - /// - /// The WzPropertyType of the property - /// - public override WzPropertyType PropertyType { get { return WzPropertyType.Canvas; } } - /// - /// The properties contained in this property - /// - public override List WzProperties - { - get - { - return properties; - } - } - /// - /// The name of the property - /// - public override string Name { get { return name; } set { name = value; } } - /// - /// Gets a wz property by it's name - /// - /// The name of the property - /// The wz property with the specified name - public override WzImageProperty this[string name] - { - get - { - if (name == "PNG") - return imageProp; - foreach (WzImageProperty iwp in properties) - if (iwp.Name.ToLower() == name.ToLower()) + public override object WzValue { get { return PngProperty; } } + /// + /// The parent of the object + /// + public override WzObject Parent { get { return parent; } internal set { parent = value; } } + /// + /// The WzPropertyType of the property + /// + public override WzPropertyType PropertyType { get { return WzPropertyType.Canvas; } } + /// + /// The properties contained in this property + /// + public override List WzProperties { + get { + return properties; + } + } + /// + /// The name of the property + /// + public override string Name { get { return name; } set { name = value; } } + /// + /// Gets a wz property by it's name + /// + /// The name of the property + /// The wz property with the specified name + public override WzImageProperty this[string name] { + get { + if (name == "PNG") + return imageProp; + foreach (WzImageProperty iwp in properties) + if (iwp.Name.ToLower() == name.ToLower()) return iwp; - return null; - } - set - { - if (value != null) - { - if (name == "PNG") - { + return null; + } + set { + if (value != null) { + if (name == "PNG") { imageProp = (WzPngProperty)value; return; } @@ -102,187 +91,154 @@ public override WzImageProperty this[string name] AddProperty(value); } } - } + } - public WzImageProperty GetProperty(string name) - { + public WzImageProperty GetProperty(string name) { foreach (WzImageProperty iwp in properties) if (iwp.Name.ToLower() == name.ToLower()) return iwp; return null; } - /// Gets a wz property by a path name - /// - /// path to property - /// the wz property with the specified name - public override WzImageProperty GetFromPath(string path) - { - string[] segments = path.Split(new char[1] { '/' }, System.StringSplitOptions.RemoveEmptyEntries); - if (segments[0] == "..") - { - return ((WzImageProperty)Parent)[path.Substring(name.IndexOf('/') + 1)]; - } - WzImageProperty ret = this; - for (int x = 0; x < segments.Length; x++) - { - bool foundChild = false; - if (segments[x] == "PNG") - { - return imageProp; - } - foreach (WzImageProperty iwp in ret.WzProperties) - { - if (iwp.Name == segments[x]) - { - ret = iwp; - foundChild = true; - break; - } - } - if (!foundChild) - { - return null; - } - } - return ret; - } - public override void WriteValue(MapleLib.WzLib.Util.WzBinaryWriter writer) - { - writer.WriteStringValue("Canvas", 0x73, 0x1B); - writer.Write((byte)0); - if (properties.Count > 0) - { - writer.Write((byte)1); - WzImageProperty.WritePropertyList(writer, properties); - } - else - { - writer.Write((byte)0); - } - writer.WriteCompressedInt(PngProperty.Width); - writer.WriteCompressedInt(PngProperty.Height); - writer.WriteCompressedInt(PngProperty.format); - writer.Write((byte)PngProperty.format2); - writer.Write((Int32)0); + /// Gets a wz property by a path name + /// + /// path to property + /// the wz property with the specified name + public override WzImageProperty GetFromPath(string path) { + string[] segments = path.Split(new char[1] { '/' }, System.StringSplitOptions.RemoveEmptyEntries); + if (segments[0] == "..") { + return ((WzImageProperty)Parent)[path.Substring(name.IndexOf('/') + 1)]; + } + WzImageProperty ret = this; + for (int x = 0; x < segments.Length; x++) { + bool foundChild = false; + if (segments[x] == "PNG") { + return imageProp; + } + foreach (WzImageProperty iwp in ret.WzProperties) { + if (iwp.Name == segments[x]) { + ret = iwp; + foundChild = true; + break; + } + } + if (!foundChild) { + return null; + } + } + return ret; + } + public override void WriteValue(MapleLib.WzLib.Util.WzBinaryWriter writer) { + writer.WriteStringValue("Canvas", 0x73, 0x1B); + writer.Write((byte)0); + if (properties.Count > 0) { + writer.Write((byte)1); + WzImageProperty.WritePropertyList(writer, properties); + } else { + writer.Write((byte)0); + } + writer.WriteCompressedInt(PngProperty.Width); + writer.WriteCompressedInt(PngProperty.Height); + writer.WriteCompressedInt(PngProperty.format); + writer.Write((byte)PngProperty.format2); + writer.Write((Int32)0); byte[] bytes = PngProperty.GetCompressedBytes(false); writer.Write(bytes.Length + 1); - writer.Write((byte)0); + writer.Write((byte)0); writer.Write(bytes); - } - public override void ExportXml(StreamWriter writer, int level) - { - writer.WriteLine(XmlUtil.Indentation(level) + XmlUtil.OpenNamedTag("WzCanvas", this.Name, false, false) + - XmlUtil.Attrib("width", PngProperty.Width.ToString()) + - XmlUtil.Attrib("height", PngProperty.Height.ToString(), true, false)); - WzImageProperty.DumpPropertyList(writer, level, this.WzProperties); - writer.WriteLine(XmlUtil.Indentation(level) + XmlUtil.CloseTag("WzCanvas")); - } - /// - /// Dispose the object - /// - public override void Dispose() - { - name = null; - imageProp.Dispose(); - imageProp = null; - foreach (WzImageProperty prop in properties) - { - prop.Dispose(); - } - properties.Clear(); - properties = null; - } - #endregion + } + public override void ExportXml(StreamWriter writer, int level) { + writer.WriteLine(XmlUtil.Indentation(level) + XmlUtil.OpenNamedTag("WzCanvas", this.Name, false, false) + + XmlUtil.Attrib("width", PngProperty.Width.ToString()) + + XmlUtil.Attrib("height", PngProperty.Height.ToString(), true, false)); + WzImageProperty.DumpPropertyList(writer, level, this.WzProperties); + writer.WriteLine(XmlUtil.Indentation(level) + XmlUtil.CloseTag("WzCanvas")); + } + /// + /// Dispose the object + /// + public override void Dispose() { + name = null; + imageProp.Dispose(); + imageProp = null; + foreach (WzImageProperty prop in properties) { + prop.Dispose(); + } + properties.Clear(); + properties = null; + } + #endregion - #region Custom Members - /// - /// The png image for this canvas property - /// - public WzPngProperty PngProperty { get { return imageProp; } set { imageProp = value; } } - /// - /// Creates a blank WzCanvasProperty - /// - public WzCanvasProperty() { } - /// - /// Creates a WzCanvasProperty with the specified name - /// - /// The name of the property - public WzCanvasProperty(string name) - { - this.name = name; - } - /// - /// Adds a property to the property list of this property - /// - /// The property to add - public void AddProperty(WzImageProperty prop) - { + #region Custom Members + /// + /// The png image for this canvas property + /// + public WzPngProperty PngProperty { get { return imageProp; } set { imageProp = value; } } + /// + /// Creates a blank WzCanvasProperty + /// + public WzCanvasProperty() { } + /// + /// Creates a WzCanvasProperty with the specified name + /// + /// The name of the property + public WzCanvasProperty(string name) { + this.name = name; + } + /// + /// Adds a property to the property list of this property + /// + /// The property to add + public void AddProperty(WzImageProperty prop) { prop.Parent = this; properties.Add(prop); - } - public void AddProperties(List props) - { - foreach (WzImageProperty prop in props) - { - AddProperty(prop); - } - } - /// - /// Remove a property - /// - /// Name of Property - public void RemoveProperty(WzImageProperty prop) - { + } + public void AddProperties(List props) { + foreach (WzImageProperty prop in props) { + AddProperty(prop); + } + } + /// + /// Remove a property + /// + /// Name of Property + public void RemoveProperty(WzImageProperty prop) { prop.Parent = null; - properties.Remove(prop); - } + properties.Remove(prop); + } - /// - /// Clears the list of properties - /// - public void ClearProperties() - { + /// + /// Clears the list of properties + /// + public void ClearProperties() { foreach (WzImageProperty prop in properties) prop.Parent = null; - properties.Clear(); - } - #endregion + properties.Clear(); + } + #endregion #region Cast Values - public override Bitmap GetBitmap() - { - if (this["_inlink"] is WzStringProperty inlink) { - WzObject currentWzObj = this; // first object to work with - while ((currentWzObj = currentWzObj.Parent) != null) { - if (!(currentWzObj is WzImage)) // keep looping if its not a WzImage - continue; + public override Bitmap GetBitmap() { + if (this["_inlink"] is WzStringProperty inlink) { + WzObject currentWzObj = this; // first object to work with + while ((currentWzObj = currentWzObj.Parent) != null) { + if (!(currentWzObj is WzImage)) // keep looping if its not a WzImage + continue; - WzImage wzImageParent = (WzImage)currentWzObj; - WzImageProperty foundProperty = wzImageParent.GetFromPath(inlink.Value); - if (foundProperty != null && foundProperty is WzImageProperty) { - return ((WzImageProperty)foundProperty).GetBitmap(); - } - } - } else if (this["_outlink"] is WzStringProperty outlink) { - WzObject wzObject = WzFileParent.GetObjectFromPath(outlink.Value); - if (wzObject is WzImageProperty imgProperty) { - return imgProperty.GetBitmap(); + WzImage wzImageParent = (WzImage)currentWzObj; + WzImageProperty foundProperty = wzImageParent.GetFromPath(inlink.Value); + if (foundProperty != null && foundProperty is WzImageProperty) { + return foundProperty.GetBitmap(); + } } - //WzObject currentWzObj = this; // first object to work with - //while ((currentWzObj = currentWzObj.Parent) != null) { - // if (!(currentWzObj is WzDirectory)) // keep looping if its not a WzImage - // continue; - - // WzFile wzFileParent = ((WzDirectory)currentWzObj).wzFile; - // WzObject foundProperty = wzFileParent.GetObjectFromPath(outlink.Value); - // if (foundProperty != null && foundProperty is WzImageProperty) { - // return ((WzImageProperty)foundProperty).GetBitmap(); - // } - //} - } + } else if (this["_outlink"] is WzStringProperty outlink) { + WzObject foundProperty = WzFileParent.GetObjectFromPath(outlink.Value); + if (foundProperty is WzImageProperty) { + return foundProperty.GetBitmap(); + } + } return imageProp.GetPNG(false); } #endregion - } + } } \ No newline at end of file diff --git a/MapleLib/WzLib/WzProperties/WzPngProperty.cs b/MapleLib/WzLib/WzProperties/WzPngProperty.cs index c350d37..8e2fe39 100644 --- a/MapleLib/WzLib/WzProperties/WzPngProperty.cs +++ b/MapleLib/WzLib/WzProperties/WzPngProperty.cs @@ -130,9 +130,10 @@ public byte[] CompressedBytes /// Creates a blank WzPngProperty /// public WzPngProperty() { } - internal WzPngProperty(WzBinaryReader reader, bool parseNow) + internal WzPngProperty(WzBinaryReader reader, bool parsePng) { // Read compressed bytes + wzReader = reader; width = reader.ReadCompressedInt(); height = reader.ReadCompressedInt(); format = reader.ReadCompressedInt(); @@ -144,7 +145,7 @@ internal WzPngProperty(WzBinaryReader reader, bool parseNow) if (len > 0) { - if (parseNow) + if (parsePng) { compressedBytes = wzReader.ReadBytes(len); ParsePng(); @@ -152,7 +153,6 @@ internal WzPngProperty(WzBinaryReader reader, bool parseNow) else reader.BaseStream.Position += len; } - wzReader = reader; } #endregion @@ -185,7 +185,7 @@ public void SetPNG(Bitmap png) CompressPng(png); } - public Bitmap GetPNG(bool saveInMemory) + public Bitmap GetPNG(bool cache) { if (png == null) { @@ -197,7 +197,7 @@ public Bitmap GetPNG(bool saveInMemory) compressedBytes = wzReader.ReadBytes(len); ParsePng(); wzReader.BaseStream.Position = pos; - if (!saveInMemory) + if (!cache) { Bitmap pngImage = png; png = null; diff --git a/MapleLib/WzLib/WzProperties/WzStringProperty.cs b/MapleLib/WzLib/WzProperties/WzStringProperty.cs index 29c04c9..6bb2de1 100644 --- a/MapleLib/WzLib/WzProperties/WzStringProperty.cs +++ b/MapleLib/WzLib/WzProperties/WzStringProperty.cs @@ -115,7 +115,7 @@ public override string GetString() public override string ToString() { - return val; + return string.Format("{0}={1}", name, val); } #endregion } diff --git a/MapleLib/WzLib/WzProperties/WzSubProperty.cs b/MapleLib/WzLib/WzProperties/WzSubProperty.cs index c688e74..de293b2 100644 --- a/MapleLib/WzLib/WzProperties/WzSubProperty.cs +++ b/MapleLib/WzLib/WzProperties/WzSubProperty.cs @@ -26,7 +26,6 @@ namespace MapleLib.WzLib.WzProperties public class WzSubProperty : WzExtended, IPropertyContainer { #region Fields - internal List properties = new List(); internal string name; internal WzObject parent; //internal WzImage imgParent; @@ -41,7 +40,7 @@ public override void SetValue(object value) public override WzImageProperty DeepClone() { WzSubProperty clone = new WzSubProperty(name); - foreach (WzImageProperty prop in properties) + foreach (WzImageProperty prop in WzProperties) clone.AddProperty(prop.DeepClone()); return clone; } @@ -61,13 +60,7 @@ public override WzImageProperty DeepClone() /// /// The wz properties contained in the property /// - public override List WzProperties - { - get - { - return properties; - } - } + public override List WzProperties { get; } = new List(); /// /// The name of the property /// @@ -82,7 +75,7 @@ public override WzImageProperty this[string name] get { - foreach (WzImageProperty iwp in properties) + foreach (WzImageProperty iwp in WzProperties) if (iwp.Name.ToLower() == name.ToLower()) return iwp; //throw new KeyNotFoundException("A wz property with the specified name was not found"); @@ -133,7 +126,7 @@ public override WzImageProperty GetFromPath(string path) public override void WriteValue(MapleLib.WzLib.Util.WzBinaryWriter writer) { writer.WriteStringValue("Property", 0x73, 0x1B); - WzImageProperty.WritePropertyList(writer, properties); + WzImageProperty.WritePropertyList(writer, WzProperties); } public override void ExportXml(StreamWriter writer, int level) { @@ -141,16 +134,20 @@ public override void ExportXml(StreamWriter writer, int level) WzImageProperty.DumpPropertyList(writer, level, WzProperties); writer.WriteLine(XmlUtil.Indentation(level) + XmlUtil.CloseTag("WzSub")); } - /// - /// Disposes the object - /// - public override void Dispose() + + public override string ToString() { + return string.Format("WzSubProperty('{0}')", Name); + } + + /// + /// Disposes the object + /// + public override void Dispose() { name = null; - foreach (WzImageProperty prop in properties) + foreach (WzImageProperty prop in WzProperties) prop.Dispose(); - properties.Clear(); - properties = null; + WzProperties.Clear(); } #endregion @@ -174,7 +171,7 @@ public WzSubProperty(string name) public void AddProperty(WzImageProperty prop) { prop.Parent = this; - properties.Add(prop); + WzProperties.Add(prop); } public void AddProperties(List props) { @@ -186,15 +183,15 @@ public void AddProperties(List props) public void RemoveProperty(WzImageProperty prop) { prop.Parent = null; - properties.Remove(prop); + WzProperties.Remove(prop); } /// /// Clears the list of properties /// public void ClearProperties() { - foreach (WzImageProperty prop in properties) prop.Parent = null; - properties.Clear(); + foreach (WzImageProperty prop in WzProperties) prop.Parent = null; + WzProperties.Clear(); } #endregion } diff --git a/MapleLib/WzLib/WzProperties/WzUOLProperty.cs b/MapleLib/WzLib/WzProperties/WzUOLProperty.cs index cc8226f..62b096d 100644 --- a/MapleLib/WzLib/WzProperties/WzUOLProperty.cs +++ b/MapleLib/WzLib/WzProperties/WzUOLProperty.cs @@ -21,38 +21,31 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the using System.Collections.Generic; using MapleLib.WzLib.Util; using System.Drawing; +using System; + +namespace MapleLib.WzLib.WzProperties { + /// + /// A property that's value is a string + /// + public class WzUOLProperty : WzExtended { + #region Fields + //internal WzImage imgParent; + private WzObject LinkedWzObject; + #endregion -namespace MapleLib.WzLib.WzProperties -{ - /// - /// A property that's value is a string - /// - public class WzUOLProperty : WzExtended - { - #region Fields - internal string name, val; - internal WzObject parent; - //internal WzImage imgParent; - internal WzObject linkVal; - #endregion - - #region Inherited Members - public override void SetValue(object value) - { - val = (string)value; + #region Inherited Members + public override void SetValue(object value) { + Value = (string)value; } - public override WzImageProperty DeepClone() - { - WzUOLProperty clone = new WzUOLProperty(name, val); - clone.linkVal = null; + public override WzImageProperty DeepClone() { + WzUOLProperty clone = new WzUOLProperty(Name, Value); + clone.LinkedWzObject = null; return clone; } - public override object WzValue - { - get - { + public override object WzValue { + get { #if UOLRES return LinkValue; #else @@ -60,186 +53,153 @@ public override object WzValue #endif } } - /// - /// The parent of the object - /// - public override WzObject Parent { get { return parent; } internal set { parent = value; } } + /// + /// The parent of the object + /// + public override WzObject Parent { get; internal set; } - /*/// + /*/// /// The image that this property is contained in /// public override WzImage ParentImage { get { return imgParent; } internal set { imgParent = value; } }*/ - /// - /// The name of the property - /// - public override string Name { get { return name; } set { name = value; } } + /// + /// The name of the property + /// + public override string Name { get; set; } #if UOLRES - public override List WzProperties - { - get - { - return LinkValue is WzImageProperty ? ((WzImageProperty)LinkValue).WzProperties : null; - } - } + public override List WzProperties { + get { + return LinkValue is WzImageProperty ? ((WzImageProperty)LinkValue).WzProperties : null; + } + } - public override WzImageProperty this[string name] - { - get - { + public override WzImageProperty this[string name] { + get { return LinkValue is WzImageProperty ? ((WzImageProperty)LinkValue)[name] : LinkValue is WzImage ? ((WzImage)LinkValue)[name] : null; - } - } + } + } - public override WzImageProperty GetFromPath(string path) - { + public override WzImageProperty GetFromPath(string path) { return LinkValue is WzImageProperty ? ((WzImageProperty)LinkValue).GetFromPath(path) : LinkValue is WzImage ? ((WzImage)LinkValue).GetFromPath(path) : null; - } + } #endif - /// - /// The WzPropertyType of the property - /// - public override WzPropertyType PropertyType { get { return WzPropertyType.UOL; } } - - public override void WriteValue(MapleLib.WzLib.Util.WzBinaryWriter writer) - { - writer.WriteStringValue("UOL", 0x73, 0x1B); - writer.Write((byte)0); - writer.WriteStringValue(Value, 0, 1); - } - - public override void ExportXml(StreamWriter writer, int level) - { - writer.WriteLine(XmlUtil.Indentation(level) + XmlUtil.EmptyNamedValuePair("WzUOL", this.Name, this.Value)); - } - - /// - /// Disposes the object - /// - public override void Dispose() - { - name = null; - val = null; - } - #endregion - - #region Custom Members - /// - /// The value of the property - /// - public string Value { get { return val; } set { val = value; } } + /// + /// The WzPropertyType of the property + /// + public override WzPropertyType PropertyType { get { return WzPropertyType.UOL; } } + + public override void WriteValue(MapleLib.WzLib.Util.WzBinaryWriter writer) { + writer.WriteStringValue("UOL", 0x73, 0x1B); + writer.Write((byte)0); + writer.WriteStringValue(Value, 0, 1); + } + + public override void ExportXml(StreamWriter writer, int level) { + writer.WriteLine(XmlUtil.Indentation(level) + XmlUtil.EmptyNamedValuePair("WzUOL", this.Name, this.Value)); + } + + /// + /// Disposes the object + /// + public override void Dispose() { + Name = null; + Value = null; + } + #endregion + + #region Custom Members + /// + /// The value of the property + /// + public string Value { get; set; } #if UOLRES - public WzObject LinkValue - { - get - { - if (linkVal == null) - { - string[] paths = val.Split('/'); - linkVal = (WzObject)this.parent; - string asdf = parent.FullPath; - foreach (string path in paths) - { - if (path == "..") - { - linkVal = (WzObject)linkVal.Parent; - } - else - { - if (linkVal is WzImageProperty) - linkVal = ((WzImageProperty)linkVal)[path]; - else if (linkVal is WzImage) - linkVal = ((WzImage)linkVal)[path]; - else if (linkVal is WzDirectory) - linkVal = ((WzDirectory)linkVal)[path]; - else - { - MapleLib.Helpers.ErrorLogger.Log(MapleLib.Helpers.ErrorLevel.Critical, "UOL got nexon'd at property: " + this.FullPath); - return null; - } - } - } - } - return linkVal; - } - } + public WzObject LinkValue { + get { + if (LinkedWzObject == null) { + string[] sp = Value.Split('/'); + WzObject relative = Parent; + foreach (string path in sp) { + if (relative == null) return null; + if (path == "..") { + // move up a level + relative = relative.Parent; + } else { + relative = relative[path]; + //throw new InvalidOperationException(string.Format("cannot change directory to '{0}' from full path: '{1}", Value, FullPath)); + } + } + return LinkedWzObject = relative; + } + return LinkedWzObject; + } + } #endif - /// - /// Creates a blank WzUOLProperty - /// - public WzUOLProperty() { } + /// + /// Creates a blank WzUOLProperty + /// + public WzUOLProperty() { } + + /// + /// Creates a WzUOLProperty with the specified name + /// + /// The name of the property + public WzUOLProperty(string name) { + this.Name = name; + } - /// - /// Creates a WzUOLProperty with the specified name - /// - /// The name of the property - public WzUOLProperty(string name) - { - this.name = name; - } - - /// - /// Creates a WzUOLProperty with the specified name and value - /// - /// The name of the property - /// The value of the property - public WzUOLProperty(string name, string value) - { - this.name = name; - this.val = value; - } - #endregion + /// + /// Creates a WzUOLProperty with the specified name and value + /// + /// The name of the property + /// The value of the property + public WzUOLProperty(string name, string value) { + this.Name = name; + this.Value = value; + } + #endregion #region Cast Values #if UOLRES - public override int GetInt() - { + public override int GetInt() { return LinkValue.GetInt(); } - public override short GetShort() - { + public override short GetShort() { return LinkValue.GetShort(); } - public override long GetLong() - { + public override long GetLong() { return LinkValue.GetLong(); } - public override float GetFloat() - { + public override float GetFloat() { return LinkValue.GetFloat(); } - public override double GetDouble() - { + public override double GetDouble() { return LinkValue.GetDouble(); } - public override string GetString() - { + public override string GetString() { return LinkValue.GetString(); } - public override Point GetPoint() - { + public override Point GetPoint() { return LinkValue.GetPoint(); } - public override Bitmap GetBitmap() - { + public override Bitmap GetBitmap() { return LinkValue.GetBitmap(); } - public override byte[] GetBytes() - { + public override byte[] GetBytes() { return LinkValue.GetBytes(); } #else @@ -248,9 +208,8 @@ public override string GetString() return val; } #endif - public override string ToString() - { - return val; + public override string ToString() { + return string.Format("WzUOLProperty('{0}')", FullPath); } #endregion } diff --git a/MapleLib/WzLib/WzStructure/MapInfo.cs b/MapleLib/WzLib/WzStructure/MapInfo.cs index 11e262b..4aa7fb5 100644 --- a/MapleLib/WzLib/WzStructure/MapInfo.cs +++ b/MapleLib/WzLib/WzStructure/MapInfo.cs @@ -46,7 +46,7 @@ public MapInfo(WzImage image, string strMapName, string strStreetName, string st this.strStreetName = strStreetName; this.strCategoryName = strCategoryName; WzFile file = (WzFile)image.WzFileParent; - string loggerSuffix = ", map " + image.Name + ((file != null) ? (" of version " + Enum.GetName(typeof(WzMapleVersion), file.MapleVersion) + ", v" + file.Version.ToString()) : ""); + string loggerSuffix = ", map " + image.Name + ((file != null) ? (" of version " + Enum.GetName(typeof(WzMapleVersion), file.MapleVersion) + ", v" + file.FileVersion.ToString()) : ""); foreach (WzImageProperty prop in image["info"].WzProperties) { switch (prop.Name) diff --git a/WzVisualizer/GUI/Form1.cs b/WzVisualizer/GUI/Form1.cs index ac70c74..49632c9 100644 --- a/WzVisualizer/GUI/Form1.cs +++ b/WzVisualizer/GUI/Form1.cs @@ -3,6 +3,7 @@ using MapleLib.WzLib.WzProperties; using System; using System.Collections.Generic; +using System.ComponentModel.Design; using System.Data; using System.Diagnostics; using System.Drawing; @@ -20,14 +21,14 @@ public partial class MainForm : Form { private readonly PropertiesViewer viewer = new PropertiesViewer(); private readonly FolderBrowserDialog folderBrowser = new FolderBrowserDialog(); private WzStringUtility StringUtility; - private WzFile stringWz; - private WzFile itemWz; - private WzFile characterWz; - private WzFile mapWz; - private WzFile mobWz; - private WzFile skillWz; - private WzFile npcWz; - private WzFile reactorWz; + private WzFile StringWz; + private WzFile ItemWz; + private WzFile CharacterWz; + private WzFile MapWz; + private WzFile MobWz; + private WzFile SkillWz; + private WzFile NpcWz; + private WzFile ReactorWz; public MainForm() { InitializeComponent(); @@ -95,18 +96,23 @@ private void AddHairRow(WzImage image) { EquipHairsView.GridView.Rows.Add(id, icon?.GetBitmap(), name, ""); } + private void AddSkillRow(WzImageProperty s) { + int id = int.Parse(s.Name); + string name = StringUtility.GetSkill(s.Name); + string properties = BuildProperties(s); + WzObject icon = s.GetFromPath("icon"); + SkillsView.GridView.Rows.Add(id, icon?.GetBitmap(), name, properties); + } + private void AddGridRow(DataGridView grid, object wzObject) { int id; string properties = BuildProperties(wzObject); string name = null; - WzImageProperty icon = null; + WzObject icon = null; if (wzObject is WzImage image) { - image.ParseImage(); - string imgName = Path.GetFileNameWithoutExtension(image.Name); + id = int.Parse(Path.GetFileNameWithoutExtension(image.Name)); properties = BuildProperties(image) ?? ""; - id = int.Parse(imgName); - WzImageProperty entityIcon = image.GetFromPath("stand/0"); WzImageProperty linkProperty = image.GetFromPath("info/link"); if (linkProperty != null) { string linkName = ((WzStringProperty)linkProperty).Value; @@ -114,11 +120,12 @@ private void AddGridRow(DataGridView grid, object wzObject) { if (image == null) return; } + WzObject entityIcon = image.GetFromPath("stand/0"); if (image.WzFileParent.Name.StartsWith("Npc")) { // icon path like: '{ID}/stand/0' name = StringUtility.GetNPC(id); } else if (image.WzFileParent.Name.StartsWith("Mob")) { // icon path like: '{ID}/(move|stand|fly)/0' name = StringUtility.GetMob(id); - entityIcon = image.GetFromPath("fly/0") ?? image.GetFromPath("move/0"); // attempt to get image of the monster + entityIcon = (entityIcon == null) ? image.GetFromPath("fly/0") ?? image.GetFromPath("move/0") : null; // attempt to get image of the monster } else if (image.WzFileParent.Name.StartsWith("Reactor")) { name = image.GetFromPath("action")?.WzValue.ToString(); entityIcon = image.GetFromPath("0/0"); @@ -128,36 +135,21 @@ private void AddGridRow(DataGridView grid, object wzObject) { icon = image.GetFromPath("info/icon"); } - if (icon == null) { - icon = (WzImageProperty)(entityIcon is WzUOLProperty link ? link.LinkValue : entityIcon); - } + if (icon == null) icon = entityIcon; } else if (wzObject is WzSubProperty subProperty) { - if (subProperty.WzFileParent.Name.StartsWith("Skill")) { - id = int.Parse(subProperty.Name); - name = StringUtility.GetSkill(subProperty.Name); - icon = subProperty.GetFromPath("icon"); - } else { // for breadcrumb like: 'category.img/{ID}/info/icon' (etc.wz) - string imgName = subProperty.Name; - id = int.Parse(imgName); - if (ItemConstants.IsEtc(id)) name = StringUtility.GetEtc(id); - else if (ItemConstants.IsCash(id)) name = StringUtility.GetCash(id); - else if (ItemConstants.IsChair(id)) name = StringUtility.GetChair(id); - else if (ItemConstants.IsConsume(id)) name = StringUtility.GetConsume(id); - - icon = subProperty.GetFromPath("info/icon"); - } + // for path like: 'category.img/{ID}/info/icon' (Etc.wz) + string imgName = subProperty.Name; + id = int.Parse(imgName); + if (ItemConstants.IsEtc(id)) name = StringUtility.GetEtc(id); + else if (ItemConstants.IsCash(id)) name = StringUtility.GetCash(id); + else if (ItemConstants.IsChair(id)) name = StringUtility.GetChair(id); + else if (ItemConstants.IsConsume(id)) name = StringUtility.GetConsume(id); + + icon = subProperty.GetFromPath("info/icon"); } else return; - if (icon is WzUOLProperty uol && uol.LinkValue is WzCanvasProperty) { - icon = (WzCanvasProperty)uol.LinkValue; - } - - Bitmap bitmap = null; - try { - bitmap = icon is WzCanvasProperty canvas ? canvas.GetBitmap() : null; - } catch (Exception) { } - grid.Rows.Add(id, bitmap, name, properties); + grid.Rows.Add(id, icon?.GetBitmap(), name, properties); } #endregion @@ -211,11 +203,11 @@ private void LoadWzData(WzMapleVersion mapleVersion, string mapleDirectory) { break; case 0: // Equips { - if (!LoadWzFileIfAbsent(ref characterWz, mapleDirectory + "/Character", mapleVersion)) return; + if (!LoadWzFileIfAbsent(ref CharacterWz, mapleDirectory + "/Character", mapleVersion)) return; - List children = characterWz.WzDirectory.GetChildImages(); + List children = CharacterWz.WzDirectory.GetChildImages(); children.Sort((a, b) => a.Name.CompareTo(b.Name)); - for (int i = 0; i < characterWz.WzDirectory.CountImages(); i++) { + for (int i = 0; i < CharacterWz.WzDirectory.CountImages(); i++) { WzImage image = children[i]; string name = Path.GetFileNameWithoutExtension(image.Name); if (int.TryParse(name, out int equipId)) { @@ -284,10 +276,10 @@ private void LoadWzData(WzMapleVersion mapleVersion, string mapleDirectory) { case 4: // Cash case 9: // Pets { - if (!LoadWzFileIfAbsent(ref itemWz, mapleDirectory + "/Item", mapleVersion)) return; - List children = itemWz.WzDirectory.GetChildImages(); + if (!LoadWzFileIfAbsent(ref ItemWz, mapleDirectory + "/Item", mapleVersion)) return; + List children = ItemWz.WzDirectory.GetChildImages(); children.Sort((a, b) => a.Name.CompareTo(b.Name)); - for (int i = 0; i < itemWz.WzDirectory.CountImages(); i++) { + for (int i = 0; i < ItemWz.WzDirectory.CountImages(); i++) { WzImage image = children[i]; string name = Path.GetFileNameWithoutExtension(image.Name); if (int.TryParse(name, out int itemId)) { @@ -325,10 +317,10 @@ private void LoadWzData(WzMapleVersion mapleVersion, string mapleDirectory) { } case 5: // Map { - if (!LoadWzFileIfAbsent(ref mapWz, mapleDirectory + "/Map", mapleVersion)) return; - List children = mapWz.WzDirectory.GetChildImages(); + if (!LoadWzFileIfAbsent(ref MapWz, mapleDirectory + "/Map", mapleVersion)) return; + List children = MapWz.WzDirectory.GetChildImages(); children.Sort((a, b) => a.Name.CompareTo(b.Name)); - for (int i = 0; i < mapWz.WzDirectory.CountImages(); i++) { + for (int i = 0; i < MapWz.WzDirectory.CountImages(); i++) { WzImage image = children[i]; string sMapId = Path.GetFileNameWithoutExtension(image.Name); if (int.TryParse(sMapId, out int mapId)) { @@ -344,12 +336,12 @@ private void LoadWzData(WzMapleVersion mapleVersion, string mapleDirectory) { } case 6: // Mob { - if (!LoadWzFileIfAbsent(ref mobWz, mapleDirectory + "/Mob", mapleVersion)) return; + if (!LoadWzFileIfAbsent(ref MobWz, mapleDirectory + "/Mob", mapleVersion)) return; MobsView.GridView.Rows.Clear(); - List children = mobWz.WzDirectory.GetChildImages(); + List children = MobWz.WzDirectory.GetChildImages(); children.Sort((a, b) => a.Name.CompareTo(b.Name)); - for (int i = 0; i < mobWz.WzDirectory.CountImages(); i++) { + for (int i = 0; i < MobWz.WzDirectory.CountImages(); i++) { WzImage image = children[i]; AddGridRow(MobsView.GridView, image); } @@ -357,20 +349,19 @@ private void LoadWzData(WzMapleVersion mapleVersion, string mapleDirectory) { } case 7: // Skills { - if (!LoadWzFileIfAbsent(ref skillWz, mapleDirectory + "/Skill", mapleVersion)) return; + if (!LoadWzFileIfAbsent(ref SkillWz, mapleDirectory + "/Skill", mapleVersion)) return; SkillsView.GridView.Rows.Clear(); - List children = skillWz.WzDirectory.GetChildImages(); - children.Sort((a, b) => a.Name.CompareTo(b.Name)); - for (int i = 0; i < skillWz.WzDirectory.CountImages(); i++) { + SkillWz.WzDirectory.ParseImages(); + List children = SkillWz.WzDirectory.GetChildImages(); + for (int i = 0; i < SkillWz.WzDirectory.CountImages(); i++) { WzImage image = children[i]; string name = Path.GetFileNameWithoutExtension(image.Name); if (int.TryParse(name, out _)) { WzImageProperty tree = image.GetFromPath("skill"); if (tree is WzSubProperty) { List skills = tree.WzProperties; - skills.ForEach(s => AddGridRow(SkillsView.GridView, s)); - skills.Clear(); + skills.ForEach(s => AddSkillRow(s)); } } } @@ -378,12 +369,12 @@ private void LoadWzData(WzMapleVersion mapleVersion, string mapleDirectory) { } case 8: // NPCs { - if (!LoadWzFileIfAbsent(ref npcWz, mapleDirectory + "/Npc", mapleVersion)) return; + if (!LoadWzFileIfAbsent(ref NpcWz, mapleDirectory + "/Npc", mapleVersion)) return; NPCView.GridView.Rows.Clear(); - List children = npcWz.WzDirectory.GetChildImages(); + List children = NpcWz.WzDirectory.GetChildImages(); children.Sort((a, b) => a.Name.CompareTo(b.Name)); - for (int i = 0; i < npcWz.WzDirectory.CountImages(); i++) { + for (int i = 0; i < NpcWz.WzDirectory.CountImages(); i++) { WzImage image = children[i]; AddGridRow(NPCView.GridView, image); } @@ -391,12 +382,12 @@ private void LoadWzData(WzMapleVersion mapleVersion, string mapleDirectory) { } case 10: // Reactors { - if (!LoadWzFileIfAbsent(ref reactorWz, mapleDirectory + "/Reactor", mapleVersion)) return; + if (!LoadWzFileIfAbsent(ref ReactorWz, mapleDirectory + "/Reactor", mapleVersion)) return; ReactorView.GridView.Rows.Clear(); - List children = reactorWz.WzDirectory.GetChildImages(); + List children = ReactorWz.WzDirectory.GetChildImages(); children.Sort((a, b) => a.Name.CompareTo(b.Name)); - for (int i = 0; i < reactorWz.WzDirectory.CountImages(); i++) { + for (int i = 0; i < ReactorWz.WzDirectory.CountImages(); i++) { WzImage image = children[i]; AddGridRow(ReactorView.GridView, image); } @@ -441,21 +432,21 @@ private void RecursivelyLoadDirectory(WzDirectory dir, string directoryPath, WzM /// then calls the garbage collector for each loaded WZ file /// private void DisposeWzFiles() { - stringWz?.Dispose(); - itemWz?.Dispose(); - characterWz?.Dispose(); - mapWz?.Dispose(); - mobWz?.Dispose(); - skillWz?.Dispose(); - npcWz?.Dispose(); - - stringWz = null; - itemWz = null; - characterWz = null; - mapWz = null; - mobWz = null; - skillWz = null; - npcWz = null; + StringWz?.Dispose(); + ItemWz?.Dispose(); + CharacterWz?.Dispose(); + MapWz?.Dispose(); + MobWz?.Dispose(); + SkillWz?.Dispose(); + NpcWz?.Dispose(); + + StringWz = null; + ItemWz = null; + CharacterWz = null; + MapWz = null; + MobWz = null; + SkillWz = null; + NpcWz = null; } /// @@ -540,25 +531,25 @@ private void BtnWzLoad_Click(object sender, EventArgs e) { else mapleVersion = (WzMapleVersion) ComboEncType.SelectedIndex - 1; - stringWz = new WzFile(stringWzPath + Resources.FileExtension, mapleVersion); - stringWz.ParseWzFile(); - short? version = stringWz.Version; + StringWz = new WzFile(stringWzPath + Resources.FileExtension, mapleVersion); + StringWz.ParseWzFile(); + short? version = StringWz.FileVersion; if (WzTool.GetDecryptionSuccessRate(stringWzPath + Resources.FileExtension, mapleVersion, ref version) < 0.8) { MessageBox.Show(Resources.BadEncryption, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } else if (Directory.Exists(stringWzPath)) { // KMS mapleVersion = WzMapleVersion.EMS; - stringWz = new WzFile(stringWzPath, mapleVersion); - WzDirectory dir = new WzDirectory("String", stringWz); - stringWz.WzDirectory = dir; + StringWz = new WzFile(stringWzPath, mapleVersion); + WzDirectory dir = new WzDirectory("String", StringWz); + StringWz.WzDirectory = dir; RecursivelyLoadDirectory(dir, stringWzPath, mapleVersion); } else { MessageBox.Show(Resources.MissingStringFile, Resources.FIleNotFound, MessageBoxButtons.OK, MessageBoxIcon.Error); DisposeWzFiles(); return; } - StringUtility = new WzStringUtility(stringWz); + StringUtility = new WzStringUtility(StringWz); LoadWzData(mapleVersion, folderPath); } DisposeWzFiles();