private void HandleItemCategory(WzDirectory pDir) { string tmp = exDir; exDir += Path.DirectorySeparatorChar + pDir.Name; // Etc foreach (var collection in pDir.GetChildImages()) // 0400.img { exDir += Path.DirectorySeparatorChar + collection.Name; bool isNebuliteDir = collection.Name == "0306.img"; foreach (var item in collection.WzProperties.Where(p => { return p is WzSubProperty; })) // 04000000 { exDir += Path.DirectorySeparatorChar + item.Name + Path.DirectorySeparatorChar; currentID = Convert.ToInt32(item.Name); if (item["info"] != null) { ExportIfExists(exDir, item["info"]["icon"], "info"); ExportIfExists(exDir, item["info"]["iconRaw"], "info"); ExportIfExists(exDir, item["info"]["iconD"], "info"); ExportIfExists(exDir, item["info"]["iconRawD"], "info"); ItemInformation.Instance.HandleInfo(currentID, item["info"].ToSubProperty()); } if (item["spec"] != null) { if (item["spec"]["slotCount"] != null) SQLStrings.Instance.AppendRow("item_spec", currentID, "slotcount", item["spec"]["slotCount"].ToInt().ToString()); if (item["spec"]["slotPerLine"] != null) SQLStrings.Instance.AppendRow("item_spec", currentID, "slotperline", item["spec"]["slotPerLine"].ToInt().ToString()); if (item["spec"]["type"] != null) SQLStrings.Instance.AppendRow("item_spec", currentID, "type", item["spec"]["type"].ToInt().ToString()); } if (item["effect"] != null) { foreach (var stance in CharacterExtractor.STANCES) if (item["effect"][stance] != null) HandleHairStyle(exDir, item["effect"][stance].ToSubProperty(), "effect." + stance); } if (isNebuliteDir && item["socket"] != null) { // Extract moar options string description = item["socket"]["string"] != null ? item["socket"]["string"].ToStringValue() : ""; string optionlist = ""; foreach (var option in item["socket"]["option"].WzProperties) { if (optionlist != "") optionlist += ';'; optionlist += option["optionString"].ToStringValue() + '=' + option["level"].ToInt(); } SqlFileItemSocket.Instance.AppendRow(currentID, description, optionlist); } exDir = RemoveFromBackDirSlash(exDir); exDir = RemoveFromBackDirSlash(exDir); } exDir = RemoveFromBackDirSlash(exDir); } exDir = RemoveFromBackDirSlash(exDir); }
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), mapleVersion); 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; } }
/// <summary> /// Parse directories in the WZ file /// </summary> /// <param name="parseErrorMessage"></param> /// <param name="lazyParse">Only load the firt WzDirectory found if true</param> /// <returns></returns> internal bool ParseMainWzDirectory(out string parseErrorMessage, bool lazyParse = false) { if (this.path == null) { Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Path is null"); parseErrorMessage = "[Error] Path is null"; return(false); } 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 (mapleStoryPatchVersion == -1) { const short MAX_PATCH_VERSION = 10000; // wont be reached for the forseeable future. for (int j = 0; j < MAX_PATCH_VERSION; j++) { this.mapleStoryPatchVersion = (short)j; this.versionHash = GetVersionHash(version, mapleStoryPatchVersion); if (this.versionHash == 0) { continue; } reader.Hash = this.versionHash; long position = reader.BaseStream.Position; // save position to rollback to, if should parsing fail from here WzDirectory testDirectory; try { testDirectory = new WzDirectory(reader, this.name, this.versionHash, this.WzIv, this); testDirectory.ParseDirectory(lazyParse); } catch { reader.BaseStream.Position = position; continue; } try { List <WzImage> childImages = testDirectory.GetChildImages(); if (childImages.Count == 0) // coincidentally in msea v194 Map001.wz, the hash matches exactly using mapleStoryPatchVersion of 113, and it fails to decrypt later on (probably 1 in a million chance). { reader.BaseStream.Position = position; // reset continue; } WzImage testImage = childImages[0]; try { reader.BaseStream.Position = testImage.Offset; byte checkByte = reader.ReadByte(); reader.BaseStream.Position = position; switch (checkByte) { case 0x73: case 0x1b: { WzDirectory directory = new WzDirectory(reader, this.name, this.versionHash, this.WzIv, this); directory.ParseDirectory(lazyParse); this.wzDir = directory; parseErrorMessage = "Success"; return(true); } default: { Helpers.ErrorLogger.Log(Helpers.ErrorLevel.MissingFeature, "New Wz image header found. checkByte = " + checkByte); // log or something break; } } reader.BaseStream.Position = position; // reset } catch { reader.BaseStream.Position = position; // reset } } finally { testDirectory.Dispose(); } } parseErrorMessage = "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, mapleStoryPatchVersion); reader.Hash = this.versionHash; WzDirectory directory = new WzDirectory(reader, this.name, this.versionHash, this.WzIv, this); directory.ParseDirectory(); this.wzDir = directory; } parseErrorMessage = "Success"; return(true); }
internal void ParseMainWzDirectory() { if (this.path == null) { Console.WriteLine("[Error] Path is null"); return; } WzBinaryReader reader = new WzBinaryReader(File.Open(this.path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), 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); 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); 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); directory.ParseDirectory(); this.wzDir = directory; } }
internal void ParseMainWzDirectory(WzFile parentFile = null) { if (mPath == null) { Console.WriteLine("[Error] Path is null"); return; } byte[] key = WzKeyGenerator.GenerateWzKey(mWzIv); mReader = new WzBinaryReader(File.Open(mPath, FileMode.Open, FileAccess.Read, FileShare.Read), key, true); Header = new WzHeader { Ident = mReader.ReadString(4), FSize = mReader.ReadUInt64(), FStart = mReader.ReadUInt32(), Copyright = mReader.ReadNullTerminatedString() }; int bytesToRead = (int)(Header.FStart - mReader.BaseStream.Position); if (bytesToRead < 0) { throw new Exception("Unable to parse WZ file header"); } mReader.ReadBytes(bytesToRead); mReader.Header = Header; mVersion = mReader.ReadInt16(); if (mFileVersion == -1) { for (int j = 0; j < short.MaxValue; j++) { mFileVersion = (short)j; if (parentFile != null) { mFileVersion = parentFile.mFileVersion; } mVersionHash = GetVersionHash(mVersion, mFileVersion); if (mVersionHash == 0) { continue; } mReader.Hash = mVersionHash; long position = mReader.BaseStream.Position; WzDirectory testDirectory; try { testDirectory = new WzDirectory(mReader, mName, mVersionHash, mWzIv); testDirectory.ParseDirectory(); } catch { mReader.BaseStream.Position = position; continue; } foreach (WzImage s in testDirectory.GetChildImages()) { if (s.Name.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0) { testDirectory.Dispose(); throw new Exception("Invalid file names were detected. An invalid encryption may have been used."); } } WzImage testImage = testDirectory.GetChildImages()[0]; try { mReader.BaseStream.Position = testImage.Offset; byte checkByte = mReader.ReadByte(); mReader.BaseStream.Position = position; testDirectory.Dispose(); switch (checkByte) { case 0x73: case 0x1b: { mHash = mVersionHash; ParseDirectory(parentFile); return; } } mReader.BaseStream.Position = position; } catch { mReader.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"); } mVersionHash = GetVersionHash(mVersion, mFileVersion); mReader.Hash = mVersionHash; mHash = mVersionHash; ParseDirectory(parentFile); }
private void HandlePets(WzDirectory pDir) { string tmp = exDir; exDir += Path.DirectorySeparatorChar + pDir.Name; // Pet foreach (var item in pDir.GetChildImages()) // 5000000.img { exDir += Path.DirectorySeparatorChar + item.Name + Path.DirectorySeparatorChar; int itemid = Convert.ToInt32(item.Name.Remove(item.Name.IndexOf('.'))); currentID = itemid; if (item["info"] != null) { ExportIfExists(exDir, item["info"]["icon"], "info"); ExportIfExists(exDir, item["info"]["iconRaw"], "info"); ExportIfExists(exDir, item["info"]["iconD"], "info"); // Dead pets ExportIfExists(exDir, item["info"]["iconRawD"], "info"); ItemInformation.Instance.HandleInfo(currentID, item["info"].ToSubProperty()); } if (item["stand0"] != null) { ExportIfExists(exDir, item["stand0"]["0"], "stand0"); SaveVector(item["stand0"]["0"]["origin"] as WzVectorProperty, "stand0.0"); } exDir = RemoveFromBackDirSlash(exDir); exDir = RemoveFromBackDirSlash(exDir); } exDir = RemoveFromBackDirSlash(exDir); }
/// <summary> /// Parse directories in the WZ file /// </summary> /// <param name="parseErrorMessage"></param> /// <param name="lazyParse">Only load the firt WzDirectory found if true</param> /// <returns></returns> internal WzFileParseStatus ParseMainWzDirectory(bool lazyParse = false) { if (this.path == null) { Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Path is null"); return(WzFileParseStatus.Path_Is_Null); } 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.ReadString((int)(Header.FStart - 17U)); reader.ReadBytes(1); reader.ReadBytes((int)(Header.FStart - (ulong)reader.BaseStream.Position)); reader.Header = this.Header; this.version = reader.ReadInt16(); if (mapleStoryPatchVersion == -1) { const short MAX_PATCH_VERSION = 10000; // wont be reached for the forseeable future. for (int j = 0; j < MAX_PATCH_VERSION; j++) { this.mapleStoryPatchVersion = (short)j; this.versionHash = CheckAndGetVersionHash(version, mapleStoryPatchVersion); if (this.versionHash == 0) // ugly hack, but that's the only way if the version number isnt known (nexon stores this in the .exe) { continue; } reader.Hash = this.versionHash; long position = reader.BaseStream.Position; // save position to rollback to, if should parsing fail from here WzDirectory testDirectory; try { testDirectory = new WzDirectory(reader, this.name, this.versionHash, this.WzIv, this); testDirectory.ParseDirectory(lazyParse); } catch (Exception exp) { Debug.WriteLine(exp.ToString()); reader.BaseStream.Position = position; continue; } try { List <WzImage> childImages = testDirectory.GetChildImages(); if (childImages.Count == 0) // coincidentally in msea v194 Map001.wz, the hash matches exactly using mapleStoryPatchVersion of 113, and it fails to decrypt later on (probably 1 in a million chance). { reader.BaseStream.Position = position; // reset continue; } WzImage testImage = childImages[0]; try { reader.BaseStream.Position = testImage.Offset; byte checkByte = reader.ReadByte(); reader.BaseStream.Position = position; switch (checkByte) { case 0x73: case 0x1b: { WzDirectory directory = new WzDirectory(reader, this.name, this.versionHash, this.WzIv, this); directory.ParseDirectory(lazyParse); this.wzDir = directory; return(WzFileParseStatus.Success); } case 0x30: case 0x6C: // idk case 0xBC: // Map002.wz? KMST? default: { Helpers.ErrorLogger.Log(Helpers.ErrorLevel.MissingFeature, string.Format("[WzFile.cs] New Wz image header found. checkByte = {0}. File Name = {1}", checkByte, Name)); // log or something break; } } reader.BaseStream.Position = position; // reset } catch { reader.BaseStream.Position = position; // reset } } finally { testDirectory.Dispose(); } } //parseErrorMessage = "Error with game version hash : The specified game version is incorrect and WzLib was unable to determine the version itself"; return(WzFileParseStatus.Error_Game_Ver_Hash); } else { this.versionHash = CheckAndGetVersionHash(version, mapleStoryPatchVersion); reader.Hash = this.versionHash; WzDirectory directory = new WzDirectory(reader, this.name, this.versionHash, this.WzIv, this); directory.ParseDirectory(); this.wzDir = directory; } return(WzFileParseStatus.Success); }
internal void ParseMainWzDirectory() { if (FilePath == null) { Log.LogCritical("Path is null"); return; } var reader = new WzBinaryReader(File.Open(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read), _wzIv); Header = new WzHeader { Ident = reader.ReadString(4), FSize = reader.ReadUInt64(), FStart = reader.ReadUInt32(), Copyright = reader.ReadNullTerminatedString() }; reader.ReadBytes((int)(Header.FStart - reader.BaseStream.Position)); reader.Header = Header; _version = reader.ReadInt16(); if (FileVersion == -1) { for (var j = 0; j < short.MaxValue; j++) { FileVersion = (short)j; _versionHash = GetVersionHash(_version, FileVersion); if (_versionHash != 0) { reader.Hash = _versionHash; var position = reader.BaseStream.Position; WzDirectory testDirectory; try { testDirectory = new WzDirectory(reader, Name, _versionHash, _wzIv, this); testDirectory.ParseDirectory(); } catch { reader.BaseStream.Position = position; continue; } var testImage = testDirectory.GetChildImages()[0]; try { reader.BaseStream.Position = testImage.Offset; var checkByte = reader.ReadByte(); reader.BaseStream.Position = position; testDirectory.Dispose(); switch (checkByte) { case 0x73: case 0x1b: { var directory = new WzDirectory(reader, Name, _versionHash, _wzIv, this); directory.ParseDirectory(); 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"); } { _versionHash = GetVersionHash(_version, FileVersion); reader.Hash = _versionHash; var directory = new WzDirectory(reader, Name, _versionHash, _wzIv, this); directory.ParseDirectory(); WzDirectory = directory; } }