From d028f6e8761643feb65d8ae305ddb717c7bee680 Mon Sep 17 00:00:00 2001 From: dexy Date: Sun, 20 Jan 2019 10:27:46 +1100 Subject: [PATCH] XML, .meta, .txt files can now be edited directly when RPF Explorer in edit mode --- ExploreForm.cs | 16 ++++----- Forms/TextForm.cs | 80 +++++++++++++++++++++++++++++++++++++++++-- Forms/XmlForm.cs | 86 +++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 168 insertions(+), 14 deletions(-) diff --git a/ExploreForm.cs b/ExploreForm.cs index 82f73c5..8525d7e 100644 --- a/ExploreForm.cs +++ b/ExploreForm.cs @@ -1361,10 +1361,10 @@ namespace CodeWalker switch (ft.DefaultAction) { case FileTypeAction.ViewText: - ViewText(name, path, data); + ViewText(name, path, data, item.File); break; case FileTypeAction.ViewXml: - ViewXml(name, path, data); + ViewXml(name, path, data, item.File); break; case FileTypeAction.ViewYtd: ViewYtd(name, path, data, item.File); @@ -1467,19 +1467,19 @@ namespace CodeWalker f.Show(); f.LoadData(name, path, data); } - private void ViewXml(string name, string path, byte[] data) + private void ViewXml(string name, string path, byte[] data, RpfFileEntry e) { string xml = Encoding.UTF8.GetString(data); - XmlForm f = new XmlForm(); + XmlForm f = new XmlForm(this); f.Show(); - f.LoadXml(name, path, xml); + f.LoadXml(name, path, xml, e); } - private void ViewText(string name, string path, byte[] data) + private void ViewText(string name, string path, byte[] data, RpfFileEntry e) { string txt = Encoding.UTF8.GetString(data); - TextForm f = new TextForm(); + TextForm f = new TextForm(this); f.Show(); - f.LoadText(name, path, txt); + f.LoadText(name, path, txt, e); } private void ViewYtd(string name, string path, byte[] data, RpfFileEntry e) { diff --git a/Forms/TextForm.cs b/Forms/TextForm.cs index 484dbcd..3b7929d 100644 --- a/Forms/TextForm.cs +++ b/Forms/TextForm.cs @@ -1,4 +1,5 @@ -using CodeWalker.Properties; +using CodeWalker.GameFiles; +using CodeWalker.Properties; using FastColoredTextBoxNS; using System; using System.Collections.Generic; @@ -40,19 +41,26 @@ namespace CodeWalker.Forms private bool modified = false; + private ExploreForm exploreForm = null; + public RpfFileEntry rpfFileEntry { get; private set; } = null; - public TextForm() + + + public TextForm(ExploreForm owner) { + exploreForm = owner; + InitializeComponent(); } - public void LoadText(string filename, string filepath, string text) + public void LoadText(string filename, string filepath, string text, RpfFileEntry e) { FileName = filename; FilePath = filepath; TextValue = text; + rpfFileEntry = e; modified = false; } @@ -128,6 +136,16 @@ namespace CodeWalker.Forms } private void SaveDocument(bool saveAs = false) { + if (saveAs == false) + { + if (SaveToRPF(textValue)) + { + return; + } + //if saving to RPF failed for whatever reason, fallback to saving the file in the filesystem. + saveAs = true; + } + if (string.IsNullOrEmpty(FileName)) saveAs = true; if (string.IsNullOrEmpty(FilePath)) saveAs = true; else if ((FilePath.ToLowerInvariant().StartsWith(GTAFolder.CurrentGTAFolder.ToLowerInvariant()))) saveAs = true; @@ -154,6 +172,62 @@ namespace CodeWalker.Forms FileName = new FileInfo(fn).Name; } + + + + private bool SaveToRPF(string txt) + { + + if (!(exploreForm?.EditMode ?? false)) return false; + if (rpfFileEntry?.Parent == null) return false; + + byte[] data = null; + + data = Encoding.UTF8.GetBytes(txt); + + if (data == null) + { + MessageBox.Show("Unspecified error - data was null!", "Cannot save file"); + return false; + } + + if (!rpfFileEntry.Path.ToLowerInvariant().StartsWith("mods")) + { + if (MessageBox.Show("This file is NOT located in the mods folder - Are you SURE you want to save this file?\r\nWARNING: This could cause permanent damage to your game!!!", "WARNING: Are you sure about this?", MessageBoxButtons.YesNo) != DialogResult.Yes) + { + return false;//that was a close one + } + } + + try + { + if (!(exploreForm?.EnsureRpfValidEncryption(rpfFileEntry.File) ?? false)) return false; + + var newentry = RpfFile.CreateFile(rpfFileEntry.Parent, rpfFileEntry.Name, data); + if (newentry != rpfFileEntry) + { } + rpfFileEntry = newentry; + + exploreForm?.RefreshMainListViewInvoke(); //update the file details in explorer... + + modified = false; + + StatusLabel.Text = "Text file saved successfully at " + DateTime.Now.ToString(); + + return true; //victory! + } + catch (Exception ex) + { + MessageBox.Show("Error saving file to RPF! The RPF archive may be corrupted...\r\n" + ex.ToString(), "Really Bad Error"); + } + + return false; + } + + + + + private void MainTextBox_TextChanged(object sender, TextChangedEventArgs e) { textValue = MainTextBox.Text; diff --git a/Forms/XmlForm.cs b/Forms/XmlForm.cs index d814453..778638f 100644 --- a/Forms/XmlForm.cs +++ b/Forms/XmlForm.cs @@ -1,4 +1,5 @@ -using CodeWalker.Properties; +using CodeWalker.GameFiles; +using CodeWalker.Properties; using FastColoredTextBoxNS; using System; using System.Collections.Generic; @@ -10,6 +11,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; +using System.Xml; namespace CodeWalker.Forms { @@ -42,19 +44,25 @@ namespace CodeWalker.Forms private bool LoadingXml = false; private bool DelayHighlight = false; + private ExploreForm exploreForm = null; + public RpfFileEntry rpfFileEntry { get; private set; } = null; - public XmlForm() + + public XmlForm(ExploreForm owner) { + exploreForm = owner; + InitializeComponent(); } - public void LoadXml(string filename, string filepath, string xml) + public void LoadXml(string filename, string filepath, string xml, RpfFileEntry e) { FileName = filename; FilePath = filepath; Xml = xml; + rpfFileEntry = e; modified = false; } @@ -153,6 +161,26 @@ namespace CodeWalker.Forms } private void SaveDocument(bool saveAs = false) { + if (saveAs == false) + { + var doc = new XmlDocument(); + try + { + doc.LoadXml(xml); + } + catch (Exception ex) + { + MessageBox.Show("There's something wrong with your XML document:\r\n" + ex.Message, "Unable to parse XML"); + return; + } + if (SaveToRPF(xml)) + { + return; + } + //if saving to RPF failed for whatever reason, fallback to saving the file in the filesystem. + saveAs = true; + } + if (string.IsNullOrEmpty(FileName)) saveAs = true; if (string.IsNullOrEmpty(FilePath)) saveAs = true; else if ((FilePath.ToLowerInvariant().StartsWith(GTAFolder.CurrentGTAFolder.ToLowerInvariant()))) saveAs = true; @@ -183,6 +211,58 @@ namespace CodeWalker.Forms + private bool SaveToRPF(string txt) + { + + if (!(exploreForm?.EditMode ?? false)) return false; + if (rpfFileEntry?.Parent == null) return false; + + byte[] data = null; + + data = Encoding.UTF8.GetBytes(txt); + + if (data == null) + { + MessageBox.Show("Unspecified error - data was null!", "Cannot save XML file"); + return false; + } + + if (!rpfFileEntry.Path.ToLowerInvariant().StartsWith("mods")) + { + if (MessageBox.Show("This file is NOT located in the mods folder - Are you SURE you want to save this file?\r\nWARNING: This could cause permanent damage to your game!!!", "WARNING: Are you sure about this?", MessageBoxButtons.YesNo) != DialogResult.Yes) + { + return false;//that was a close one + } + } + + try + { + if (!(exploreForm?.EnsureRpfValidEncryption(rpfFileEntry.File) ?? false)) return false; + + var newentry = RpfFile.CreateFile(rpfFileEntry.Parent, rpfFileEntry.Name, data); + if (newentry != rpfFileEntry) + { } + rpfFileEntry = newentry; + + exploreForm?.RefreshMainListViewInvoke(); //update the file details in explorer... + + modified = false; + + StatusLabel.Text = "XML file saved successfully at " + DateTime.Now.ToString(); + + return true; //victory! + } + catch (Exception ex) + { + MessageBox.Show("Error saving file to RPF! The RPF archive may be corrupted...\r\n" + ex.ToString(), "Really Bad Error"); + } + + return false; + } + + + + Style BlueStyle = new TextStyle(Brushes.Blue, null, FontStyle.Regular);