This commit is contained in:
dexy 2024-07-12 09:43:53 +10:00
parent 252435208a
commit 6cf72c4b74
2 changed files with 67 additions and 17 deletions

View File

@ -1436,11 +1436,15 @@ namespace CodeWalker.GameFiles
} }
public long GetDefragmentedFileSize() public long GetDefragmentedFileSize(bool recursive = true)
{ {
//this represents the size the file would be when fully defragmented. //this represents the size the file would be when fully defragmented.
if (!recursive)
{
uint blockcount = GetHeaderBlockCount(); uint blockcount = GetHeaderBlockCount();
foreach (var entry in AllEntries) foreach (var entry in AllEntries)
{ {
var fentry = entry as RpfFileEntry; var fentry = entry as RpfFileEntry;
@ -1452,6 +1456,31 @@ namespace CodeWalker.GameFiles
return (long)blockcount * 512; return (long)blockcount * 512;
} }
else
{
uint blockcount = GetHeaderBlockCount();
long childRpfsSize = 0;
foreach (var entry in AllEntries)
{
var fentry = entry as RpfFileEntry;
if (fentry != null)
{
var childRpf = this.FindChildArchive(fentry);
if (childRpf == null)
{
blockcount += GetBlockCount(fentry.GetFileSize());
}
else
{
childRpfsSize += childRpf.GetDefragmentedFileSize(true);
}
}
}
return (long)blockcount * 512 + childRpfsSize;
}
}
private void UpdateStartPos(long newpos) private void UpdateStartPos(long newpos)
@ -1914,10 +1943,25 @@ namespace CodeWalker.GameFiles
} }
public static void Defragment(RpfFile file, Action<string, float> progress = null) public static void Defragment(RpfFile file, Action<string, float> progress = null, bool recursive = true)
{ {
if (file?.AllEntries == null) return; if (file?.AllEntries == null) return;
if (recursive)
{
foreach (var entry in file?.AllEntries)
{
if (entry is RpfFileEntry)
{
var childRpf = file.FindChildArchive(entry as RpfFileEntry);
if (childRpf != null)
{
Defragment(childRpf, null, true);
}
}
}
}
string fpath = file.GetPhysicalFilePath(); string fpath = file.GetPhysicalFilePath();
using (var fstream = File.Open(fpath, FileMode.Open, FileAccess.ReadWrite)) using (var fstream = File.Open(fpath, FileMode.Open, FileAccess.ReadWrite))
{ {

View File

@ -3170,7 +3170,7 @@ namespace CodeWalker
Form form = new Form() { Form form = new Form() {
Width = 450, Width = 450,
Height = 250, Height = 290,
FormBorderStyle = FormBorderStyle.FixedDialog, FormBorderStyle = FormBorderStyle.FixedDialog,
Text = "Defragment RPF Archive - CodeWalker by dexyfex", Text = "Defragment RPF Archive - CodeWalker by dexyfex",
StartPosition = FormStartPosition.CenterParent, StartPosition = FormStartPosition.CenterParent,
@ -3181,14 +3181,19 @@ namespace CodeWalker
var addLabel = new Func<int, string, Control>((y, t) => { var addLabel = new Func<int, string, Control>((y, t) => {
return addCtrl(new Label() { Left = 30, Top = y, Width = 370, Height = 20, Text = t }); return addCtrl(new Label() { Left = 30, Top = y, Width = 370, Height = 20, Text = t });
}); });
var addCheckbox = new Func<int, string, bool, Control>((y, t, defaultVal) =>
{
return addCtrl(new CheckBox() { Left = 33, Top = y, Width = 370, Height = 20, Text = t, Checked = defaultVal });
});
var rpfNameLabel = addLabel(20, "Archive: " + rpf.Path); var rpfNameLabel = addLabel(20, "Archive: " + rpf.Path);
var curSizeLabel = addLabel(40, string.Empty); var curSizeLabel = addLabel(40, string.Empty);
var newSizeLabel = addLabel(60, string.Empty); var newSizeLabel = addLabel(60, string.Empty);
var redSizeLabel = addLabel(80, string.Empty); var redSizeLabel = addLabel(80, string.Empty);
var statusLabel = addLabel(110, string.Empty); var statusLabel = addLabel(110, string.Empty);
var progressBar = addCtrl(new ProgressBar() { Left = 30, Top = 130, Width = 370, Height = 20, Minimum = 0, Maximum = 1000, MarqueeAnimationSpeed = 50 }) as ProgressBar; CheckBox recursiveCheckbox = addCheckbox(130, "Recursive", true) as CheckBox;
var beginButton = addCtrl(new Button() { Text = "Begin Defragment", Left = 30, Top = 170, Width = 120 }) as Button; var progressBar = addCtrl(new ProgressBar() { Left = 30, Top = 180, Width = 370, Height = 20, Minimum = 0, Maximum = 1000, MarqueeAnimationSpeed = 50 }) as ProgressBar;
var closeButton = addCtrl(new Button() { Text = "Close", Left = 320, Top = 170, Width = 80 }) as Button; var beginButton = addCtrl(new Button() { Text = "Begin Defragment", Left = 30, Top = 210, Width = 120 }) as Button;
var closeButton = addCtrl(new Button() { Text = "Close", Left = 320, Top = 210, Width = 80 }) as Button;
var inProgress = false; var inProgress = false;
var updateProgress = new Action<string, float>((s, p) => { form.Invoke(new Action(() => { var updateProgress = new Action<string, float>((s, p) => { form.Invoke(new Action(() => {
statusLabel.Text = s; statusLabel.Text = s;
@ -3196,7 +3201,7 @@ namespace CodeWalker
}));}); }));});
var updateSizeLabels = new Action<bool>((init) => { var updateSizeLabels = new Action<bool>((init) => {
var curSize = rpf.FileSize; var curSize = rpf.FileSize;
var newSize = rpf.GetDefragmentedFileSize(); var newSize = rpf.GetDefragmentedFileSize(recursiveCheckbox.Checked);
var redSize = curSize - newSize; var redSize = curSize - newSize;
curSizeLabel.Text = "Archive current size: " + TextUtil.GetBytesReadable(curSize); curSizeLabel.Text = "Archive current size: " + TextUtil.GetBytesReadable(curSize);
newSizeLabel.Text = "Defragmented size: " + TextUtil.GetBytesReadable(newSize); newSizeLabel.Text = "Defragmented size: " + TextUtil.GetBytesReadable(newSize);
@ -3212,7 +3217,7 @@ namespace CodeWalker
if (!EnsureRpfValidEncryption(rpf)) return; if (!EnsureRpfValidEncryption(rpf)) return;
inProgress = true; inProgress = true;
enableUi(false); enableUi(false);
RpfFile.Defragment(rpf, updateProgress); RpfFile.Defragment(rpf, updateProgress, recursiveCheckbox.Checked);
updateProgress("Defragment complete.", 1.0f); updateProgress("Defragment complete.", 1.0f);
enableUi(true); enableUi(true);
form.Invoke(new Action(() => { updateSizeLabels(false); })); form.Invoke(new Action(() => { updateSizeLabels(false); }));
@ -3221,6 +3226,7 @@ namespace CodeWalker
updateSizeLabels(true); updateSizeLabels(true);
beginButton.Click += (sender, e) => { defragment(); }; beginButton.Click += (sender, e) => { defragment(); };
closeButton.Click += (sender, e) => { form.Close(); }; closeButton.Click += (sender, e) => { form.Close(); };
recursiveCheckbox.Click += (sender, e) => { updateSizeLabels(false); };
form.FormClosing += (s, e) => { e.Cancel = inProgress; }; form.FormClosing += (s, e) => { e.Cancel = inProgress; };
form.ShowDialog(this); form.ShowDialog(this);
RefreshMainListView(); RefreshMainListView();