mirror of
https://github.com/kwsch/pk3DS.git
synced 2026-04-24 15:16:50 -05:00
138 lines
4.6 KiB
C#
138 lines
4.6 KiB
C#
using pk3DS.Core;
|
|
using pk3DS.Core.CTR;
|
|
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Windows.Forms;
|
|
|
|
namespace pk3DS.WinForms;
|
|
|
|
/* GARC File Shuffler
|
|
* Shuffles the FATB table references around (Start/End/Length)
|
|
* Only shuffles nonfoldered files around.
|
|
* Backs up the original file incase the user shuffles a file with ill-effect.
|
|
*/
|
|
public partial class Shuffler : Form
|
|
{
|
|
public Shuffler()
|
|
{
|
|
InitializeComponent();
|
|
CB_a.SelectedIndex = CB_b.SelectedIndex = CB_c.SelectedIndex = 0;
|
|
|
|
// Ban Models, Encounters, TitleScreen etc
|
|
banlist = Main.Config.ORAS
|
|
?
|
|
[
|
|
"a005", "a008", "a013", "a039", "a040", "a071", "a072", "a073", "a074", "a075", "a076", "a078", "a079", "a080", "a081", "a082", "a083", "a084", "a085", "a086",
|
|
"a100", "a152",
|
|
"a195",
|
|
]
|
|
:
|
|
[
|
|
"a005", "a007", "a012", "a041", "a042", "a072", "a073", "a074", "a075", "a076", "a078", "a079", "a080", "a081", "a082", "a083", "a084", "a085", "a086", "a087",
|
|
"a101", "a165",
|
|
"a218",
|
|
];
|
|
}
|
|
|
|
private string garc;
|
|
private readonly string[] banlist;
|
|
|
|
private void UpdateLabel(object sender, EventArgs e)
|
|
{
|
|
garc = Path.Combine(Main.RomFSPath, "a",
|
|
CB_a.SelectedIndex.ToString(), CB_b.SelectedIndex.ToString(), CB_c.SelectedIndex.ToString());
|
|
|
|
if (File.Exists(garc))
|
|
{
|
|
L_File.Text = $"File: a\\{CB_a.SelectedIndex}\\{CB_b.SelectedIndex}\\{CB_c.SelectedIndex}";
|
|
B_Shuffle.Enabled = true;
|
|
}
|
|
else
|
|
{
|
|
L_File.Text = "File does not exist!";
|
|
B_Shuffle.Enabled = false;
|
|
garc = null;
|
|
}
|
|
}
|
|
|
|
private void B_Shuffle_Click(object sender, EventArgs e)
|
|
{
|
|
if (garc == null)
|
|
return;
|
|
|
|
string garcID = L_File.Text.Split(':')[1].Replace("\\", "").Replace(" ", "");
|
|
if (banlist.Contains(garcID))
|
|
{ WinFormsUtil.Alert("GARC is prevented from being shuffled."); return; }
|
|
|
|
var g = GARC.UnpackGARC(garc);
|
|
|
|
// Build a list of all the files we can relocate.
|
|
int[] randFiles = new int[g.fatb.FileCount];
|
|
int ctr = 0;
|
|
for (int i = 0; i < randFiles.Length; i++)
|
|
{
|
|
if (!g.fatb.Entries[i].IsFolder)
|
|
randFiles[ctr++] = i;
|
|
}
|
|
|
|
Array.Resize(ref randFiles, ctr);
|
|
|
|
if (ctr == 0)
|
|
{ WinFormsUtil.Alert("No files to shuffle...?"); return; }
|
|
|
|
// Create backup
|
|
string dest = "backup" + Path.DirectorySeparatorChar + $"PreShuffle {garcID}";
|
|
if (!File.Exists(dest))
|
|
File.Copy(garc, dest);
|
|
|
|
var g2 = GARC.UnpackGARC(garc);
|
|
int[] newFileOffset = (int[])randFiles.Clone();
|
|
Util.Shuffle(newFileOffset);
|
|
|
|
for (int i = 0; i < randFiles.Length; i++)
|
|
g.fatb.Entries[randFiles[i]] = g2.fatb.Entries[newFileOffset[i]];
|
|
|
|
#region Re-write GARC Header information!
|
|
using (var newGARC = File.OpenWrite(garc))
|
|
using (var gw = new BinaryWriter(newGARC))
|
|
{
|
|
gw.Seek(7 * 4, SeekOrigin.Begin); // Skip GARC Header
|
|
// Write GARC
|
|
// gw.Write((uint)0x47415243); // GARC
|
|
// gw.Write((uint)0x0000001C); // Header Length
|
|
// gw.Write((ushort)0xFEFF); // Endianness BOM
|
|
// gw.Write((ushort)0x0400); // Const (4)
|
|
// gw.Write((uint)0x00000004); // Section Count (4)
|
|
// gw.Write((uint)0x00000000); // Data Offset (temp)
|
|
// gw.Write((uint)0x00000000); // File Length (temp)
|
|
// gw.Write((uint)0x00000000); // Largest File Size (temp)
|
|
|
|
// Write FATO
|
|
gw.Write((uint)0x4641544F); // FATO
|
|
gw.Write(g.fato.HeaderSize); // Header Size
|
|
gw.Write(g.fato.EntryCount); // Entry Count
|
|
gw.Write(g.fato.Padding); // Padding
|
|
foreach (var t in g.fato.Entries)
|
|
gw.Write((uint)t.Offset);
|
|
|
|
// Write FATB
|
|
gw.Write((uint)0x46415442); // FATB
|
|
gw.Write(g.fatb.HeaderSize); // Header Size
|
|
gw.Write(g.fatb.FileCount); // File Count
|
|
foreach (var fe in g.fatb.Entries)
|
|
{
|
|
gw.Write(fe.Vector);
|
|
foreach (var s in fe.SubEntries.Where(s => s.Exists))
|
|
{
|
|
gw.Write((uint)s.Start);
|
|
gw.Write((uint)s.End);
|
|
gw.Write((uint)s.Length);
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
WinFormsUtil.Alert("GARC Shuffled!");
|
|
}
|
|
} |