internal void ParseMainWzDirectory() { if (FilePath == null) { _log.Error("Path is null"); return; } if (!File.Exists(FilePath)) { var message = $"WZ File does not exist at path: '{FilePath}'"; _log.Error(message); throw new FileNotFoundException(message); } 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 (Version == -1 && !CalculateVersion(reader)) { throw new InvalidDataException( "Error with game version hash : The specified game version is incorrect"); } _versionHash = GetVersionHash(_version, Version); reader.Hash = _versionHash; var tempDirectory = new WzDirectory(reader, Name, _versionHash, _wzIv, this); tempDirectory.ParseDirectory(); WzDirectory = tempDirectory; }
private void ParseMainWzDirectory(byte[] wzIv) { if (FilePath == null) { throw new ArgumentNullException(nameof(FilePath), "WZ File path is null"); } if (!File.Exists(FilePath)) { throw new FileNotFoundException($"WZ File does not exist at path: '{FilePath}'"); } var mmf = MemoryMappedFile.CreateFromFile(FilePath); var reader = new WzBinaryReader(mmf.CreateViewStream(), 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 (Version == -1 && !CalculateVersion(reader)) { throw new InvalidDataException( "Error with game version hash : The specified game version is incorrect"); } _versionHash = GetVersionHash(_version, Version); reader.Hash = _versionHash; var tempDirectory = new WzDirectory(reader, Name, _versionHash, wzIv, this); tempDirectory.ParseDirectory(); WzDirectory = tempDirectory; }
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(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); }
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; } }