pk3DS/pk3DS.WinForms/Subforms/EnhancedRestore.cs
2024-06-02 18:30:56 -05:00

160 lines
5.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using pk3DS.Core;
namespace pk3DS.WinForms;
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++)
{
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"))
: [];
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(string src, string dest, string disp = null)
{
public readonly string DisplayName = disp ?? Path.GetFileName(src);
public readonly string FileLocation = src;
public readonly string Destination = dest;
}
private readonly List<List<RestoreInfo>> Items = [];
private readonly List<CheckedListBox> List = [];
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(src)) // only restore files that exist
File.Copy(src, dest, overwrite: true); count++;
}
catch { Debug.WriteLine("Unable to overwrite backup: " + dest); }
}
}
WinFormsUtil.Alert($"Restored {count} file(s).", "The program will now close.");
Environment.Exit(-1); // 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);
}
}