Exemple #1
0
        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;
        }
Exemple #2
0
        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;
        }
Exemple #3
0
        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);
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        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;
            }
        }