Add gui for file restoring

This commit is contained in:
Kurt 2017-10-04 21:19:55 -07:00
parent d3519e8961
commit 1ae709b79c
6 changed files with 431 additions and 20 deletions

View File

@ -6,10 +6,10 @@ namespace pk3DS.Core
{
public static class GameBackup
{
private const string bakpath = "backup";
private const string bakexefs = "exefs";
private const string baka = "a";
private const string bakdll = "dll";
public const string bakpath = "backup";
public const string bakexefs = "exefs";
public const string baka = "a";
public const string bakdll = "dll";
public static void backupFiles(this GameConfig config, bool overwrite = false)
{
@ -212,7 +212,7 @@ private static int restoreDLL(GameConfig config, string bak_dll)
string dest = Path.Combine(CRRBAKPATH, Path.GetFileName(src));
if (File.Exists(dest))
{
File.Copy(dest, src);
File.Copy(dest, src, true);
count++;
}
else

View File

@ -84,21 +84,7 @@ private void L_GARCInfo_Click(object sender, EventArgs e)
try { Clipboard.SetText(s); }
catch { WinFormsUtil.Alert("Unable to copy to Clipboard."); }
}
private void L_Game_Click(object sender, EventArgs e)
{
if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Restore Original Files?"))
return;
string[] result = Config.restoreFiles();
if (result.Length == 2) // error
{
WinFormsUtil.Alert(result);
return;
}
WinFormsUtil.Alert("Restored files:", result[0], "The program will now close.");
Application.Exit(); // do not call closing events that repackage personal/gametext
}
private void L_Game_Click(object sender, EventArgs e) => new EnhancedRestore(Config).ShowDialog();
private void B_Open_Click(object sender, EventArgs e)
{

127
pk3DS/Subforms/EnhancedRestore.Designer.cs generated Normal file
View File

@ -0,0 +1,127 @@
namespace pk3DS
{
partial class EnhancedRestore
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.tabControl1 = new System.Windows.Forms.TabControl();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.tabPage3 = new System.Windows.Forms.TabPage();
this.B_Go = new System.Windows.Forms.Button();
this.B_All = new System.Windows.Forms.Button();
this.tabControl1.SuspendLayout();
this.SuspendLayout();
//
// tabControl1
//
this.tabControl1.Controls.Add(this.tabPage1);
this.tabControl1.Controls.Add(this.tabPage2);
this.tabControl1.Controls.Add(this.tabPage3);
this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabControl1.Location = new System.Drawing.Point(0, 0);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(284, 261);
this.tabControl1.TabIndex = 0;
//
// tabPage1
//
this.tabPage1.Location = new System.Drawing.Point(4, 22);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
this.tabPage1.Size = new System.Drawing.Size(276, 235);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "GARC";
this.tabPage1.UseVisualStyleBackColor = true;
//
// tabPage2
//
this.tabPage2.Location = new System.Drawing.Point(4, 22);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
this.tabPage2.Size = new System.Drawing.Size(276, 235);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "ExeFS";
this.tabPage2.UseVisualStyleBackColor = true;
//
// tabPage3
//
this.tabPage3.Location = new System.Drawing.Point(4, 22);
this.tabPage3.Name = "tabPage3";
this.tabPage3.Size = new System.Drawing.Size(276, 235);
this.tabPage3.TabIndex = 2;
this.tabPage3.Text = "CRO";
this.tabPage3.UseVisualStyleBackColor = true;
//
// B_Go
//
this.B_Go.Location = new System.Drawing.Point(206, -1);
this.B_Go.Name = "B_Go";
this.B_Go.Size = new System.Drawing.Size(75, 23);
this.B_Go.TabIndex = 0;
this.B_Go.Text = "OK";
this.B_Go.UseVisualStyleBackColor = true;
this.B_Go.Click += new System.EventHandler(this.B_Go_Click);
//
// B_All
//
this.B_All.Location = new System.Drawing.Point(156, -1);
this.B_All.Name = "B_All";
this.B_All.Size = new System.Drawing.Size(45, 23);
this.B_All.TabIndex = 1;
this.B_All.Text = "All";
this.B_All.UseVisualStyleBackColor = true;
this.B_All.Click += new System.EventHandler(this.B_All_Click);
//
// EnhancedRestore
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 261);
this.Controls.Add(this.B_Go);
this.Controls.Add(this.B_All);
this.Controls.Add(this.tabControl1);
this.MaximizeBox = false;
this.Name = "EnhancedRestore";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "File Restore";
this.tabControl1.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TabControl tabControl1;
private System.Windows.Forms.TabPage tabPage1;
private System.Windows.Forms.TabPage tabPage2;
private System.Windows.Forms.TabPage tabPage3;
private System.Windows.Forms.Button B_Go;
private System.Windows.Forms.Button B_All;
}
}

View File

@ -0,0 +1,169 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using pk3DS.Core;
namespace pk3DS
{
public partial class EnhancedRestore : Form
{
public EnhancedRestore(GameConfig config)
{
InitializeComponent();
LoadBackupFileInfo(config);
}
private void LoadBackupFileInfo(GameConfig config)
{
var gamePath = new DirectoryInfo(config.RomFS).Parent;
string gameFolder = gamePath.Name;
string gameBackup = Path.Combine(GameBackup.bakpath, gameFolder);
string bak_a = Path.Combine(gameBackup, GameBackup.baka);
string bak_exefs = Path.Combine(gameBackup, GameBackup.bakexefs);
string bak_dll = Path.Combine(gameBackup, GameBackup.bakdll);
var garcs = GetRestorableGarcs(config, bak_a);
var exefs = GetRestorableExeFS(config, bak_exefs);
var cros = GetRestorableCROs(config, bak_dll);
var files = new[] { garcs, exefs, cros };
// load files to UI
for (int i = 0; i < files.Length; i++)
{
Items.Add(new List<RestoreInfo>());
var tab = tabControl1.TabPages[i];
var clb = new CheckedListBox
{
Dock = DockStyle.Fill,
CheckOnClick = true,
Margin = new Padding(0),
Padding = new Padding(0)
};
foreach (var z in files[i])
{
Items[i].Add(z);
clb.Items.Add(z.DisplayName, true);
}
List.Add(clb);
tab.Controls.Add(clb);
}
}
private static IEnumerable<RestoreInfo> GetRestorableCROs(GameConfig config, string bak_dll)
{
string path = config.RomFS;
string[] files = Directory.GetFiles(path);
string[] CROs = files.Where(x => new FileInfo(x).Name.Contains("Dll")).ToArray();
string[] CRSs = files.Where(x => new FileInfo(x).Extension.Contains("crs")).ToArray();
var CRRs = Directory.Exists(Path.Combine(path, ".crr"))
? Directory.EnumerateFiles(Path.Combine(path, ".crr"))
: new string[0];
string CRRBAKPATH = Path.Combine(bak_dll, ".crr");
foreach (string src in CROs.Concat(CRSs))
{
string dest = Path.Combine(bak_dll, Path.GetFileName(src));
if (File.Exists(dest))
yield return new RestoreInfo(dest, src);
}
// Separate folder for the .crr
foreach (string src in CRRs)
{
string dest = Path.Combine(CRRBAKPATH, Path.GetFileName(src));
if (File.Exists(dest))
yield return new RestoreInfo(dest, src);
}
}
private static IEnumerable<RestoreInfo> GetRestorableGarcs(GameConfig config, string bak_a)
{
var files = config.Files.Select(file => file.Name);
foreach (var f in files)
{
string GARC = config.getGARCFileName(f);
string name = $"{f} ({GARC.Replace(Path.DirectorySeparatorChar.ToString(), "")})";
string src = Path.Combine(config.RomFS, GARC);
string dest = Path.Combine(bak_a, name);
if (!File.Exists(dest))
continue;
string dispname = Path.GetFileNameWithoutExtension(dest);
var split = dispname.Split(' ');
dispname = $"{split[1]} {split[0]}";
yield return new RestoreInfo(dest, src, dispname);
}
}
private static IEnumerable<RestoreInfo> GetRestorableExeFS(GameConfig config, string bak_exefs)
{
var files = Directory.GetFiles(config.ExeFS);
foreach (var src in files)
{
string dest = Path.Combine(bak_exefs, Path.GetFileName(src));
if (File.Exists(dest))
yield return new RestoreInfo(dest, src);
}
}
private class RestoreInfo
{
public readonly string DisplayName;
public readonly string FileLocation;
public readonly string Destination;
public RestoreInfo(string src, string dest, string disp = null)
{
FileLocation = src;
Destination = dest;
DisplayName = disp ?? Path.GetFileName(src);
}
}
private readonly List<List<RestoreInfo>> Items = new List<List<RestoreInfo>>();
private readonly List<CheckedListBox> List = new List<CheckedListBox>();
private void B_Go_Click(object sender, EventArgs e)
{
// restore files that are selected
int count = 0;
for (int i = 0; i < List.Count; i++)
{
for (int j = 0; j < List[i].Items.Count; j++)
{
if (!List[i].GetItemChecked(j))
continue;
var item = Items[i][j];
string dest = item.Destination;
string src = item.FileLocation;
try
{
if (File.Exists(dest)) // only restore files that exist
File.Copy(dest, src, overwrite: true); count++;
}
catch { Debug.WriteLine("Unable to overwrite backup: " + dest); }
}
}
WinFormsUtil.Alert($"Restored {count} file(s).", "The program will now close.");
Application.Exit(); // do not call closing events that repackage personal/gametext
}
private void B_All_Click(object sender, EventArgs e)
{
var clb = List[tabControl1.SelectedIndex];
for (int i = 0; i < clb.Items.Count; i++)
clb.SetItemChecked(i, ModifierKeys != Keys.Control);
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -68,6 +68,12 @@
<ItemGroup>
<Compile Include="ARCUtil.cs" />
<Compile Include="GarcUtil.cs" />
<Compile Include="Subforms\EnhancedRestore.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Subforms\EnhancedRestore.Designer.cs">
<DependentUpon>EnhancedRestore.cs</DependentUpon>
</Compile>
<Compile Include="WinFormsUtil.cs" />
<Compile Include="Misc\ErrorWindow.cs">
<SubType>Form</SubType>
@ -378,6 +384,9 @@
<EmbeddedResource Include="Misc\ErrorWindow.resx">
<DependentUpon>ErrorWindow.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Subforms\EnhancedRestore.resx">
<DependentUpon>EnhancedRestore.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Subforms\Gen7\EggMoveEditor7.resx">
<DependentUpon>EggMoveEditor7.cs</DependentUpon>
</EmbeddedResource>