diff --git a/ExploreForm.cs b/ExploreForm.cs index 7315fd8..e20e075 100644 --- a/ExploreForm.cs +++ b/ExploreForm.cs @@ -1070,6 +1070,21 @@ namespace CodeWalker return false; } + private bool CanExportXml(MainListItem item) + { + if (item == null) return false; + if (item.FileType == null) return false; + switch (item.FileType.DefaultAction) + { + case FileTypeAction.ViewYmt: + case FileTypeAction.ViewYmf: + case FileTypeAction.ViewYmap: + case FileTypeAction.ViewYtyp: + case FileTypeAction.ViewJPso: + return true; + } + return false; + } private void View(MainListItem item) @@ -1396,6 +1411,7 @@ namespace CodeWalker isfolder = (item.Folder != null); isfilesys = (item.File == null) && (item.Folder == null); canview = CanViewFile(item); + canexportxml = CanExportXml(item); isitem = true; isfile = !isfolder; canedit = editmode && !canimport; @@ -1458,15 +1474,94 @@ namespace CodeWalker } private void ExportXml() { - MessageBox.Show("Export XML TODO!"); - for (int i = 0; i < MainListView.SelectedIndices.Count; i++) + if (MainListView.SelectedIndices.Count == 1) { - var idx = MainListView.SelectedIndices[i]; - if ((idx < 0) || (idx >= CurrentFiles.Count)) continue; + var idx = MainListView.SelectedIndices[0]; + if ((idx < 0) || (idx >= CurrentFiles.Count)) return; var file = CurrentFiles[idx]; if (file.Folder == null) { - //todo: meta convert to XML and export... + if (CanExportXml(file)) + { + byte[] data = GetFileData(file); + if (data == null) + { + MessageBox.Show("Unable to extract file: " + file.Path); + return; + } + + string newfn; + string xml = MetaXml.GetXml(file.File, data, out newfn); + if (string.IsNullOrEmpty(xml)) + { + MessageBox.Show("Unable to convert file to XML: " + file.Path); + return; + } + + SaveFileDialog.FileName = newfn; + if (SaveFileDialog.ShowDialog() == DialogResult.OK) + { + string path = SaveFileDialog.FileName; + try + { + File.WriteAllText(path, xml); + } + catch (Exception ex) + { + MessageBox.Show("Error saving file " + path + ":\n" + ex.ToString()); + } + } + } + } + } + else + { + if (FolderBrowserDialog.ShowDialog() != DialogResult.OK) return; + string folderpath = FolderBrowserDialog.SelectedPath; + if (!folderpath.EndsWith("\\")) folderpath += "\\"; + + StringBuilder errors = new StringBuilder(); + + for (int i = 0; i < MainListView.SelectedIndices.Count; i++) + { + var idx = MainListView.SelectedIndices[i]; + if ((idx < 0) || (idx >= CurrentFiles.Count)) continue; + var file = CurrentFiles[idx]; + if (file.Folder == null) + { + if (!CanExportXml(file)) continue; + + var data = GetFileData(file); + if (data == null) + { + errors.AppendLine("Unable to extract file: " + file.Path); + continue; + } + + string newfn; + string xml = MetaXml.GetXml(file.File, data, out newfn); + if (string.IsNullOrEmpty(xml)) + { + errors.AppendLine("Unable to convert file to XML: " + file.Path); + continue; + } + + var path = folderpath + newfn; + try + { + File.WriteAllText(path, xml); + } + catch (Exception ex) + { + errors.AppendLine("Error saving file " + path + ":\n" + ex.ToString()); + } + } + } + + string errstr = errors.ToString(); + if (!string.IsNullOrEmpty(errstr)) + { + MessageBox.Show("Errors were encountered:\n" + errstr); } } } diff --git a/Forms/MetaForm.cs b/Forms/MetaForm.cs index e0d1297..dc2f773 100644 --- a/Forms/MetaForm.cs +++ b/Forms/MetaForm.cs @@ -177,67 +177,50 @@ namespace CodeWalker.Forms public void LoadMeta(YmtFile ymt) { - var fn = (ymt?.RpfFileEntry?.Name) ?? ""; - if (ymt.Meta != null) { LoadMeta(ymt.Meta); fn += ".xml"; } - else if (ymt.Pso != null) { LoadMeta(ymt.Pso); fn += ".pso.xml"; } - else if (ymt.Rbf != null) { LoadMeta(ymt.Rbf); fn += ".rbf.xml"; } + string fn; + Xml = MetaXml.GetXml(ymt, out fn); FileName = fn; RawPropertyGrid.SelectedObject = ymt; + modified = false; } public void LoadMeta(YmfFile ymf) { - var fn = (ymf?.FileEntry?.Name) ?? ""; - if (ymf.Meta != null) { LoadMeta(ymf.Meta); fn += ".xml"; } - else if (ymf.Pso != null) { LoadMeta(ymf.Pso); fn += ".pso.xml"; } - else if (ymf.Rbf != null) { LoadMeta(ymf.Rbf); fn += ".rbf.xml"; } + string fn; + Xml = MetaXml.GetXml(ymf, out fn); FileName = fn; RawPropertyGrid.SelectedObject = ymf; + modified = false; } public void LoadMeta(YmapFile ymap) { - var fn = (ymap?.RpfFileEntry?.Name) ?? ""; - if (ymap.Meta != null) { LoadMeta(ymap.Meta); fn += ".xml"; } - else if (ymap.Pso != null) { LoadMeta(ymap.Pso); fn += ".pso.xml"; } - else if (ymap.Rbf != null) { LoadMeta(ymap.Rbf); fn += ".rbf.xml"; } + string fn; + Xml = MetaXml.GetXml(ymap, out fn); FileName = fn; RawPropertyGrid.SelectedObject = ymap; + modified = false; } public void LoadMeta(YtypFile ytyp) { - var fn = (ytyp?.FileEntry?.Name) ?? ""; - if (ytyp.Meta != null) { LoadMeta(ytyp.Meta); fn += ".xml"; } - else if (ytyp.Pso != null) { LoadMeta(ytyp.Pso); fn += ".pso.xml"; } - else if (ytyp.Rbf != null) { LoadMeta(ytyp.Rbf); fn += ".rbf.xml"; } + string fn; + Xml = MetaXml.GetXml(ytyp, out fn); FileName = fn; RawPropertyGrid.SelectedObject = ytyp; + modified = false; } public void LoadMeta(JPsoFile jpso) { - var fn = jpso?.FileEntry?.Name ?? ""; - if (jpso.Pso != null) { LoadMeta(jpso.Pso); fn += ".pso.xml"; } + string fn; + Xml = MetaXml.GetXml(jpso, out fn); FileName = fn; RawPropertyGrid.SelectedObject = jpso; + modified = false; } public void LoadMeta(CutFile cut) { - var fn = cut?.FileEntry?.Name ?? ""; - if (cut.Pso != null) { LoadMeta(cut.Pso); fn += ".pso.xml"; } + string fn; + Xml = MetaXml.GetXml(cut, out fn); FileName = fn; RawPropertyGrid.SelectedObject = cut; - } - public void LoadMeta(Meta meta) - { - Xml = MetaXml.GetXml(meta); - modified = false; - } - public void LoadMeta(PsoFile pso) - { - Xml = PsoXml.GetXml(pso); - modified = false; - } - public void LoadMeta(RbfFile rbf) - { - Xml = RbfXml.GetXml(rbf); modified = false; } diff --git a/GameFiles/MetaTypes/MetaXml.cs b/GameFiles/MetaTypes/MetaXml.cs index 5245a59..b85e24a 100644 --- a/GameFiles/MetaTypes/MetaXml.cs +++ b/GameFiles/MetaTypes/MetaXml.cs @@ -11,6 +11,101 @@ namespace CodeWalker.GameFiles public class MetaXml : MetaXmlBase { + public static string GetXml(RpfFileEntry e, byte[] data, out string filename) + { + var fn = e.Name; + var fnl = fn.ToLowerInvariant(); + if (fnl.EndsWith(".ymt")) + { + YmtFile ymt = RpfFile.GetFile(e, data); + return GetXml(ymt, out filename); + } + else if (fnl.EndsWith(".ymf")) + { + YmfFile ymf = RpfFile.GetFile(e, data); + return GetXml(ymf, out filename); + } + else if (fnl.EndsWith(".ymap")) + { + YmapFile ymap = RpfFile.GetFile(e, data); + return GetXml(ymap, out filename); + } + else if (fnl.EndsWith(".ytyp")) + { + YtypFile ytyp = RpfFile.GetFile(e, data); + return GetXml(ytyp, out filename); + } + else if (fnl.EndsWith(".pso")) + { + JPsoFile pso = RpfFile.GetFile(e, data); + return GetXml(pso, out filename); + } + else if (fnl.EndsWith(".cut")) + { + CutFile cut = RpfFile.GetFile(e, data); + return GetXml(cut, out filename); + } + filename = fn; + return string.Empty; + } + public static string GetXml(YmtFile ymt, out string filename) + { + var fn = (ymt?.RpfFileEntry?.Name) ?? ""; + if (ymt.Meta != null) { filename = fn + ".xml"; return GetXml(ymt.Meta); } + else if (ymt.Pso != null) { filename = fn + ".pso.xml"; return PsoXml.GetXml(ymt.Pso); } + else if (ymt.Rbf != null) { filename = fn + ".rbf.xml"; return RbfXml.GetXml(ymt.Rbf); } + filename = string.Empty; + return string.Empty; + } + public static string GetXml(YmfFile ymf, out string filename) + { + var fn = (ymf?.FileEntry?.Name) ?? ""; + if (ymf.Meta != null) { filename = fn + ".xml"; return GetXml(ymf.Meta); } + else if (ymf.Pso != null) { filename = fn + ".pso.xml"; return PsoXml.GetXml(ymf.Pso); } + else if (ymf.Rbf != null) { filename = fn + ".rbf.xml"; return RbfXml.GetXml(ymf.Rbf); } + filename = string.Empty; + return string.Empty; + } + public static string GetXml(YmapFile ymap, out string filename) + { + var fn = (ymap?.RpfFileEntry?.Name) ?? ""; + if (ymap.Meta != null) { filename = fn + ".xml"; return GetXml(ymap.Meta); } + else if (ymap.Pso != null) { filename = fn + ".pso.xml"; return PsoXml.GetXml(ymap.Pso); } + else if (ymap.Rbf != null) { filename = fn + ".rbf.xml"; return RbfXml.GetXml(ymap.Rbf); } + filename = string.Empty; + return string.Empty; + } + public static string GetXml(YtypFile ytyp, out string filename) + { + var fn = (ytyp?.FileEntry?.Name) ?? ""; + if (ytyp.Meta != null) { filename = fn + ".xml"; return GetXml(ytyp.Meta); } + else if (ytyp.Pso != null) { filename = fn + ".pso.xml"; return PsoXml.GetXml(ytyp.Pso); } + else if (ytyp.Rbf != null) { filename = fn + ".rbf.xml"; return RbfXml.GetXml(ytyp.Rbf); } + filename = string.Empty; + return string.Empty; + } + public static string GetXml(JPsoFile pso, out string filename) + { + var fn = (pso?.FileEntry?.Name) ?? ""; + if (pso.Pso != null) { filename = fn + ".pso.xml"; return PsoXml.GetXml(pso.Pso); } + filename = string.Empty; + return string.Empty; + } + public static string GetXml(CutFile cut, out string filename) + { + var fn = (cut?.FileEntry?.Name) ?? ""; + if (cut.Pso != null) { filename = fn + ".pso.xml"; return PsoXml.GetXml(cut.Pso); } + filename = string.Empty; + return string.Empty; + } + + + + + + + + public static string GetXml(Meta meta) {