diff --git a/.gitignore b/.gitignore index 3cee717..c0c1c6e 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ *.user *.userosscache *.sln.docstates +.vscode # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs diff --git a/UnionPatcher.Gui/Forms/FilePatchForm.cs b/UnionPatcher.Gui/Forms/FilePatchForm.cs index a52e04d..1653459 100644 --- a/UnionPatcher.Gui/Forms/FilePatchForm.cs +++ b/UnionPatcher.Gui/Forms/FilePatchForm.cs @@ -24,25 +24,8 @@ public class FilePatchForm : Form { return control; } - public Control CreateHelpButton(int tabIndex = 0) { - Button control = new() { - Text = "Help", - TabIndex = tabIndex, - }; - - control.Click += delegate { - Process process = new(); - - process.StartInfo.UseShellExecute = true; - process.StartInfo.FileName = "https://www.lbpunion.com"; - process.Start(); - }; - - return control; - } - public FilePatchForm() { - this.Title = "UnionPatcher - File Patch"; + this.Title = "File Patch"; this.ClientSize = new Size(500, -1); this.Content = new TableLayout { Spacing = new Size(5,5), @@ -61,7 +44,7 @@ public class FilePatchForm : Form { new TableCell(this.outputFileName = new FilePicker { TabIndex = 2, FileAction = FileAction.SaveFile, Filters = { new FileFilter("ELF files", "*.elf", "*.ELF"), new FileFilter("All Files", "*.*") }}) ), new TableRow( - new TableCell(this.CreateHelpButton(4)), + new TableCell(), new TableCell(this.CreatePatchButton(3)) ), }, diff --git a/UnionPatcher.Gui/Forms/ModeSelectionForm.cs b/UnionPatcher.Gui/Forms/ModeSelectionForm.cs index ce45984..8e8ec7e 100644 --- a/UnionPatcher.Gui/Forms/ModeSelectionForm.cs +++ b/UnionPatcher.Gui/Forms/ModeSelectionForm.cs @@ -8,8 +8,8 @@ namespace LBPUnion.UnionPatcher.Gui.Forms; public class ModeSelectionForm : Form { #region UI public ModeSelectionForm() { - this.Title = "Welcome to UnionPatcher"; - this.ClientSize = new Size(500, -1); + this.Title = "UnionPatcher"; + this.ClientSize = new Size(200, -1); this.Content = new TableLayout { Spacing = new Size(5, 5), Padding = new Padding(10, 10, 10, 10), @@ -17,9 +17,6 @@ public class ModeSelectionForm : Form { new TableRow( new TableCell(new Button(openRemotePatcher) { Text = "Remote Patcher (PS3)" }) ), - new TableRow( - new TableCell(new Button(openLocalPatcher) { Text = "Local Patch (RPCS3)", Enabled = false }) - ), new TableRow( new TableCell(new Button(openFilePatcher) { Text = "File Patch (PS3/RPCS3)" }) ), diff --git a/UnionPatcher.Gui/Forms/RemotePatchForm.cs b/UnionPatcher.Gui/Forms/RemotePatchForm.cs index 7354ea9..58d49a9 100644 --- a/UnionPatcher.Gui/Forms/RemotePatchForm.cs +++ b/UnionPatcher.Gui/Forms/RemotePatchForm.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics; +using System.Threading.Tasks; using Eto.Drawing; using Eto.Forms; @@ -31,7 +32,7 @@ public class RemotePatchForm : Form Width = 200, }; - control.Click += delegate { + control.Click += async delegate { if (string.IsNullOrEmpty(this.ps3LocalIP.Text)) { Gui.CreateOkDialog("Error", "No PS3 IP address specified!"); @@ -56,24 +57,33 @@ public class RemotePatchForm : Form return; } - try + Task patchTask = null; + + if (this.lbpGameID.Text.ToUpper().StartsWith('B')) { - if (this.lbpGameID.Text.ToUpper().StartsWith('B')) - { - this.RemotePatcher.DiscEBOOTRemotePatch(this.ps3LocalIP.Text, this.lbpGameID.Text, this.serverUrl.Text, this.ftpUser.Text, this.ftpPass.Text); - } - else - { - this.RemotePatcher.PSNEBOOTRemotePatch(this.ps3LocalIP.Text, this.lbpGameID.Text, this.serverUrl.Text, this.ftpUser.Text, this.ftpPass.Text); - } + patchTask = this.RemotePatcher.DiscEBOOTRemotePatch(this.ps3LocalIP.Text, this.lbpGameID.Text, this.serverUrl.Text, this.ftpUser.Text, this.ftpPass.Text); + } + else + { + patchTask = this.RemotePatcher.PSNEBOOTRemotePatch(this.ps3LocalIP.Text, this.lbpGameID.Text, this.serverUrl.Text, this.ftpUser.Text, this.ftpPass.Text); + } + + // Something went horribly wrong, this should be impossible to encounter. + if (patchTask == null) return; + + Control revertButton = this.FindChild("revert"); + foreach (Control control in this.Controls) control.Enabled = false; + Gui.CreateOkDialog("Sit Tight!", $"We're patching your title for {this.ps3LocalIP.Text}! Maybe grab some tea?"); + try + { + await patchTask; + Gui.CreateOkDialog("Have fun!", $"The Server URL for {this.lbpGameID.Text} on the PS3 at {this.ps3LocalIP.Text} has been patched to {this.serverUrl.Text}"); } catch (Exception e) { - Gui.CreateOkDialog("Error occurred while patching", "An error occured while patching:\n" + e); - return; + Gui.CreateOkDialog("Error occurred while patching", "An error occured while patching:\n" + e.Message); } - - Gui.CreateOkDialog("Success!", $"The Server URL for {this.lbpGameID.Text} on the PS3 at {this.ps3LocalIP.Text} has been patched to {this.serverUrl.Text}"); + foreach (Control control in this.Controls) control.Enabled = true; }; return control; @@ -85,10 +95,10 @@ public class RemotePatchForm : Form { Text = "Revert EBOOT", TabIndex = tabIndex, - Width = 200, + Width = 50, }; - control.Click += delegate { + control.Click += async delegate { if (string.IsNullOrEmpty(this.ps3LocalIP.Text)) { Gui.CreateOkDialog("Form Error", "No PS3 IP address specified!"); @@ -100,37 +110,20 @@ public class RemotePatchForm : Form Gui.CreateOkDialog("Form Error", "No game ID specified!"); return; } - - try + + foreach (Control control in this.Controls) control.Enabled = false; + Task revertTask = this.RemotePatcher.RevertEBOOT(this.ps3LocalIP.Text, this.lbpGameID.Text, this.serverUrl.Text, this.ftpUser.Text, this.ftpPass.Text); + + try { - this.RemotePatcher.RevertEBOOT(this.ps3LocalIP.Text, this.lbpGameID.Text, this.serverUrl.Text, this.ftpUser.Text, this.ftpPass.Text); + await revertTask; + Gui.CreateOkDialog("Success!", $"UnionPatcher reverted your the EBOOT for {this.lbpGameID.Text} to stock. You're ready to patch your EBOOT again."); } catch (Exception e) { - Gui.CreateOkDialog("Error occurred while reverting EBOOT", "An error occured while patching:\n" + e); - return; + Gui.CreateOkDialog("Error occurred while reverting EBOOT", "An error occured while patching:\n" + e.Message); } - - Gui.CreateOkDialog("Success!", $"UnionRemotePatcher reverted your the EBOOT for {this.lbpGameID.Text} to stock. You're ready to patch your EBOOT again."); - }; - - return control; - } - - public Control CreateHelpButton(int tabIndex = 0) - { - Button control = new() - { - Text = "Help", - TabIndex = tabIndex, - }; - - control.Click += delegate { - Process process = new(); - - process.StartInfo.UseShellExecute = true; - process.StartInfo.FileName = "https://www.lbpunion.com"; - process.Start(); + foreach (Control control in this.Controls) control.Enabled = true; }; return control; @@ -138,7 +131,7 @@ public class RemotePatchForm : Form void InitializeComponent() { - this.Title = "UnionPatcher - Remote Patch"; + this.Title = "Remote Patcher"; this.MinimumSize = new Size(450, 200); this.Resizable = false; this.Padding = 10; @@ -169,11 +162,8 @@ public class RemotePatchForm : Form new TableCell(this.ftpPass = new TextBox { TabIndex = 4 }) ), new TableRow( - new TableCell(this.CreateHelpButton(7)), - new TableRow( - new TableCell(this.CreatePatchButton(5)), - new TableCell(this.CreateRevertEBOOTButton(6)) - ) + new TableCell(this.CreateRevertEBOOTButton(6)), + new TableCell(this.CreatePatchButton(5)) ), }, }; diff --git a/UnionPatcher/RemotePatch.cs b/UnionPatcher/RemotePatch.cs index 8642559..830b965 100644 --- a/UnionPatcher/RemotePatch.cs +++ b/UnionPatcher/RemotePatch.cs @@ -5,6 +5,7 @@ using System.IO; using System.Linq; using System.Net; using System.Runtime.InteropServices; +using System.Threading.Tasks; using LBPUnion.UnionPatcher.Communication; namespace LBPUnion.UnionPatcher; @@ -17,24 +18,29 @@ public class RemotePatch { Console.WriteLine("Getting users..."); - Dictionary users = new(); - - string[] userFolders = FTP.ListDirectory($"ftp://{ps3Ip}/dev_hdd0/home/", user, pass); - - string username = ""; - - for (int i = 0; i < userFolders.Length; i++) + Task> users = Task.Run(() => { - username = FTP.ReadFile($"ftp://{ps3Ip}/dev_hdd0/home/{userFolders[i]}/localusername", user, - pass); - users.Add(userFolders[i], username); + Dictionary users = new(); - Console.WriteLine("User found: " + username + $" <{userFolders[i]}>"); - } + string[] userFolders = FTP.ListDirectory($"ftp://{ps3Ip}/dev_hdd0/home/", user, pass); - return users; + string username = ""; + + for (int i = 0; i < userFolders.Length; i++) + { + username = FTP.ReadFile($"ftp://{ps3Ip}/dev_hdd0/home/{userFolders[i]}/localusername", user, + pass); + users.Add(userFolders[i], username); + + Console.WriteLine("User found: " + username + $" <{userFolders[i]}>"); + } + + return users; + }); + + return users.Result; } - + public static void LaunchSCETool(string args) { string platformExecutable = ""; @@ -44,13 +50,15 @@ public class RemotePatch platformExecutable = "scetool/win64/scetool.exe"; break; case OSPlatform.Linux: - if(RuntimeInformation.ProcessArchitecture == Architecture.X64) + if (RuntimeInformation.ProcessArchitecture == Architecture.X64) { platformExecutable = "scetool/linux64/scetool"; - } else if (RuntimeInformation.ProcessArchitecture == Architecture.Arm) + } + else if (RuntimeInformation.ProcessArchitecture == Architecture.Arm) { platformExecutable = "scetool/linuxarm/scetool"; - } else if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64) + } + else if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64) { platformExecutable = "scetool/linuxarm64/scetool"; } @@ -87,154 +95,167 @@ public class RemotePatch Console.WriteLine("\n===== END SCETOOL =====\n\n"); } - public void RevertEBOOT(string ps3ip, string gameID, string serverURL, string user, string pass) + public Task RevertEBOOT(string ps3ip, string gameID, string serverURL, string user, string pass) { Console.WriteLine("Restoring original EBOOT.BIN from EBOOT.BIN.BAK"); - - // Create a simple directory structure - Directory.CreateDirectory(@"eboot"); - Directory.CreateDirectory($@"eboot/{gameID}"); - Directory.CreateDirectory($@"eboot/{gameID}/original"); - - // Now we'll check and see if a backup exists on the server, if so download it and then upload it back as EBOOT.BIN - if (FTP.FileExists($"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN.BAK", user, pass)) + + return Task.Run(() => { - FTP.DownloadFile($"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN.BAK", @$"eboot/{gameID}/original/EBOOT.BIN.BAK", user, pass); - FTP.UploadFile(@$"eboot/{gameID}/original/EBOOT.BIN.BAK", $"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN", user, pass); - } - else - { - throw new WebException("Could not find EBOOT.BIN.BAK on server."); - } + // Create a simple directory structure + Directory.CreateDirectory(@"eboot"); + Directory.CreateDirectory($@"eboot/{gameID}"); + Directory.CreateDirectory($@"eboot/{gameID}/original"); + + // Now we'll check and see if a backup exists on the server, if so download it and then upload it back as EBOOT.BIN + if (FTP.FileExists($"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN.BAK", user, pass)) + { + + FTP.DownloadFile($"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN.BAK", @$"eboot/{gameID}/original/EBOOT.BIN.BAK", user, pass); + FTP.UploadFile(@$"eboot/{gameID}/original/EBOOT.BIN.BAK", $"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN", user, pass); + + } + else + { + throw new WebException("Could not find EBOOT.BIN.BAK on server."); + } + }); } - public void PSNEBOOTRemotePatch(string ps3ip, string gameID, string serverURL, string user, string pass) + public Task PSNEBOOTRemotePatch(string ps3ip, string gameID, string serverURL, string user, string pass) { Console.WriteLine("Detected Digital Copy - Running in Full Mode"); - - string idps = ""; - string contentID = ""; - Dictionary users; - this._ps3Mapi.ConnectTarget(ps3ip); - this._ps3Mapi.PS3.RingBuzzer(PS3MAPI.PS3Cmd.BuzzerMode.Double); - this._ps3Mapi.PS3.Notify("UnionRemotePatcher Connected! Patching..."); - - // Create simple directory structure - Directory.CreateDirectory(@"rifs"); - Directory.CreateDirectory(@"eboot"); - Directory.CreateDirectory($@"eboot/{gameID}"); - Directory.CreateDirectory($@"eboot/{gameID}/original"); - Directory.CreateDirectory($@"eboot/{gameID}/patched"); - - // Let's grab and backup our EBOOT - FTP.DownloadFile($"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN", - @$"eboot/{gameID}/original/EBOOT.BIN", user, pass); - - // Now we'll check and see if a backup exists on the server or not, if we don't have one on the server, then upload one - if (!FTP.FileExists($"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN.BAK", user, pass)) - FTP.UploadFile(@$"eboot/{gameID}/original/EBOOT.BIN", - $"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN.BAK", user, pass); - - // Start getting idps and act.dat - these will help us decrypt a PSN eboot - idps = PS3MAPI.PS3MAPIClientServer.PS3_GetIDPS(); - - File.WriteAllBytes(@"data/idps", IDPSHelper.StringToByteArray(idps)); - - // Scan the users on the system - users = GetUsers(ps3ip, user, pass); - - // Scan the system for a license for the game - foreach (string currentUser in users.Keys.ToArray()) + // Create a new thread so we don't occupy the UI thread. + return Task.Run(() => { - if (FTP.FileExists($"ftp://{ps3ip}/dev_hdd0/home/{currentUser}/exdata", user, pass)) + string idps = ""; + string contentID = ""; + Dictionary users; + + this._ps3Mapi.ConnectTarget(ps3ip); + this._ps3Mapi.PS3.RingBuzzer(PS3MAPI.PS3Cmd.BuzzerMode.Double); + this._ps3Mapi.PS3.Notify("UnionRemotePatcher Connected! Patching..."); + + // Create simple directory structure + Directory.CreateDirectory(@"rifs"); + Directory.CreateDirectory(@"eboot"); + Directory.CreateDirectory($@"eboot/{gameID}"); + Directory.CreateDirectory($@"eboot/{gameID}/original"); + Directory.CreateDirectory($@"eboot/{gameID}/patched"); + + // Let's grab and backup our EBOOT + FTP.DownloadFile($"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN", + @$"eboot/{gameID}/original/EBOOT.BIN", user, pass); + + // Now we'll check and see if a backup exists on the server or not, if we don't have one on the server, then upload one + if (!FTP.FileExists($"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN.BAK", user, pass)) + FTP.UploadFile(@$"eboot/{gameID}/original/EBOOT.BIN", + $"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN.BAK", user, pass); + + // Start getting idps and act.dat - these will help us decrypt a PSN eboot + idps = PS3MAPI.PS3MAPIClientServer.PS3_GetIDPS(); + + File.WriteAllBytes(@"data/idps", IDPSHelper.StringToByteArray(idps)); + + // Scan the users on the system + users = GetUsers(ps3ip, user, pass); + + // Scan the system for a license for the game + foreach (string currentUser in users.Keys.ToArray()) { - foreach (string fileName in FTP.ListDirectory( - $"ftp://{ps3ip}/dev_hdd0/home/{currentUser}/exdata/", user, pass)) - if (fileName.Contains(gameID)) - { - FTP.DownloadFile($"ftp://{ps3ip}/dev_hdd0/home/{currentUser}/exdata/act.dat", @"data/act.dat", - user, - pass); - - FTP.DownloadFile($"ftp://{ps3ip}/dev_hdd0/home/{currentUser}/exdata/{fileName}", - @$"rifs/{fileName}", user, pass); - - contentID = fileName.Substring(0, fileName.Length - 4); - - Console.WriteLine($"Got content ID {contentID}"); - } + if (FTP.FileExists($"ftp://{ps3ip}/dev_hdd0/home/{currentUser}/exdata", user, pass)) + { + foreach (string fileName in FTP.ListDirectory( + $"ftp://{ps3ip}/dev_hdd0/home/{currentUser}/exdata/", user, pass)) + if (fileName.Contains(gameID)) + { + FTP.DownloadFile($"ftp://{ps3ip}/dev_hdd0/home/{currentUser}/exdata/act.dat", @"data/act.dat", + user, + pass); + + FTP.DownloadFile($"ftp://{ps3ip}/dev_hdd0/home/{currentUser}/exdata/{fileName}", + @$"rifs/{fileName}", user, pass); + + contentID = fileName.Substring(0, fileName.Length - 4); + + Console.WriteLine($"Got content ID {contentID}"); + } + } } - } - // Finally, let's decrypt the EBOOT.BIN - LaunchSCETool($" -v -d \"{Path.GetFullPath(@$"eboot/{gameID}/original/EBOOT.BIN")}\" \"{Path.GetFullPath(@$"eboot/{gameID}/original/EBOOT.ELF")}\""); + // Finally, let's decrypt the EBOOT.BIN + LaunchSCETool($" -v -d \"{Path.GetFullPath(@$"eboot/{gameID}/original/EBOOT.BIN")}\" \"{Path.GetFullPath(@$"eboot/{gameID}/original/EBOOT.ELF")}\""); - // Now, patch the EBOOT; - Patcher.PatchFile($"eboot/{gameID}/original/EBOOT.ELF", serverURL, $"eboot/{gameID}/patched/EBOOT.ELF"); + // Now, patch the EBOOT; + Patcher.PatchFile($"eboot/{gameID}/original/EBOOT.ELF", serverURL, $"eboot/{gameID}/patched/EBOOT.ELF"); - // Encrypt the EBOOT (PSN) - LaunchSCETool($"--verbose " + - $"--sce-type=SELF" + - $" --skip-sections=FALSE" + - $" --self-add-shdrs=TRUE" + - $" --compress-data=TRUE" + - $" --key-revision=0A" + - $" --self-app-version=0001000000000000" + - $" --self-auth-id=1010000001000003" + - $" --self-vendor-id=01000002" + - $" --self-ctrl-flags=0000000000000000000000000000000000000000000000000000000000000000" + - $" --self-cap-flags=00000000000000000000000000000000000000000000003B0000000100040000" + - $" --self-type=NPDRM" + - $" --self-fw-version=0003005500000000" + - $" --np-license-type=FREE" + - $" --np-app-type=SPRX" + - $" --np-content-id={contentID}" + - $" --np-real-fname=EBOOT.BIN" + - $" --encrypt eboot/{gameID}/patched/EBOOT.ELF eboot/{gameID}/patched/EBOOT.BIN"); + // Encrypt the EBOOT (PSN) + LaunchSCETool($"--verbose " + + $"--sce-type=SELF" + + $" --skip-sections=FALSE" + + $" --self-add-shdrs=TRUE" + + $" --compress-data=TRUE" + + $" --key-revision=0A" + + $" --self-app-version=0001000000000000" + + $" --self-auth-id=1010000001000003" + + $" --self-vendor-id=01000002" + + $" --self-ctrl-flags=0000000000000000000000000000000000000000000000000000000000000000" + + $" --self-cap-flags=00000000000000000000000000000000000000000000003B0000000100040000" + + $" --self-type=NPDRM" + + $" --self-fw-version=0003005500000000" + + $" --np-license-type=FREE" + + $" --np-app-type=SPRX" + + $" --np-content-id={contentID}" + + $" --np-real-fname=EBOOT.BIN" + + $" --encrypt eboot/{gameID}/patched/EBOOT.ELF eboot/{gameID}/patched/EBOOT.BIN"); - // And upload the encrypted, patched EBOOT to the system. - FTP.UploadFile(@$"eboot/{gameID}/patched/EBOOT.BIN", - $"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN", user, pass); + // And upload the encrypted, patched EBOOT to the system. + FTP.UploadFile(@$"eboot/{gameID}/patched/EBOOT.BIN", + $"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN", user, pass); + }); } // Cut-down version that only patches disc copies - public void DiscEBOOTRemotePatch(string ps3ip, string gameID, string serverURL, string user, string pass) + public Task DiscEBOOTRemotePatch(string ps3ip, string gameID, string serverURL, string user, string pass) { Console.WriteLine("Detected Disc Copy - Running in Simplified Mode"); - - // Create a simple directory structure - Directory.CreateDirectory(@"eboot"); - Directory.CreateDirectory($@"eboot/{gameID}"); - Directory.CreateDirectory($@"eboot/{gameID}/original"); - Directory.CreateDirectory($@"eboot/{gameID}/patched"); - // Let's grab and backup our EBOOT - FTP.DownloadFile($"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN", - @$"eboot/{gameID}/original/EBOOT.BIN", user, pass); + // Create a new thread so we don't occupy the UI thread. + return Task.Run(() => + { + // Create a simple directory structure + Directory.CreateDirectory(@"eboot"); + Directory.CreateDirectory($@"eboot/{gameID}"); + Directory.CreateDirectory($@"eboot/{gameID}/original"); + Directory.CreateDirectory($@"eboot/{gameID}/patched"); - // Now we'll check and see if a backup exists on the server or not, if we don't have one on the server, then upload one - if (!FTP.FileExists($"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN.BAK", user, pass)) - FTP.UploadFile(@$"eboot/{gameID}/original/EBOOT.BIN", - $"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN.BAK", user, pass); + // Let's grab and backup our EBOOT + FTP.DownloadFile($"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN", + @$"eboot/{gameID}/original/EBOOT.BIN", user, pass); - // Check for keys in the data directory - if (!File.Exists("data/keys")) - throw new FileNotFoundException( - "UnionRemotePatcher cannot find the keys, ldr_curves, or vsh_curves files required to continue. Please make sure you have copies of these files placed in the data directory where you found the executable to run UnionRemotePatcher. Without them, we can't patch your game."); + // Now we'll check and see if a backup exists on the server or not, if we don't have one on the server, then upload one + if (!FTP.FileExists($"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN.BAK", user, pass)) + FTP.UploadFile(@$"eboot/{gameID}/original/EBOOT.BIN", + $"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN.BAK", user, pass); - // Decrypt the EBOOT - LaunchSCETool($"-v -d eboot/{gameID}/original/EBOOT.BIN eboot/{gameID}/original/EBOOT.ELF"); + // Check for keys in the data directory + if (!File.Exists("data/keys")) + throw new FileNotFoundException( + "UnionRemotePatcher cannot find the keys, ldr_curves, or vsh_curves files required to continue. Please make sure you have copies of these files placed in the data directory where you found the executable to run UnionRemotePatcher. Without them, we can't patch your game."); - // Now, patch the EBOOT; - Patcher.PatchFile($"eboot/{gameID}/original/EBOOT.ELF", serverURL, $"eboot/{gameID}/patched/EBOOT.ELF"); + // Decrypt the EBOOT + LaunchSCETool($"-v -d eboot/{gameID}/original/EBOOT.BIN eboot/{gameID}/original/EBOOT.ELF"); - // Encrypt the EBOOT (Disc) - LaunchSCETool( - $" -v --sce-type=SELF --skip-sections=FALSE --key-revision=0A --self-app-version=0001000000000000 --self-auth-id=1010000001000003 --self-vendor-id=01000002 --self-ctrl-flags=0000000000000000000000000000000000000000000000000000000000000000 --self-cap-flags=00000000000000000000000000000000000000000000003B0000000100040000 --self-type=APP --self-fw-version=0003005500000000 --compress-data true --encrypt \"{Path.GetFullPath(@$"eboot/{gameID}/patched/EBOOT.ELF")}\" \"{Path.GetFullPath(@$"eboot/{gameID}/patched/EBOOT.BIN")}\""); + // Now, patch the EBOOT; + Patcher.PatchFile($"eboot/{gameID}/original/EBOOT.ELF", serverURL, $"eboot/{gameID}/patched/EBOOT.ELF"); - // And upload the encrypted, patched EBOOT to the system. - FTP.UploadFile(@$"eboot/{gameID}/patched/EBOOT.BIN", - $"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN", user, pass); + // Encrypt the EBOOT (Disc) + LaunchSCETool( + $" -v --sce-type=SELF --skip-sections=FALSE --key-revision=0A --self-app-version=0001000000000000 --self-auth-id=1010000001000003 --self-vendor-id=01000002 --self-ctrl-flags=0000000000000000000000000000000000000000000000000000000000000000 --self-cap-flags=00000000000000000000000000000000000000000000003B0000000100040000 --self-type=APP --self-fw-version=0003005500000000 --compress-data true --encrypt \"{Path.GetFullPath(@$"eboot/{gameID}/patched/EBOOT.ELF")}\" \"{Path.GetFullPath(@$"eboot/{gameID}/patched/EBOOT.BIN")}\""); + + // And upload the encrypted, patched EBOOT to the system. + FTP.UploadFile(@$"eboot/{gameID}/patched/EBOOT.BIN", + $"ftp://{ps3ip}/dev_hdd0/game/{gameID}/USRDIR/EBOOT.BIN", user, pass); + }); } }