Пример #1
0
 protected void CalcOffset(Wz_File wzFile, IEnumerable <Wz_Image> imgList)
 {
     foreach (var img in imgList)
     {
         img.Offset = wzFile.CalcOffset(img.HashedOffsetPosition, img.HashedOffset);
     }
 }
Пример #2
0
        public void LoadImg(string fileName, Wz_Node node)
        {
            Wz_File file = null;

            try
            {
                file = new Wz_File(fileName, this);
                file.TextEncoding = this.TextEncoding;
                var imgNode = new Wz_Node(node.Text);
                //跳过checksum检测
                var img = new Wz_Image(node.Text, (int)file.FileStream.Length, 0, 0, 0, file)
                {
                    OwnerNode         = imgNode,
                    Offset            = 0,
                    IsChecksumChecked = true
                };
                imgNode.Value = img;
                node.Nodes.Add(imgNode);
                this.wz_files.Add(file);
            }
            catch
            {
                file?.Close();
                throw;
            }
        }
Пример #3
0
        /// <summary>
        /// 搜索node所属的wz_file,若搜索不到则返回null。
        /// </summary>
        /// <param Name="node">要搜索的wznode。</param>
        /// <returns></returns>
        public static Wz_File GetNodeWzFile(this Wz_Node node, bool returnClosestWzFile = false)
        {
            Wz_File wzfile = null;

            while (node != null)
            {
                if ((wzfile = node.Value as Wz_File) != null)
                {
                    if (wzfile.OwnerWzFile != null)
                    {
                        wzfile = wzfile.OwnerWzFile;
                        node   = wzfile.Node;
                    }
                    if (!wzfile.IsSubDir || returnClosestWzFile)
                    {
                        break;
                    }
                }
                else if (node.Value is Wz_Image wzImg ||
                         (wzImg = (node as Wz_Image.Wz_ImageNode)?.Image) != null)
                {
                    wzfile = GetImageWzFile(wzImg, returnClosestWzFile);
                    break;
                }
                node = node.ParentNode;
            }
            return(wzfile);
        }
Пример #4
0
        public bool IsKMST1125WzFormat(string fileName)
        {
            if (!string.Equals(Path.GetExtension(fileName), ".wz", StringComparison.OrdinalIgnoreCase))
            {
                return(false);
            }

            string iniFile = Path.ChangeExtension(fileName, ".ini");

            if (!File.Exists(iniFile))
            {
                return(false);
            }

            // check if the file is an empty wzfile
            using (var file = new Wz_File(fileName, this))
            {
                if (!file.Loaded)
                {
                    return(false);
                }
                var tempNode = new Wz_Node();
                if (!this.encryption.encryption_detected)
                {
                    this.encryption.DetectEncryption(file);
                }
                file.FileStream.Position = file.Header.DataStartPosition;
                file.GetDirTree(tempNode);
                return(file.ImageCount == 0);
            }
        }
Пример #5
0
            public bool Verify(Wz_File wzFile)
            {
                List <Wz_Image> imgList = EnumerableAllWzImage(wzFile.node).Where(_img => _img.WzFile == wzFile).ToList();

                if (wzFile.header.VersionChecked)
                {
                    this.CalcOffset(wzFile, imgList);
                }
                else
                {
                    // find the wzImage with minimum size.
                    Wz_Image minSizeImg = imgList.DefaultIfEmpty().Aggregate((_img1, _img2) => _img1.Size < _img2.Size ? _img1 : _img2);

                    if (minSizeImg == null && imgList.Count > 0)
                    {
                        minSizeImg = imgList[0];
                    }

                    if (minSizeImg != null)
                    {
                        this.DetectWithWzImage(wzFile, minSizeImg);
                    }
                    else if (wzFile.directories.Count > 0)
                    {
                        this.DetectWithAllWzDir(wzFile);
                    }

                    if (wzFile.header.VersionChecked)
                    {
                        this.CalcOffset(wzFile, imgList);
                    }
                }

                return(wzFile.header.VersionChecked);
            }
Пример #6
0
            public bool Verify(Wz_File wzFile)
            {
                List <Wz_Image> imgList = EnumerableAllWzImage(wzFile.node).Where(_img => _img.WzFile == wzFile).ToList();

                if (wzFile.header.VersionChecked)
                {
                    this.CalcOffset(wzFile, imgList);
                }
                else
                {
                    if (imgList.Count > 0)
                    {
                        this.FastDetectWithAllWzImages(wzFile, imgList);
                    }
                    else if (wzFile.directories.Count > 0)
                    {
                        this.DetectWithAllWzDir(wzFile);
                    }

                    if (wzFile.header.VersionChecked)
                    {
                        this.CalcOffset(wzFile, imgList);
                    }
                }

                return(wzFile.header.VersionChecked);
            }
Пример #7
0
        public Wz_File LoadFile(string fileName, Wz_Node node, bool useBaseWz = false, bool loadWzAsFolder = false)
        {
            Wz_File file = null;

            try
            {
                file = new Wz_File(fileName, this);
                if (!file.Loaded)
                {
                    throw new Exception("The file is not a valid wz file.");
                }
                this.wz_files.Add(file);
                file.TextEncoding = this.TextEncoding;
                if (!this.encryption.encryption_detected)
                {
                    this.encryption.DetectEncryption(file);
                }
                node.Value = file;
                file.Node  = node;
                file.FileStream.Position = file.Header.DataStartPosition;
                file.GetDirTree(node, useBaseWz, loadWzAsFolder);
                file.DetectWzType();
                file.DetectWzVersion();
                return(file);
            }
            catch
            {
                if (file != null)
                {
                    file.Close();
                    this.wz_files.Remove(file);
                }
                throw;
            }
        }
Пример #8
0
            protected bool DetectWithAllWzDir(Wz_File wzFile)
            {
                while (wzFile.header.TryGetNextVersion())
                {
                    bool isSuccess = wzFile.directories.All(testDir =>
                    {
                        uint offs = wzFile.CalcOffset(testDir.HashedOffsetPosition, testDir.HashedOffset);

                        if (offs < wzFile.header.DataStartPosition || offs + 1 > wzFile.header.DirEndPosition) // dir offset out of file size.
                        {
                            return(false);
                        }

                        wzFile.fileStream.Position = offs;
                        if (wzFile.fileStream.ReadByte() != 0) // for splitted wz format, dir data only contains one byte: 0x00
                        {
                            return(false);
                        }

                        return(true);
                    });

                    if (isSuccess)
                    {
                        wzFile.header.VersionChecked = true;
                        break;
                    }
                }

                return(wzFile.header.VersionChecked);
            }
Пример #9
0
            protected bool DetectWithWzImage(Wz_File wzFile, Wz_Image testWzImg)
            {
                while (wzFile.header.TryGetNextVersion())
                {
                    uint offs = wzFile.CalcOffset(testWzImg.HashedOffsetPosition, testWzImg.HashedOffset);

                    if (offs < wzFile.header.DirEndPosition || offs + testWzImg.Size > wzFile.fileStream.Length)  //img offset out of file size
                    {
                        continue;
                    }

                    wzFile.fileStream.Position = offs;
                    var firstByte = (byte)wzFile.fileStream.ReadByte();
                    if (!FastCheckFirstByte(testWzImg, firstByte))
                    {
                        continue;
                    }

                    testWzImg.Offset = offs;
                    if (!testWzImg.TryExtract())
                    {
                        continue;
                    }

                    testWzImg.Unextract();
                    wzFile.header.VersionChecked = true;
                    break;
                }

                return(wzFile.header.VersionChecked);
            }
Пример #10
0
        public void LoadFile(string fileName, Wz_Node node, bool useBaseWz)
        {
            Wz_File file;

            try
            {
                file = new Wz_File(fileName, this);
                file.TextEncoding = this.TextEncoding;
                if (!this.encryption.encryption_detected)
                {
                    this.encryption.DetectEncryption(file);
                }
                this.wz_files.Add(file);
                node.Value = file;
                file.Node  = node;
                file.FileStream.Position = 62;
                file.GetDirTree(node, useBaseWz);
                file.DetectWzType();
                file.DetectWzVersion();
            }
            catch
            {
                throw;
            }
        }
Пример #11
0
 public Wz_Png(int w, int h, int data_length, int form, int offs, Wz_File wz_f)
 {
     this.w           = w;
     this.h           = h;
     this.data_length = data_length;
     this.form        = form;
     this.offs        = offs;
     this.wz_f        = wz_f;
 }
Пример #12
0
 public Wz_Sound(int offset, int length, byte[] header, int ms, Wz_File wz_f)
 {
     this.offset     = offset;
     this.dataLength = length;
     this.header     = header;
     this.ms         = ms;
     this.wz_f       = wz_f;
     TryDecryptHeader();
 }
Пример #13
0
        public Wz_Image(string name, int size, int cs32, uint hashOff, uint hashPos, Wz_File wz_f)
        {
            this.Name                 = name;
            this.WzFile               = wz_f;
            this.Size                 = size;
            this.Checksum             = cs32;
            this.HashedOffset         = hashOff;
            this.HashedOffsetPosition = hashPos;
            this.Node                 = new Wz_ImageNode(name, this);

            this.extr    = false;
            this.chec    = false;
            this.checEnc = false;
        }
Пример #14
0
 public static int GetMergedVersion(this Wz_File wzFile)
 {
     if (wzFile.Header.WzVersion != 0)
     {
         return(wzFile.Header.WzVersion);
     }
     foreach (var subFile in wzFile.MergedWzFiles)
     {
         if (subFile.Header.WzVersion != 0)
         {
             return(subFile.Header.WzVersion);
         }
     }
     return(0);
 }
Пример #15
0
            protected bool FastDetectWithAllWzImages(Wz_File wzFile, IList <Wz_Image> imgList)
            {
                var imageSizes = new SizeRange[imgList.Count];

                while (wzFile.header.TryGetNextVersion())
                {
                    int  count     = 0;
                    bool isSuccess = imgList.All(img =>
                    {
                        uint offs = wzFile.CalcOffset(img.HashedOffsetPosition, img.HashedOffset);
                        if (offs < wzFile.header.DirEndPosition || offs + img.Size > wzFile.fileStream.Length)  //img offset out of file size
                        {
                            return(false);
                        }

                        imageSizes[count++] = new SizeRange()
                        {
                            Start = offs,
                            End   = offs + img.Size,
                        };
                        return(true);
                    });

                    if (isSuccess)
                    {
                        // check if there's any image overlaps with another image.
                        Array.Sort(imageSizes, 0, count);
                        for (int i = 1; i < count; i++)
                        {
                            if (imageSizes[i - 1].End > imageSizes[i].Start)
                            {
                                isSuccess = false;
                                break;
                            }
                        }

                        if (isSuccess)
                        {
                            wzFile.header.VersionChecked = true;
                            break;
                        }
                    }
                }

                return(wzFile.header.VersionChecked);
            }
Пример #16
0
        public void MergeWzFile(Wz_File wz_File)
        {
            var children = wz_File.node.Nodes.ToList();

            wz_File.node.Nodes.Clear();
            foreach (var child in children)
            {
                this.node.Nodes.Add(child);
            }

            if (this.mergedWzFiles == null)
            {
                this.mergedWzFiles = new List <Wz_File>();
            }
            this.mergedWzFiles.Add(wz_File);

            wz_File.ownerWzFile = this;
        }
Пример #17
0
        /// <summary>
        /// 搜索node所属的wz_file,若搜索不到则返回null。
        /// </summary>
        /// <param Name="node">要搜索的wznode。</param>
        /// <returns></returns>
        public static Wz_File GetNodeWzFile(this Wz_Node node)
        {
            Wz_File  wzfile = null;
            Wz_Image wzImg  = null;

            while (node != null)
            {
                if ((wzfile = node.Value as Wz_File) != null)
                {
                    break;
                }
                if ((wzImg = node.Value as Wz_Image) != null ||
                    (wzImg = (node as Wz_Image.Wz_ImageNode)?.Image) != null)
                {
                    wzfile = wzImg.WzFile;
                    break;
                }
                node = node.ParentNode;
            }
            return(wzfile);
        }
Пример #18
0
 public Wz_Directory(string name, int size, int cs32, uint hashOff, uint hashPos, Wz_File wz_f)
 {
     this.Name                 = name;
     this.WzFile               = wz_f;
     this.Size                 = size;
     this.Checksum             = cs32;
     this.HashedOffset         = hashOff;
     this.HashedOffsetPosition = hashPos;
 }
Пример #19
0
        public void DetectEncryption(Wz_File f)
        {
            int old_off = (int)f.FileStream.Position;

            f.FileStream.Position = f.Header.DataStartPosition;
            if (f.ReadInt32() <= 0) //只有文件头 无法预判
            {
                return;
            }
            f.FileStream.Position++;
            int len = (int)(-f.BReader.ReadSByte());

            byte[] bytes = f.BReader.ReadBytes(len);

            for (int i = 0; i < len; i++)
            {
                bytes[i] ^= (byte)(0xAA + i);
            }

            StringBuilder sb = new StringBuilder();

            if (!this.encryption_detected)
            {
                //测试bms
                sb.Clear();
                for (int i = 0; i < len; i++)
                {
                    sb.Append((char)(keys_bms[i] ^ bytes[i]));
                }
                if (IsLegalNodeName(sb.ToString()))
                {
                    this.EncType             = Wz_CryptoKeyType.BMS;
                    this.encryption_detected = true;
                    goto lbl_end;
                }

                //测试kms
                sb.Clear();
                for (int i = 0; i < len; i++)
                {
                    sb.Append((char)(keys_kms[i] ^ bytes[i]));
                }
                if (IsLegalNodeName(sb.ToString()))
                {
                    this.EncType             = Wz_CryptoKeyType.KMS;
                    this.encryption_detected = true;
                    goto lbl_end;
                }

                //测试gms
                sb.Clear();
                for (int i = 0; i < len; i++)
                {
                    sb.Append((char)(keys_gms[i] ^ bytes[i]));
                }
                if (IsLegalNodeName(sb.ToString()))
                {
                    this.EncType             = Wz_CryptoKeyType.GMS;
                    this.encryption_detected = true;
                    goto lbl_end;
                }
            }

lbl_end:
            f.FileStream.Position = old_off;
        }