public void LoadImg(string fileName) { this.WzNode = new Wz_Node(Path.GetFileName(fileName)); this.LoadFileImg(fileName, WzNode); }
public void LoadWzFolder(string folder, ref Wz_Node node, bool useBaseWz = false) { string baseName = Path.Combine(folder, Path.GetFileName(folder)); string entryWzFileName = Path.ChangeExtension(baseName, ".wz"); string iniFileName = Path.ChangeExtension(baseName, ".ini"); Func <int, string> extraWzFileName = _index => Path.ChangeExtension($"{baseName}_{_index:D3}", ".wz"); // load iniFile int?lastWzIndex = null; if (File.Exists(iniFileName)) { var iniConf = File.ReadAllLines(iniFileName).Select(row => { string[] columns = row.Split('|'); string key = columns.Length > 0 ? columns[0] : null; string value = columns.Length > 1 ? columns[1] : null; return(new KeyValuePair <string, string>(key, value)); }); if (int.TryParse(iniConf.FirstOrDefault(kv => kv.Key == "LastWzIndex").Value, out var indexFromIni)) { lastWzIndex = indexFromIni; } } // ini file missing or unexpected format if (lastWzIndex == null) { for (int i = 0; ; i++) { string extraFile = extraWzFileName(i); if (!File.Exists(extraFile)) { break; } lastWzIndex = i; } } // load entry file if (node == null) { node = new Wz_Node(Path.GetFileName(entryWzFileName)); } var entryWzf = this.LoadFile(entryWzFileName, node, useBaseWz, true); // load extra file if (lastWzIndex != null) { for (int i = 0, j = lastWzIndex.Value; i <= j; i++) { string extraFile = extraWzFileName(i); var tempNode = new Wz_Node(Path.GetFileName(extraFile)); var extraWzf = this.LoadFile(extraFile, tempNode, false, true); /* * there is a little hack here, we'll move all img to the entry file, and each img still refers to the original wzfile. * before: * base.wz (Wz_File) * |- a.img (Wz_Image) * base_000.wz (Wz_File) * |- b.img (Wz_Image) { wz_f = base_000.wz } * * after: * base.wz (Wz_File) { mergedFiles = [base_000.wz] } * |- a.img (Wz_Image) { wz_f = base.wz } * |- b.img (Wz_Image) { wz_f = base_000.wz } * * this.wz_files references all opened files so they can be closed correctly. */ entryWzf.MergeWzFile(extraWzf); } } }
public static void DumpAsXml(this Wz_Node node, XmlWriter writer) { object value = node.Value; if (value == null || value is Wz_Image) { writer.WriteStartElement("dir"); writer.WriteAttributeString("name", node.Text); } else if (value is Wz_Png) { var png = (Wz_Png)value; writer.WriteStartElement("png"); writer.WriteAttributeString("name", node.Text); using (var bmp = png.ExtractPng()) { using (var ms = new MemoryStream()) { bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png); byte[] data = ms.ToArray(); writer.WriteAttributeString("value", Convert.ToBase64String(data)); } } } else if (value is Wz_Uol) { var uol = (Wz_Uol)value; writer.WriteStartElement("uol"); writer.WriteAttributeString("name", node.Text); writer.WriteAttributeString("value", uol.Uol); } else if (value is Wz_Vector) { var vector = (Wz_Vector)value; writer.WriteStartElement("vector"); writer.WriteAttributeString("name", node.Text); writer.WriteAttributeString("value", $"{vector.X}, {vector.Y}"); } else if (value is Wz_Sound) { var sound = (Wz_Sound)value; writer.WriteStartElement("sound"); writer.WriteAttributeString("name", node.Text); byte[] data = sound.ExtractSound(); if (data == null) { data = new byte[sound.DataLength]; sound.WzFile.FileStream.Seek(sound.Offset, SeekOrigin.Begin); sound.WzFile.FileStream.Read(data, 0, sound.DataLength); } writer.WriteAttributeString("value", Convert.ToBase64String(data)); } else { var tag = value.GetType().Name.ToLower(); writer.WriteStartElement(tag); writer.WriteAttributeString("name", node.Text); writer.WriteAttributeString("value", value.ToString()); } //输出子节点 foreach (var child in node.Nodes) { DumpAsXml(child, writer); } //结束标识 writer.WriteEndElement(); }
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; if (willLoadBaseWz && this.WzStructure.AutoDetectExtFiles) { var baseFolder = Path.GetDirectoryName(this.header.FileName); for (int i = 0; i < dirCount; i++) { //检测文件名 var m = Regex.Match(dirs[i], @"^([A-Za-z]+)$"); if (m.Success) { //检测扩展wz文件 for (int fileID = 2; ; fileID++) { string extDirName = m.Result("$1") + fileID; string extWzFile = Path.Combine(baseFolder, extDirName + ".wz"); if (File.Exists(extWzFile) && !dirs.Take(dirCount).Any(dir => extDirName.Equals(dir, StringComparison.OrdinalIgnoreCase))) { dirs.Add(extDirName); } else { break; } } //检测KMST1058的wz文件 for (int fileID = 1; ; fileID++) { string extDirName = m.Result("$1") + fileID.ToString("D3"); string extWzFile = Path.Combine(baseFolder, extDirName + ".wz"); if (File.Exists(extWzFile) && !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(Path.GetDirectoryName(this.Header.FileName), dir + ".wz"); if (File.Exists(filePath)) { this.WzStructure.LoadFile(filePath, t); } } catch (Exception ex) { } } else { GetDirTree(t, false); } } parent.Nodes.Trim(); }
public void GetDirTree(Wz_Node parent) { GetDirTree(parent, true); }
private void ExtractImg(long offset, Wz_Node parent, int eob) { int entries = 0; string tag = this.WzFile.ReadString(offset); switch (tag) { case "Property": this.WzFile.FileStream.Position += 2; entries = this.WzFile.ReadInt32(); for (int i = 0; i < entries; i++) { ExtractValue(offset, parent); } break; case "Shape2D#Vector2D": parent.Value = new Wz_Vector(this.WzFile.ReadInt32(), this.WzFile.ReadInt32()); break; case "Canvas": this.WzFile.FileStream.Position++; if (this.WzFile.BReader.ReadByte() == 0x01) { this.WzFile.FileStream.Position += 2; entries = this.WzFile.ReadInt32(); for (int i = 0; i < entries; i++) { ExtractValue(offset, parent); } } int w = this.WzFile.ReadInt32(); int h = this.WzFile.ReadInt32(); int form = this.WzFile.ReadInt32() + this.WzFile.BReader.ReadByte(); this.WzFile.FileStream.Position += 4; int bufsize = this.WzFile.BReader.ReadInt32(); parent.Value = new Wz_Png(w, h, bufsize - 1, form, (int)this.WzFile.FileStream.Position + 1, this.WzFile); this.WzFile.FileStream.Position += bufsize; break; case "Shape2D#Convex2D": entries = this.WzFile.ReadInt32(); for (int i = 0; i < entries; i++) { ExtractImg(offset, parent, 0); } break; case "Sound_DX8": this.WzFile.FileStream.Position++; int len = this.WzFile.ReadInt32(); int ms = this.WzFile.ReadInt32(); int headerLen = eob - len - (int)this.WzFile.FileStream.Position; byte[] header = this.WzFile.BReader.ReadBytes(headerLen); parent.Value = new Wz_Sound(eob - len, len, header, ms, this.WzFile); this.WzFile.FileStream.Position = eob; break; case "UOL": this.WzFile.FileStream.Position++; parent.Value = new Wz_Uol(this.WzFile.ReadString(offset)); break; default: throw new Exception("Unknown wz tag: " + tag); } }
public void LoadFile(string fileName, Wz_Node node) { this.LoadFile(fileName, node, 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); } } }