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; } }
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); }
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); }
public static Wz_File GetImageWzFile(this Wz_Image wzImg, bool returnClosestWzFile = false) { if (!returnClosestWzFile && wzImg.WzFile != null) { return(GetNodeWzFile(wzImg.WzFile.Node, returnClosestWzFile)); } return(wzImg.WzFile); }
public Wz_Node HandleUol(Wz_Node currentNode) { if (currentNode == null || currentNode.ParentNode == null || string.IsNullOrEmpty(uol)) { return(null); } string[] dirs = this.uol.Split('/'); currentNode = currentNode.ParentNode; bool outImg = false; for (int i = 0; i < dirs.Length; i++) { string dir = dirs[i]; if (dir == "..") { if (currentNode.ParentNode == null) { Wz_Image img = currentNode.GetValueEx <Wz_Image>(null); if (img != null) { currentNode = img.OwnerNode.ParentNode; outImg = true; } else { currentNode = null; } } else { currentNode = currentNode.ParentNode; } } else { var dirNode = currentNode.FindNodeByPath(dir); if (dirNode == null && outImg) { dirNode = currentNode.FindNodeByPath(true, dir + ".img"); if (dirNode.GetValueEx <Wz_Image>(null) != null) { outImg = false; } } currentNode = dirNode; } if (currentNode == null) { return(null); } } return(currentNode); }
protected bool FastCheckFirstByte(Wz_Image image, byte firstByte) { if (image.IsLuaImage) { // for lua image, the first byte is always 01 return(firstByte == 0x01); } else { // first element is always a string return(firstByte == 0x73 || firstByte == 0x1b); } }
public static Wz_Image GetNodeWzImage(this Wz_Node node) { Wz_Image wzImg = null; while (node != null) { if ((wzImg = node.Value as Wz_Image) != null || (wzImg = (node as Wz_Image.Wz_ImageNode)?.Image) != null) { break; } node = node.ParentNode; } return(wzImg); }
public void AddImageNode(string newimg, string imagekey) { // Wz_File file = new Wz_File(newimg, this.WzFile.WzStructure); // file.TextEncoding = this.WzFile.WzStructure.TextEncoding; var imgNode = new Wz_Node(newimg); var img = new Wz_Image(imagekey, 128, 0, 0, 0, this.WzFile) { OwnerNode = this.Node, Offset = 0, IsChecksumChecked = true }; imgNode.Value = img; this.WzFile.Node.Nodes.Add(imgNode); // this.WzFile.WzStructure.wz_files.Add(file); this.WzFile.WzStructure.WzNode.AddKey("test"); }
private IEnumerable <Wz_Image> EnumerableAllWzImage(Wz_Node parentNode) { foreach (var node in parentNode.Nodes) { Wz_Image img = node.Value as Wz_Image; if (img != null) { yield return(img); } if (!(node.Value is Wz_File) && node.Nodes.Count > 0) { foreach (var imgChild in EnumerableAllWzImage(node)) { yield return(imgChild); } } } }
public void DetectWzVersion() { if (!this.header.VersionChecked) { //选择最小的img作为实验品 Wz_Image minSizeImg = null; List <Wz_Image> imgList = new List <Wz_Image>(this.imageCount); foreach (var img in (EnumerableAllWzImage(this.node))) { if (img.Size >= 20 && (minSizeImg == null || img.Size < minSizeImg.Size)) { minSizeImg = img; } imgList.Add(img); } if (minSizeImg == null) { if (imgList.Count <= 0) { return; } minSizeImg = imgList[0]; } while (this.header.TryGetNextVersion()) { uint offs = CalcOffset(minSizeImg.HashedOffsetPosition, minSizeImg.HashedOffset); if (offs < this.header.HeaderSize || offs + minSizeImg.Size > this.fileStream.Length) //img块越界 { continue; } this.fileStream.Position = offs; switch (this.fileStream.ReadByte()) { case 0x73: case 0x1b: //试读img第一个string break; default: continue; } minSizeImg.Offset = offs; if (minSizeImg.TryExtract()) //试读成功 { minSizeImg.Unextract(); this.header.VersionChecked = true; break; } } if (this.header.VersionChecked) //重新计算全部img { foreach (var img in imgList) { img.Offset = CalcOffset(img.HashedOffsetPosition, img.HashedOffset); } } else //最终测试失败 那就失败吧.. { this.header.VersionChecked = true; } } }
public void GetDirTree(Wz_Node parent, bool useBaseWz) { List <string> dirs = new List <string>(); string name = null; int size = 0; int cs32 = 0; //int offs = 0; int count = ReadInt32(); for (int i = 0; i < count; i++) { switch ((int)this.BReader.ReadByte()) { case 0x02: name = this.ReadStringAt(this.Header.HeaderSize + 1 + this.BReader.ReadInt32()); goto case 0xffff; case 0x04: name = this.ReadString(); goto case 0xffff; case 0xffff: size = this.ReadInt32(); cs32 = this.ReadInt32(); uint pos = (uint)this.bReader.BaseStream.Position; uint hashOffset = this.bReader.ReadUInt32(); Wz_Image img = new Wz_Image(name, size, cs32, hashOffset, pos, this); Wz_Node childNode = parent.Nodes.Add(name); childNode.Value = img; img.OwnerNode = childNode; this.imageCount++; break; case 0x03: name = this.ReadString(); size = this.ReadInt32(); cs32 = this.ReadInt32(); this.FileStream.Position += 4; dirs.Add(name); break; } } int dirCount = dirs.Count; bool willLoadBaseWz = useBaseWz ? parent.Text.Equals("base.wz", StringComparison.OrdinalIgnoreCase) : false; var baseFolder = Path.GetDirectoryName(this.header.FileName); if (willLoadBaseWz && this.WzStructure.AutoDetectExtFiles) { for (int i = 0; i < dirCount; i++) { //检测文件名 var m = Regex.Match(dirs[i], @"^([A-Za-z]+)$"); if (m.Success) { string wzTypeName = m.Result("$1"); //检测扩展wz文件 for (int fileID = 2; ; fileID++) { string extDirName = wzTypeName + fileID; string extWzFile = Path.Combine(baseFolder, extDirName + ".wz"); if (File.Exists(extWzFile)) { if (!dirs.Take(dirCount).Any(dir => extDirName.Equals(dir, StringComparison.OrdinalIgnoreCase))) { dirs.Add(extDirName); } } else { break; } } //检测KMST1058的wz文件 for (int fileID = 1; ; fileID++) { string extDirName = wzTypeName + fileID.ToString("D3"); string extWzFile = Path.Combine(baseFolder, extDirName + ".wz"); if (File.Exists(extWzFile)) { if (!dirs.Take(dirCount).Any(dir => extDirName.Equals(dir, StringComparison.OrdinalIgnoreCase))) { dirs.Add(extDirName); } } else { break; } } } } } for (int i = 0; i < dirs.Count; i++) { string dir = dirs[i]; Wz_Node t = parent.Nodes.Add(dir); if (willLoadBaseWz) { this.WzStructure.has_basewz = true; if (i < dirCount) { GetDirTree(t, false); } try { string filePath = Path.Combine(baseFolder, dir + ".wz"); if (File.Exists(filePath)) { this.WzStructure.LoadFile(filePath, t); } } catch (Exception ex) { } } else { GetDirTree(t, false); } } parent.Nodes.Trim(); }
public Wz_ImageNode(string nodeText, Wz_Image image) : base(nodeText) { this.Image = image; }
public void DetectWzVersion() { bool DetectWithWzImage(Wz_Image testWzImg) { while (this.header.TryGetNextVersion()) { uint offs = CalcOffset(testWzImg.HashedOffsetPosition, testWzImg.HashedOffset); if (offs < this.header.HeaderSize || offs + testWzImg.Size > this.fileStream.Length) //img块越界 { continue; } this.fileStream.Position = offs; switch (this.fileStream.ReadByte()) { case 0x73: case 0x1b: //试读img第一个string break; default: continue; } testWzImg.Offset = offs; if (testWzImg.TryExtract()) //试读成功 { testWzImg.Unextract(); this.header.VersionChecked = true; break; } } return(this.header.VersionChecked); } bool DetectWithAllWzDir() { while (this.header.TryGetNextVersion()) { bool isSuccess = true; foreach (var testDir in this.directories) { uint offs = CalcOffset(testDir.HashedOffsetPosition, testDir.HashedOffset); if (offs < this.header.HeaderSize || offs + 1 > this.fileStream.Length) // dir offset out of file size. { isSuccess = false; break; } this.fileStream.Position = offs; if (this.fileStream.ReadByte() != 0) // dir data only contains one byte: 0x00 { isSuccess = false; break; } } if (isSuccess) { this.header.VersionChecked = true; break; } } return(this.header.VersionChecked); } if (!this.header.VersionChecked) { //选择最小的img作为实验品 Wz_Image minSizeImg = null; List <Wz_Image> imgList = new List <Wz_Image>(this.imageCount); foreach (var img in (EnumerableAllWzImage(this.node).Where(_img => _img.WzFile == this))) { if (img.Size >= 20 && (minSizeImg == null || img.Size < minSizeImg.Size)) { minSizeImg = img; } imgList.Add(img); } if (minSizeImg == null && imgList.Count > 0) { minSizeImg = imgList[0]; } if (minSizeImg != null) { DetectWithWzImage(minSizeImg); } else if (this.directories.Count > 0) { DetectWithAllWzDir(); } if (this.header.VersionChecked) //重新计算全部img { foreach (var img in imgList) { img.Offset = CalcOffset(img.HashedOffsetPosition, img.HashedOffset); } } else //最终测试失败 那就失败吧.. { this.header.VersionChecked = true; } } }
public void GetDirTree(Wz_Node parent, bool useBaseWz) { List <string> dirs = new List <string>(); string name = null; int size = 0; int cs32 = 0; //int offs = 0; bool parentBase = parent.Text.Equals("base.wz", StringComparison.CurrentCultureIgnoreCase); int count = ReadInt32(); for (int i = 0; i < count; i++) { switch ((int)this.BReader.ReadByte()) { case 0x02: name = this.ReadStringAt(this.Header.HeaderSize + 1 + this.BReader.ReadInt32()); goto case 0xffff; case 0x04: name = this.ReadString(); goto case 0xffff; case 0xffff: size = this.ReadInt32(); cs32 = this.ReadInt32(); uint pos = (uint)this.bReader.BaseStream.Position; uint hashOffset = this.bReader.ReadUInt32(); Wz_Image img = new Wz_Image(name, size, cs32, hashOffset, pos, this); Wz_Node childNode = parent.Nodes.Add(name); childNode.Value = img; img.OwnerNode = childNode; this.imageCount++; break; case 0x03: name = this.ReadString(); size = this.ReadInt32(); cs32 = this.ReadInt32(); this.FileStream.Position += 4; dirs.Add(name); break; } } foreach (string dir in dirs) { Wz_Node t = parent.Nodes.Add(dir); if (parentBase && useBaseWz) { this.WzStructure.has_basewz = true; GetDirTree(t, false); try { string filePath = Path.Combine(Path.GetDirectoryName(this.Header.FileName), dir + ".wz"); if (File.Exists(filePath)) { this.WzStructure.LoadFile(filePath, t); } } catch (Exception ex) { } } else { GetDirTree(t); } } }