-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #72 from LittleBigRefresh/pipelines-rpcs3
RPCS3 Pipelines
- Loading branch information
Showing
26 changed files
with
664 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace Refresher.Core.Patching; | ||
|
||
public class EncryptionDetails | ||
{ | ||
public string? LicenseDirectory { get; internal set; } | ||
public string? DownloadedActDatPath { get; internal set; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
namespace Refresher.Core.Patching; | ||
|
||
public class GameInformation | ||
{ | ||
public string TitleId { get; set; } = null!; | ||
|
||
public string? Name { get; set; } | ||
public string? ContentId { get; set; } | ||
public string? Version { get; set; } | ||
|
||
public string? DownloadedEbootPath { get; set; } | ||
public string? DecryptedEbootPath { get; internal set; } | ||
|
||
public override string ToString() | ||
{ | ||
return $"[{this.TitleId}] name: {this.Name}, contentId: {this.ContentId}, version: {this.Version}"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
namespace Refresher.Core.Pipelines; | ||
|
||
internal static class CommonStepInputs | ||
{ | ||
internal static readonly StepInput TitleId = new("title-id", "Game", StepInputType.Game) | ||
{ | ||
Placeholder = "NPUA80662", | ||
}; | ||
|
||
internal static readonly StepInput ServerUrl = new("url", "Server URL") | ||
{ | ||
Placeholder = "https://lbp.littlebigrefresh.com", | ||
}; | ||
|
||
internal static readonly StepInput RPCS3Folder = new("hdd0-path", "RPCS3 dev_hdd0 folder", StepInputType.Directory) | ||
{ | ||
// provide an example to Windows users. | ||
// don't bother with other platforms because they should be automatic | ||
Placeholder = @$"C:\Users\{Environment.UserName}\RPCS3\dev_hdd0", | ||
DetermineDefaultValue = DetermineDefaultRpcs3Path, | ||
}; | ||
|
||
// TODO: Cache the last used location for easier entry | ||
private static string? DetermineDefaultRpcs3Path() | ||
{ | ||
// RPCS3 builds for Windows are portable, so we can't determine this automatically | ||
if (OperatingSystem.IsWindows()) | ||
return null; | ||
|
||
// ~/.config/rpcs3/dev_hdd0 | ||
string folder = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "rpcs3", "dev_hdd0"); | ||
|
||
if (Directory.Exists(folder)) | ||
return folder; | ||
|
||
return null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
using Refresher.Core.Pipelines.Steps; | ||
|
||
namespace Refresher.Core.Pipelines; | ||
|
||
public class RPCS3PatchPipeline : Pipeline | ||
{ | ||
public override string Id => "rpcs3-patch"; | ||
public override string Name => "RPCS3 Patch"; | ||
protected override List<Type> StepTypes => | ||
[ | ||
// Info gathering stage | ||
typeof(SetupEmulatorAccessorStep), | ||
typeof(ValidateGameStep), | ||
typeof(DownloadParamSfoStep), | ||
typeof(DownloadGameEbootStep), | ||
typeof(ReadEbootContentIdStep), | ||
typeof(DownloadGameLicenseStep), | ||
|
||
// Decryption and patch stage | ||
typeof(PrepareSceToolStep), | ||
typeof(DecryptGameEbootStep), | ||
typeof(PrepareEbootPatchCreatorAndVerifyStep), | ||
typeof(ApplyPatchToEbootStep), | ||
// The patch creator will automatically write to the patch file. No upload steps are required. | ||
]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
namespace Refresher.Core.Pipelines; | ||
|
||
public enum StepInputType : byte | ||
{ | ||
Text, | ||
Directory, | ||
OpenFile, | ||
SaveFile, | ||
Game, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
namespace Refresher.Core.Pipelines.Steps; | ||
|
||
public class ApplyPatchToEbootStep : Step | ||
{ | ||
public ApplyPatchToEbootStep(Pipeline pipeline) : base(pipeline) | ||
{} | ||
|
||
public override List<StepInput> Inputs => | ||
[ | ||
CommonStepInputs.ServerUrl, | ||
]; | ||
|
||
public override float Progress { get; protected set; } | ||
public override Task ExecuteAsync(CancellationToken cancellationToken = default) | ||
{ | ||
string url = this.Pipeline.Inputs["url"]; | ||
this.Pipeline.Patcher!.Patch(url, true); // TODO: handle autodiscover in pipelines | ||
return Task.CompletedTask; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
using SCEToolSharp; | ||
|
||
namespace Refresher.Core.Pipelines.Steps; | ||
|
||
public class DecryptGameEbootStep : Step | ||
{ | ||
public DecryptGameEbootStep(Pipeline pipeline) : base(pipeline) | ||
{} | ||
|
||
public override float Progress { get; protected set; } | ||
public override Task ExecuteAsync(CancellationToken cancellationToken = default) | ||
{ | ||
string tempFile = this.Game.DecryptedEbootPath = Path.GetTempFileName(); | ||
LibSceToolSharp.Decrypt(this.Game.DownloadedEbootPath!, tempFile); | ||
|
||
// HACK: scetool doesn't give us result codes, check if the file has been written to instead | ||
if (new FileInfo(tempFile).Length == 0) | ||
{ | ||
throw new Exception("Decryption failed."); | ||
} | ||
|
||
return Task.CompletedTask; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
using Refresher.Core.Accessors; | ||
|
||
namespace Refresher.Core.Pipelines.Steps; | ||
|
||
public class DownloadGameEbootStep : Step | ||
{ | ||
public DownloadGameEbootStep(Pipeline pipeline) : base(pipeline) | ||
{} | ||
|
||
public override float Progress { get; protected set; } | ||
public override Task ExecuteAsync(CancellationToken cancellationToken = default) | ||
{ | ||
string titleId = this.Game.TitleId; | ||
string usrDir = $"game/{titleId}/USRDIR"; | ||
|
||
string ebootPath = Path.Combine(usrDir, "EBOOT.BIN.ORIG"); // Prefer original backup over active copy | ||
PatchAccessor.Try(() => | ||
{ | ||
if (this.Pipeline.Accessor!.FileExists(ebootPath)) return; | ||
// If the backup doesn't exist, use the EBOOT.BIN | ||
State.Logger.LogInfo(Accessor, "Couldn't find an original backup of the EBOOT, using active copy. This is not an error."); | ||
ebootPath = Path.Combine(usrDir, "EBOOT.BIN"); | ||
this.Progress = 0.25f; | ||
if (this.Pipeline.Accessor.FileExists(ebootPath)) return; | ||
// If we land here, then we have no valid patch target without any way to recover. | ||
// This is very inconvenient for us and the user. | ||
throw new FileNotFoundException("The EBOOT.BIN file does not exist, nor does the original backup exist." + | ||
"This usually means you haven't installed any updates for your game."); | ||
}); | ||
|
||
this.Progress = 0.5f; | ||
|
||
string downloadedFile = null!; | ||
PatchAccessor.Try(() => | ||
{ | ||
downloadedFile = this.Pipeline.Accessor!.DownloadFile(ebootPath); | ||
this.Game.DownloadedEbootPath = downloadedFile; | ||
}); | ||
|
||
State.Logger.LogDebug(Accessor, $"Downloaded EBOOT Path: {downloadedFile}"); | ||
if (!File.Exists(downloadedFile)) | ||
{ | ||
throw new FileNotFoundException("Could not find the EBOOT we downloaded. This is likely a bug. Patching cannot continue."); | ||
} | ||
|
||
return Task.CompletedTask; | ||
} | ||
} |
Oops, something went wrong.