chovy-sign/LibChovy/ChovySign.cs

162 lines
7.2 KiB
C#

using GameBuilder.Pops;
using GameBuilder.Psp;
using Li.Progress;
using PspCrypto;
using Vita.PsvImgTools;
namespace LibChovy
{
public class ChovySign : ProgressTracker
{
private void onProgress(ProgressInfo inf)
{
updateProgress(inf.Done, inf.Remain, inf.CurrentProcess);
}
private void createPSP(PspParameters parameters)
{
using(NpUmdImg img = new NpUmdImg(parameters.DrmInfo, parameters.Umd, parameters.Compress))
{
img.PatchSfo();
using (PbpBuilder pbpBuilder = new PbpBuilder(parameters.Umd.DataFiles["PARAM.SFO"], parameters.Umd.DataFiles["ICON0.PNG"], parameters.Umd.DataFiles["ICON1.PMF"], parameters.Umd.DataFiles["PIC0.PNG"], parameters.Umd.DataFiles["PIC1.PNG"], parameters.Umd.DataFiles["SND0.AT3"], img, 1))
{
pbpBuilder.RegisterCallback(onProgress);
pbpBuilder.CreatePsarAndPbp();
pbpBuilder.PbpStream.Seek(0x00, SeekOrigin.Begin);
byte[] ebootsig = new byte[0x200];
SceNpDrm.KsceNpDrmEbootSigGenPsp(pbpBuilder.PbpStream, ebootsig, parameters.FirmwareVersion);
if (!parameters.CreatePsvImg)
{
File.WriteAllBytes(Path.Combine(parameters.OutputFolder, "__sce_ebootpbp"), ebootsig.ToArray());
pbpBuilder.WritePbpToFile(Path.Combine(parameters.OutputFolder, "EBOOT.PBP"));
}
else
{
createPsvImg(parameters.OutputFolder, parameters.Umd.DiscId, parameters.Umd.DataFiles["PARAM.SFO"], parameters.Umd.DataFiles["ICON0.PNG"], pbpBuilder, parameters.DrmRif, ebootsig, parameters.Account.CmaKey);
}
}
}
}
private void createPOPS(PopsParameters parameters)
{
Sfo psfo = new Sfo();
psfo.AddKey("BOOTABLE", 1, 4);
psfo.AddKey("CATEGORY", "ME", 4);
psfo.AddKey("DISC_ID", parameters.FirstDisc.DiscId, 16);
psfo.AddKey("DISC_VERSION", "1.00", 8);
psfo.AddKey("LICENSE", "Chovy-Sign is licensed under the GPLv3, And was made possible by SquallATF and Li.", 512);
psfo.AddKey("PARENTAL_LEVEL", 0, 4);
psfo.AddKey("PSP_SYSTEM_VER", "6.61", 8);
psfo.AddKey("REGION", 32768, 4);
psfo.AddKey("TITLE", parameters.Name, 128);
byte[] sfo = psfo.WriteSfo();
PopsImg img;
if (parameters.MultiDisc)
img = new PsTitleImg(parameters.DrmInfo, parameters.Discs);
else
img = new PsIsoImg(parameters.DrmInfo, parameters.FirstDisc);
// apply eboot elf overrides
if(parameters.EbootElfOverride is not null)
{
img.EbootElf = parameters.EbootElfOverride;
img.PatchEboot = false;
}
if (parameters.ConfigBinOverride is not null)
{
img.ConfigBin = parameters.ConfigBinOverride;
}
using (PbpBuilder pbpBuilder = new PbpBuilder(sfo, parameters.Icon0, null, parameters.Pic0, parameters.Pic1, null, img, 0))
{
pbpBuilder.RegisterCallback(onProgress);
pbpBuilder.CreatePsarAndPbp();
pbpBuilder.PbpStream.Seek(0x00, SeekOrigin.Begin);
byte[] ebootsig = new byte[0x200];
SceNpDrm.KsceNpDrmEbootSigGenPs1(pbpBuilder.PbpStream, ebootsig, parameters.FirmwareVersion);
if (!parameters.CreatePsvImg)
{
File.WriteAllBytes(Path.Combine(parameters.OutputFolder, "__sce_ebootpbp"), ebootsig.ToArray());
pbpBuilder.WritePbpToFile(Path.Combine(parameters.OutputFolder, "EBOOT.PBP"));
}
else
{
createPsvImg(parameters.OutputFolder, parameters.FirstDisc.DiscId, sfo, parameters.Icon0, pbpBuilder, parameters.DrmRif, ebootsig, parameters.Account.CmaKey);
}
}
}
private void createPsvImg(string outputFolder, string discId,
byte[] sfo, byte[] icon0,
PbpBuilder pbp, NpDrmRif license, byte[] sig,
byte[] cmaKey)
{
// create GAME.PSVIMG
pbp.PbpStream.Seek(0x00, SeekOrigin.Begin);
string gameFolder = Path.Combine(outputFolder, "game");
string licenseFolder = Path.Combine(outputFolder, "license");
string sceSysFolder = Path.Combine(outputFolder, "sce_sys");
if (!Directory.Exists(gameFolder)) Directory.CreateDirectory(gameFolder);
if (!Directory.Exists(licenseFolder)) Directory.CreateDirectory(licenseFolder);
if (!Directory.Exists(sceSysFolder)) Directory.CreateDirectory(sceSysFolder);
using (FileStream gamePsvimg = File.Open(Path.Combine(gameFolder, "game.psvimg"), FileMode.Create, FileAccess.ReadWrite))
{
PSVIMGBuilder psvImg = new PSVIMGBuilder(gamePsvimg, cmaKey);
psvImg.RegisterCallback(onProgress);
psvImg.AddFile(pbp.PbpStream, "ux0:pspemu/temp/game/PSP/GAME/" + discId, "/EBOOT.PBP");
psvImg.AddFile(sig, "ux0:pspemu/temp/game/PSP/GAME/" + discId, "/__sce_ebootpbp");
long contentSize = psvImg.Finish();
// create GAME.PSVMD
using (FileStream gamePsvmd = File.Open(Path.Combine(gameFolder, "game.psvmd"), FileMode.Create, FileAccess.ReadWrite))
PSVMDBuilder.CreatePsvmd(gamePsvmd, gamePsvimg, contentSize, "game", cmaKey);
}
// create LICENSE.PSVIMG
using (FileStream gamePsvimg = File.Open(Path.Combine(licenseFolder, "license.psvimg"), FileMode.Create, FileAccess.ReadWrite))
{
PSVIMGBuilder psvImg = new PSVIMGBuilder(gamePsvimg, cmaKey);
psvImg.RegisterCallback(onProgress);
psvImg.AddFile(license.Rif, "ux0:pspemu/temp/game/PSP/LICENSE", "/" + license.ContentId + ".rif");
long contentSize = psvImg.Finish();
// create LICENSE.PSVMD
using (FileStream gamePsvmd = File.Open(Path.Combine(licenseFolder, "license.psvmd"), FileMode.Create, FileAccess.ReadWrite))
PSVMDBuilder.CreatePsvmd(gamePsvmd, gamePsvimg, contentSize, "license", cmaKey);
}
// write SCE_SYS
File.WriteAllBytes(Path.Combine(sceSysFolder, "param.sfo"), sfo);
File.WriteAllBytes(Path.Combine(sceSysFolder, "icon0.png"), icon0);
}
public void Go(ChovySignParameters parameters)
{
SceNpDrm.Aid = parameters.DrmRif.AccountId;
if (!Directory.Exists(parameters.OutputFolder))
Directory.CreateDirectory(parameters.OutputFolder);
if (parameters.Type == ChovyTypes.PSP)
createPSP((PspParameters)parameters);
else
createPOPS((PopsParameters)parameters);
}
}
}