make Chovy-Sign-CLI and GUI version run on linux
This commit is contained in:
parent
5aa34528ea
commit
c15e345b30
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<_LastSelectedProfileId>C:\Users\Li\Documents\git\Chovy-Sign-v2\ChovySign-CLI\Properties\PublishProfiles\FolderProfile.pubxml</_LastSelectedProfileId>
|
||||
<_LastSelectedProfileId>C:\Users\Li\Documents\git\Chovy-Sign-v2\ChovySign-CLI\Properties\PublishProfiles\Win64.pubxml</_LastSelectedProfileId>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -4,6 +4,8 @@ using GameBuilder.Psp;
|
|||
using LibChovy;
|
||||
using LibChovy.VersionKey;
|
||||
using System.Text;
|
||||
using Vita.ContentManager;
|
||||
using PspCrypto;
|
||||
|
||||
namespace ChovySign_CLI
|
||||
{
|
||||
|
@ -11,19 +13,29 @@ namespace ChovySign_CLI
|
|||
{
|
||||
private static ArgumentParsingMode mode = ArgumentParsingMode.ARG;
|
||||
private static List<string> parameters = new List<string>();
|
||||
private static string[] discs;
|
||||
private static string[] discs = new string[] { };
|
||||
private static bool pspCompress = false;
|
||||
private static bool devKit = false;
|
||||
private static string? popsDiscName;
|
||||
private static string? popsIcon0File;
|
||||
private static string? popsPic0File;
|
||||
private static byte[]? popsIcon0File;
|
||||
private static byte[]? popsPic0File;
|
||||
private static PbpMode? pbpMode = null;
|
||||
private static NpDrmRif? rifFile = null;
|
||||
private static NpDrmInfo? drmInfo = null;
|
||||
|
||||
// cma
|
||||
private static bool devKit = false;
|
||||
private static bool packagePsvImg = true;
|
||||
private static string? outputFolder = null;
|
||||
|
||||
// --vkey-gen
|
||||
private static byte[]? actDat = null;
|
||||
private static byte[]? idps = null;
|
||||
private static string? rifFolder = null;
|
||||
|
||||
// --pops-eboot-sign
|
||||
private static byte[]? ebootElf = null;
|
||||
private static byte[]? configBin = null;
|
||||
|
||||
enum PbpMode
|
||||
{
|
||||
PSP = 0,
|
||||
|
@ -33,15 +45,23 @@ namespace ChovySign_CLI
|
|||
}
|
||||
enum ArgumentParsingMode
|
||||
{
|
||||
ARG = 0,
|
||||
POPS_DISC = 1,
|
||||
PSP_UMD = 2,
|
||||
VERSIONKEY = 3,
|
||||
VERSIONKEY_EXTRACT = 4,
|
||||
VERSIONKEY_GENERATOR = 5,
|
||||
POPS_INFO = 6,
|
||||
KEYS_TXT_GEN = 7,
|
||||
RIF = 8
|
||||
ARG,
|
||||
POPS_DISC,
|
||||
PSP_UMD,
|
||||
|
||||
VERSIONKEY,
|
||||
VERSIONKEY_EXTRACT,
|
||||
VERSIONKEY_GENERATOR,
|
||||
|
||||
CMA_DEVKIT,
|
||||
CMA_OUTPUT_FOLDER,
|
||||
CMA_PACKAGE_PSVIMG,
|
||||
|
||||
POPS_INFO,
|
||||
POPS_EBOOT,
|
||||
|
||||
KEYS_TXT_GEN,
|
||||
RIF
|
||||
}
|
||||
public static int Error(string errorMsg, int ret)
|
||||
{
|
||||
|
@ -102,13 +122,13 @@ namespace ChovySign_CLI
|
|||
switch (mode)
|
||||
{
|
||||
case ArgumentParsingMode.POPS_DISC:
|
||||
if (parameters.Count > 5) return Error("--pops: no more than 5 disc images allowed in a single game (sony's rules, not mine)", 5);
|
||||
if (parameters.Count < 1) return Error("--pops: at least 1 disc image file is required.", 5);
|
||||
if (parameters.Count > 5) return Error("--pops: no more than 5 disc images allowed in a single game (sony's rules, not mine)", 4);
|
||||
if (parameters.Count < 1) return Error("--pops: at least 1 disc image file is required.", 4);
|
||||
discs = parameters.ToArray();
|
||||
break;
|
||||
case ArgumentParsingMode.PSP_UMD:
|
||||
if (parameters.Count < 1) return Error("--psp: a path to a disc image is required", 5);
|
||||
if (parameters.Count > 2) return Error("--psp: no more than 2 arguments. ("+parameters.Count+" given)", 5);
|
||||
if (parameters.Count < 1) return Error("--psp: a path to a disc image is required", 4);
|
||||
if (parameters.Count > 2) return Error("--psp: no more than 2 arguments. ("+parameters.Count+" given)", 4);
|
||||
discs = new string[1];
|
||||
discs[0] = parameters[0];
|
||||
|
||||
|
@ -134,10 +154,10 @@ namespace ChovySign_CLI
|
|||
if (parameters.Count < 2) return Error("--pops-info takes at least 1 arguments ("+parameters.Count+" given)", 4);
|
||||
if (parameters.Count > 3) return Error("--pops-info takes no more than 3 arguments("+parameters.Count+" given)", 4);
|
||||
popsDiscName = parameters[0];
|
||||
if (parameters.Count > 1)
|
||||
popsIcon0File = parameters[1];
|
||||
if (parameters.Count > 2)
|
||||
popsPic0File = parameters[2];
|
||||
if (parameters.Count > 1 && File.Exists(parameters[1]))
|
||||
popsIcon0File = File.ReadAllBytes(parameters[1]);
|
||||
if (parameters.Count > 2 && File.Exists(parameters[2]))
|
||||
popsPic0File = File.ReadAllBytes(parameters[2]);
|
||||
break;
|
||||
case ArgumentParsingMode.KEYS_TXT_GEN:
|
||||
if (parameters.Count != 3) return Error("--keys-txt-gen takes 3 arguments, (" + parameters.Count + " given)", 4);
|
||||
|
@ -145,6 +165,23 @@ namespace ChovySign_CLI
|
|||
idps = StringToByteArray(parameters[1]);
|
||||
rifFolder = parameters[2];
|
||||
break;
|
||||
case ArgumentParsingMode.POPS_EBOOT:
|
||||
if (parameters.Count < 1) return Error("--pops-eboot-sign expects at most 1 arguments", 4);
|
||||
if (!File.Exists(parameters[0])) return Error("--pops-eboot-sign: file not found", 4);
|
||||
ebootElf = File.ReadAllBytes(parameters[0]);
|
||||
|
||||
if (parameters.Count >= 2 && File.Exists(parameters[1]))
|
||||
configBin = File.ReadAllBytes(parameters[1]);
|
||||
else
|
||||
configBin = GameBuilder.Resources.DATAPSPSDCFG;
|
||||
|
||||
break;
|
||||
case ArgumentParsingMode.CMA_OUTPUT_FOLDER:
|
||||
if (parameters.Count < 1) return Error("--output-folder expects 1 output", 4);
|
||||
if (!Directory.Exists(parameters[0])) return Error("--output-folder: directory not found", 4);
|
||||
|
||||
SettingsReader.BackupsFolder = parameters[0];
|
||||
break;
|
||||
case ArgumentParsingMode.RIF:
|
||||
if (parameters.Count != 1) return Error("--rif expects only 1 argument,", 4);
|
||||
rifFile = new NpDrmRif(File.ReadAllBytes(parameters[0]));
|
||||
|
@ -163,12 +200,20 @@ namespace ChovySign_CLI
|
|||
Console.WriteLine("Chovy-Sign v2 (CLI)");
|
||||
Console.WriteLine("--pops [disc1.cue] [disc2.cue] [disc3.cue] ... (up to 5)");
|
||||
Console.WriteLine("--pops-info [game title] [icon0.png] (optional) [pic1.png] (optional)");
|
||||
Console.WriteLine("--pops-eboot [eboot.elf] [config.bin] (optional)");
|
||||
|
||||
Console.WriteLine("--psp [umd.iso] [compress; true/false] (optional)");
|
||||
|
||||
Console.WriteLine("--rif [GAME.RIF]");
|
||||
|
||||
Console.WriteLine("--devkit (Use 000000000000 account id)");
|
||||
Console.WriteLine("--no-psvimg (Disable creating a .psvimg file)");
|
||||
Console.WriteLine("--output-folder [output_folder]");
|
||||
|
||||
Console.WriteLine("--vkey [versionkey] [contentid] [key_index]");
|
||||
Console.WriteLine("--vkey-extract [eboot.pbp]");
|
||||
Console.WriteLine("--vkey-gen [act.dat] [license.rif] [console_id] [key_index]");
|
||||
|
||||
Console.WriteLine("--keys-txt-gen [act.dat] [console_id] [psp_license_folder]");
|
||||
}
|
||||
|
||||
|
@ -236,6 +281,17 @@ namespace ChovySign_CLI
|
|||
return Error("rif is already set", 3);
|
||||
|
||||
break;
|
||||
case "--pops-eboot":
|
||||
mode = ArgumentParsingMode.POPS_EBOOT;
|
||||
break;
|
||||
case "--output-folder":
|
||||
mode = ArgumentParsingMode.CMA_OUTPUT_FOLDER;
|
||||
break;
|
||||
|
||||
case "--no-psvimg":
|
||||
packagePsvImg = false;
|
||||
break;
|
||||
|
||||
case "--devkit":
|
||||
devKit = true;
|
||||
break;
|
||||
|
@ -248,6 +304,7 @@ namespace ChovySign_CLI
|
|||
case ArgumentParsingMode.VERSIONKEY_EXTRACT:
|
||||
case ArgumentParsingMode.PSP_UMD:
|
||||
case ArgumentParsingMode.POPS_DISC:
|
||||
case ArgumentParsingMode.POPS_EBOOT:
|
||||
case ArgumentParsingMode.POPS_INFO:
|
||||
case ArgumentParsingMode.RIF:
|
||||
default:
|
||||
|
@ -267,14 +324,14 @@ namespace ChovySign_CLI
|
|||
if (pbpMode is null) return Error("no pbp mode was set, exiting", 7);
|
||||
|
||||
if (pbpMode == PbpMode.PSP && drmInfo.KeyIndex != 2)
|
||||
return Error("KeyType is "+drmInfo.KeyIndex+", but PBP mode is PSP, you cant do that .. please use a type 1 versionkey.", 8);
|
||||
return Error("KeyType is "+drmInfo.KeyIndex+", but PBP mode is PSP, you cant do that .. please use a type 2 versionkey.", 8);
|
||||
|
||||
if (pbpMode == PbpMode.POPS && drmInfo.KeyIndex != 1)
|
||||
return Error("KeyType is " + drmInfo.KeyIndex + ", but PBP mode is POPS, you cant do that .. please use a type 1 versionkey.", 8);
|
||||
|
||||
if (rifFile is null)
|
||||
return Error("Rif is not set, use --rif to specify base game RIF", 8);
|
||||
//if (pbpMode == PbpMode.POPS && (popsDiscName is null || popsIcon0File is null)) return Error("pbp mode is POPS, but you have not specified a disc title or icon file using --pops-info.", 9);
|
||||
|
||||
ChovySign csign = new ChovySign();
|
||||
csign.RegisterCallback(onProgress);
|
||||
if (pbpMode == PbpMode.POPS)
|
||||
|
@ -287,11 +344,17 @@ namespace ChovySign_CLI
|
|||
if(popsDiscName is not null)
|
||||
popsParameters.Name = popsDiscName;
|
||||
|
||||
if(File.Exists(popsIcon0File))
|
||||
popsParameters.Icon0 = File.ReadAllBytes(popsIcon0File);
|
||||
if(popsIcon0File is not null)
|
||||
popsParameters.Icon0 = popsIcon0File;
|
||||
|
||||
|
||||
popsParameters.CreatePsvImg = packagePsvImg;
|
||||
popsParameters.Account.Devkit = devKit;
|
||||
|
||||
// Allow for custom eboot.elf and configs
|
||||
popsParameters.ConfigBinOverride = configBin;
|
||||
popsParameters.EbootElfOverride = ebootElf;
|
||||
|
||||
csign.Go(popsParameters);
|
||||
|
||||
}
|
||||
|
@ -299,6 +362,8 @@ namespace ChovySign_CLI
|
|||
{
|
||||
PspParameters pspParameters = new PspParameters(drmInfo, rifFile);
|
||||
pspParameters.Account.Devkit = devKit;
|
||||
pspParameters.CreatePsvImg = packagePsvImg;
|
||||
|
||||
pspParameters.Compress = pspCompress;
|
||||
pspParameters.Umd = new UmdInfo(discs.First());
|
||||
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<History>True|2023-05-01T17:56:05.9738806Z;True|2023-04-26T15:20:05.7988009+12:00;True|2023-04-24T08:18:55.4774877+12:00;True|2023-04-20T08:33:00.3404616+12:00;False|2023-04-20T08:29:02.1306599+12:00;True|2023-04-19T21:53:45.1116925+12:00;True|2023-04-19T20:46:20.2756012+12:00;True|2023-04-19T19:58:40.3825010+12:00;True|2023-04-18T00:00:51.4131559+12:00;True|2023-04-17T09:56:35.5065135+12:00;True|2023-04-17T09:22:54.8607008+12:00;True|2023-04-17T08:27:16.5281469+12:00;True|2023-04-17T08:22:02.0531219+12:00;</History>
|
||||
<LastFailureDetails />
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>bin\Release\Linux</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<_TargetId>Folder</_TargetId>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
|
||||
<SelfContained>true</SelfContained>
|
||||
<PublishSingleFile>true</PublishSingleFile>
|
||||
<PublishReadyToRun>true</PublishReadyToRun>
|
||||
<PublishTrimmed>true</PublishTrimmed>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -6,7 +6,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
|||
<PropertyGroup>
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>bin\Release\</PublishDir>
|
||||
<PublishDir>bin\Release\Windows</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<_TargetId>Folder</_TargetId>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
|
@ -47,7 +47,16 @@ namespace ChovySign_GUI.Global
|
|||
|
||||
if(Parameters is null) { await MessageBox.Show(currentWindow, "ChovySignParameters was null, cannot start!", "Invalid Parameters", MessageBoxButtons.Ok); return; }
|
||||
|
||||
await Task.Run(() => { chovySign.Go(Parameters); });
|
||||
await Task.Run(() => {
|
||||
try
|
||||
{
|
||||
chovySign.Go(Parameters);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Dispatcher.UIThread.Post(() => { _ = MessageBox.Show(currentWindow, "Error building: " + e.Message + "\n\nSTACKTRACE: " + e.StackTrace, "ERROR", MessageBoxButtons.Ok); });
|
||||
}
|
||||
});
|
||||
|
||||
OnFinished(new EventArgs());
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
|
||||
namespace ChovySign_GUI
|
||||
|
|
|
@ -103,7 +103,12 @@ namespace ChovySign_GUI.Ps1
|
|||
loadIcon(newCover);
|
||||
iconCache = newCover;
|
||||
}
|
||||
catch (Exception) { }
|
||||
catch (Exception e) {
|
||||
Window? currentWindow = this.VisualRoot as Window;
|
||||
if (currentWindow is not Window) throw new Exception("could not find current window");
|
||||
|
||||
await MessageBox.Show(currentWindow, "unable to read cue sheet: " + Path.GetFileName(cueFile) + "\n" + e.Message + "\n\nSTACKTRACE: " + e.StackTrace, "cannot load cue sheet", MessageBox.MessageBoxButtons.Ok);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<byte[]?> doLoad(BrowseButton imgFile, int width, int height)
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace ChovySign_GUI.Psp
|
|||
{
|
||||
keySelector.IsEnabled = true;
|
||||
isoSelector.IsEnabled = true;
|
||||
SettingsTab.Settings.IsEnabled = false;
|
||||
SettingsTab.Settings.IsEnabled = true;
|
||||
|
||||
Window? currentWindow = this.VisualRoot as Window;
|
||||
if (currentWindow is not Window) throw new Exception("could not find current window");
|
||||
|
|
|
@ -3,6 +3,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Channels;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -12,6 +13,9 @@ namespace GameBuilder.Atrac3
|
|||
{
|
||||
public class Atrac3ToolEncoder : IAtracEncoderBase
|
||||
{
|
||||
[DllImport("libc")]
|
||||
private static extern int setenv(string name, string value, bool overwrite);
|
||||
|
||||
private static Random rng = new Random();
|
||||
private static string TOOLS_DIRECTORY = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tools");
|
||||
|
||||
|
@ -19,6 +23,7 @@ namespace GameBuilder.Atrac3
|
|||
private static string AT3TOOL_LINUX = Path.Combine(TOOLS_DIRECTORY, "at3tool.elf");
|
||||
|
||||
private static string TEMP_DIRECTORY = Path.Combine(Path.GetTempPath(), "at3tool_tmp");
|
||||
private static string LD_LIBRARY_PATH = "LD_LIBRARY_PATH";
|
||||
|
||||
// random name so that can generate multiple at once if wanted ..
|
||||
private string TEMP_WAV;
|
||||
|
@ -45,10 +50,24 @@ namespace GameBuilder.Atrac3
|
|||
}
|
||||
}
|
||||
|
||||
private string setupLibaryPath()
|
||||
{
|
||||
string? libaryPath = Environment.GetEnvironmentVariable(LD_LIBRARY_PATH);
|
||||
if (libaryPath is null) libaryPath = TOOLS_DIRECTORY;
|
||||
else libaryPath += ";" + TOOLS_DIRECTORY;
|
||||
|
||||
Environment.SetEnvironmentVariable(libaryPath, libaryPath);
|
||||
setenv(LD_LIBRARY_PATH, libaryPath, true);
|
||||
|
||||
return libaryPath;
|
||||
}
|
||||
private void runAtrac3Tool()
|
||||
{
|
||||
using(Process proc = new Process())
|
||||
{
|
||||
if (OperatingSystem.IsLinux())
|
||||
proc.StartInfo.Environment.Add(LD_LIBRARY_PATH, setupLibaryPath());
|
||||
|
||||
proc.StartInfo.FileName = AT3TOOL_LOCATION;
|
||||
proc.StartInfo.Arguments = "-br 132 -e \"" + TEMP_WAV + "\" \"" + TEMP_AT3 + "\"";
|
||||
|
||||
|
|
|
@ -300,6 +300,19 @@ namespace GameBuilder.Cue
|
|||
openTracks.Clear();
|
||||
}
|
||||
|
||||
private string getFilename(string str)
|
||||
{
|
||||
if (!str.Contains(' ')) throw new Exception("cue specifies no bin file.");
|
||||
if (!str.Contains('"')) return str.Split(' ')[1];
|
||||
|
||||
int start = str.IndexOf('"');
|
||||
str = str.Substring(start + 1);
|
||||
|
||||
|
||||
int end = str.IndexOf('"');
|
||||
str = str.Substring(0, end);
|
||||
return str;
|
||||
}
|
||||
public CueReader(string cueFile)
|
||||
{
|
||||
openTracks = new Dictionary<int, CueStream>();
|
||||
|
@ -310,10 +323,11 @@ namespace GameBuilder.Cue
|
|||
CueTrack? curTrack = null;
|
||||
|
||||
for (string? cueData = cueReader.ReadLine();
|
||||
cueData != null;
|
||||
cueData is not null;
|
||||
cueData = cueReader.ReadLine())
|
||||
{
|
||||
string[] cueLn = cueData.Trim().Replace("\r", "").Replace("\n", "").Split(' ');
|
||||
cueData = cueData.Trim().Replace("\r", "").Replace("\n", "");
|
||||
string[] cueLn = cueData.Split(' ');
|
||||
|
||||
if (cueLn[0] == "INDEX")
|
||||
{
|
||||
|
@ -350,17 +364,17 @@ namespace GameBuilder.Cue
|
|||
if (curTrack != null) setTrackNumber(curTrack.TrackNo, ref curTrack);
|
||||
|
||||
// parse out filename..
|
||||
string[] cueFnameParts = new string[cueLn.Length - 2];
|
||||
Array.ConstrainedCopy(cueLn, 1, cueFnameParts, 0, cueFnameParts.Length);
|
||||
string cueFname = String.Join(' ', cueFnameParts);
|
||||
|
||||
// open file ..
|
||||
string binFileName = cueFname.Substring(1, cueFname.Length - 2);
|
||||
string binFileName = getFilename(cueData);
|
||||
string? folderContainingCue = Path.GetDirectoryName(cueFile);
|
||||
|
||||
if (folderContainingCue != null)
|
||||
binFileName = Path.Combine(folderContainingCue, binFileName);
|
||||
|
||||
if(!File.Exists(binFileName))
|
||||
binFileName = Path.ChangeExtension(cueFile, ".bin");
|
||||
|
||||
if (!File.Exists(binFileName)) throw new FileNotFoundException("unable to find bin file.");
|
||||
|
||||
curTrack = new CueTrack(binFileName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,9 @@ namespace GameBuilder.Pops
|
|||
this.createSimpleDat();
|
||||
this.SimplePgd = CreatePgd(simple.ToArray());
|
||||
|
||||
this.EbootElf = Resources.DATAPSPSD;
|
||||
this.ConfigBin = Resources.DATAPSPSDCFG;
|
||||
this.PatchEboot = true;
|
||||
}
|
||||
internal void createSimpleDat()
|
||||
{
|
||||
|
@ -55,27 +58,41 @@ namespace GameBuilder.Pops
|
|||
{
|
||||
Span<byte> loaderEnc = new byte[0x9B13];
|
||||
|
||||
byte[] dataPspElf = Resources.DATAPSPSD;
|
||||
//byte[] dataPspElf = Resources.DATAPSPSD;
|
||||
|
||||
// calculate size low and high part ..
|
||||
uint szLow = Convert.ToUInt32(Psar.Length) >> 16;
|
||||
uint szHigh = Convert.ToUInt32(Psar.Length) & 0xFFFF;
|
||||
if (this.PatchEboot)
|
||||
{
|
||||
// calculate size low and high part ..
|
||||
uint szLow = Convert.ToUInt32(Psar.Length) >> 16;
|
||||
uint szHigh = Convert.ToUInt32(Psar.Length) & 0xFFFF;
|
||||
|
||||
// convert to big endain bytes
|
||||
byte[] lowBits = BitConverter.GetBytes(Convert.ToUInt16(szLow)).ToArray();
|
||||
byte[] highBits = BitConverter.GetBytes(Convert.ToUInt16(szHigh)).ToArray();
|
||||
// convert to big endain bytes
|
||||
byte[] lowBits = BitConverter.GetBytes(Convert.ToUInt16(szLow)).ToArray();
|
||||
byte[] highBits = BitConverter.GetBytes(Convert.ToUInt16(szHigh)).ToArray();
|
||||
|
||||
// overwrite data.psar size check ..
|
||||
Array.ConstrainedCopy(lowBits, 0, dataPspElf, 0x68C, 0x2);
|
||||
Array.ConstrainedCopy(highBits, 0, dataPspElf, 0x694, 0x2);
|
||||
// overwrite data.psar size check ..
|
||||
Array.ConstrainedCopy(lowBits, 0, this.EbootElf, 0x68C, 0x2);
|
||||
Array.ConstrainedCopy(highBits, 0, this.EbootElf, 0x694, 0x2);
|
||||
}
|
||||
|
||||
SceMesgLed.Encrypt(loaderEnc, dataPspElf, 0x0DAA06F0, SceExecFileDecryptMode.DECRYPT_MODE_POPS_EXEC, DrmInfo.VersionKey, DrmInfo.ContentId, Resources.DATAPSPSDCFG);
|
||||
SceMesgLed.Encrypt(
|
||||
loaderEnc,
|
||||
this.EbootElf,
|
||||
0x0DAA06F0,
|
||||
SceExecFileDecryptMode.DECRYPT_MODE_POPS_EXEC,
|
||||
DrmInfo.VersionKey,
|
||||
DrmInfo.ContentId,
|
||||
this.ConfigBin);
|
||||
return loaderEnc.ToArray();
|
||||
}
|
||||
|
||||
private MemoryStream simple;
|
||||
private StreamUtil simpleUtil;
|
||||
|
||||
public byte[] EbootElf;
|
||||
public byte[] ConfigBin;
|
||||
public bool PatchEboot;
|
||||
|
||||
public byte[] StartDat;
|
||||
public byte[] SimplePgd;
|
||||
|
||||
|
|
|
@ -43,8 +43,8 @@ namespace GameBuilder.Psp
|
|||
public void PatchSfo()
|
||||
{
|
||||
Sfo sfoKeys = Sfo.ReadSfo(umdImage.DataFiles["PARAM.SFO"]);
|
||||
if ((sfoKeys["CATEGORY"] as String) == "UG") // "UMD Game"
|
||||
sfoKeys["CATEGORY"] = "EG"; // set it to "Eboot Game"
|
||||
//if ((sfoKeys["CATEGORY"] as String) == "UG") // "UMD Game"
|
||||
sfoKeys["CATEGORY"] = "EG"; // set it to "Eboot Game"
|
||||
umdImage.DataFiles["PARAM.SFO"] = sfoKeys.WriteSfo();
|
||||
}
|
||||
private void createNpHdr()
|
||||
|
|
|
@ -12,12 +12,12 @@ namespace GameBuilder.Psp
|
|||
{
|
||||
private string[] filesList = new string[]
|
||||
{
|
||||
"PSP_GAME\\ICON0.PNG",
|
||||
"PSP_GAME\\ICON1.PMF",
|
||||
"PSP_GAME\\PARAM.SFO",
|
||||
"PSP_GAME\\PIC0.PNG",
|
||||
"PSP_GAME\\PIC1.PNG",
|
||||
"PSP_GAME\\SND0.AT3"
|
||||
Path.Combine("PSP_GAME","ICON0.PNG"),
|
||||
Path.Combine("PSP_GAME","ICON1.PMF"),
|
||||
Path.Combine("PSP_GAME","PARAM.SFO"),
|
||||
Path.Combine("PSP_GAME","PIC0.PNG"),
|
||||
Path.Combine("PSP_GAME","PIC1.PNG"),
|
||||
Path.Combine("PSP_GAME","SND0.AT3")
|
||||
};
|
||||
|
||||
public Dictionary<string, byte[]?> DataFiles = new Dictionary<string, byte[]?>();
|
||||
|
@ -27,12 +27,12 @@ namespace GameBuilder.Psp
|
|||
this.IsoStream = File.OpenRead(isoFile);
|
||||
using (CDReader cdReader = new CDReader(this.IsoStream, true, true))
|
||||
{
|
||||
foreach (string file in filesList)
|
||||
foreach (string file in this.filesList)
|
||||
{
|
||||
string fname = Path.GetFileName(file).ToUpperInvariant();
|
||||
if (cdReader.FileExists(file))
|
||||
if (cdReader.FileExists(file.Replace('/', '\\')))
|
||||
{
|
||||
using (SparseStream s = cdReader.OpenFile(file, FileMode.Open))
|
||||
using (SparseStream s = cdReader.OpenFile(file.Replace('/', '\\'), FileMode.Open))
|
||||
{
|
||||
byte[] data = new byte[s.Length];
|
||||
|
||||
|
@ -48,11 +48,14 @@ namespace GameBuilder.Psp
|
|||
}
|
||||
}
|
||||
|
||||
byte[]? paramFile = DataFiles["PARAM.SFO"];
|
||||
if (paramFile is null) throw new Exception("ISO contains no PARAM.SFO file, so this is not a valid PSP game.");
|
||||
|
||||
if (DataFiles["PARAM.SFO"] is null) throw new Exception("ISO contains no PARAM.SFO file, so this is not a valid PSP game.");
|
||||
Sfo sfo = Sfo.ReadSfo(paramFile);
|
||||
string? discId = sfo["DISC_ID"] as String;
|
||||
if (discId is null) throw new Exception("PARAM.SFO does not contain \"DISC_ID\"");
|
||||
|
||||
Sfo sfo = Sfo.ReadSfo(DataFiles["PARAM.SFO"]);
|
||||
this.DiscId = sfo["DISC_ID"] as String;
|
||||
this.DiscId = discId;
|
||||
|
||||
// check minis
|
||||
if (sfo["ATTRIBUTE"] is UInt32)
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace LibChovy.Art
|
|||
using (Image psnBorder = Image.Load(Resources.ICON0))
|
||||
{
|
||||
|
||||
coverImage.Mutate(x => x.Crop(new Rectangle(80, 0, coverImage.Width - 80, coverImage.Height)));
|
||||
//coverImage.Mutate(x => x.Crop(new Rectangle(80, 0, coverImage.Width - 80, coverImage.Height)));
|
||||
coverImage.Mutate(x => x.Resize(58, 58));
|
||||
psnBorder.Mutate(x => x.DrawImage(coverImage, new Point(13, 11), 1.0f));
|
||||
|
||||
|
|
|
@ -62,6 +62,17 @@ namespace LibChovy
|
|||
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);
|
||||
|
|
|
@ -19,6 +19,9 @@ namespace LibChovy
|
|||
Type = ChovyTypes.POPS;
|
||||
discList = new List<PSInfo>();
|
||||
|
||||
EbootElfOverride = null;
|
||||
ConfigBinOverride = null;
|
||||
|
||||
discIdOverride = null;
|
||||
nameOverride = null;
|
||||
libCryptMethod = LibCryptMethod.METHOD_MAGIC_WORD;
|
||||
|
@ -32,6 +35,10 @@ namespace LibChovy
|
|||
private byte[]? pic1;
|
||||
private byte[]? icon0;
|
||||
|
||||
|
||||
public byte[]? EbootElfOverride;
|
||||
public byte[]? ConfigBinOverride;
|
||||
|
||||
public PSInfo FirstDisc
|
||||
{
|
||||
get
|
||||
|
|
|
@ -75,7 +75,50 @@ namespace Vita.ContentManager
|
|||
|
||||
private static string getDefaultCmaPSVitaFolder()
|
||||
{
|
||||
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "PS Vita");
|
||||
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "PS Vita");
|
||||
}
|
||||
|
||||
private static string getQcmaConfFile()
|
||||
{
|
||||
if (OperatingSystem.IsLinux())
|
||||
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".config", "codestation", "qcma.conf");
|
||||
else if (OperatingSystem.IsMacOS())
|
||||
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Library", "Preferences", "com.codestation.qcma.plist");
|
||||
else
|
||||
throw new PlatformNotSupportedException("cannot open qcma config as i dont know where it is.");
|
||||
}
|
||||
private static string? getQcmaConfigSetting(string file, string key)
|
||||
{
|
||||
if (!File.Exists(file)) return null;
|
||||
|
||||
if (OperatingSystem.IsLinux())
|
||||
{
|
||||
using (TextReader confFile = File.OpenText(file))
|
||||
{
|
||||
for (string? ln = confFile.ReadLine();
|
||||
ln is not null;
|
||||
ln = confFile.ReadLine())
|
||||
{
|
||||
ln = ln.Trim();
|
||||
if (ln.StartsWith("[")) continue;
|
||||
|
||||
string[] kvp = ln.Split('=');
|
||||
if (kvp.Length < 2) continue;
|
||||
|
||||
string settingKey = kvp[0].Trim();
|
||||
string settingValue = kvp[1].Trim();
|
||||
|
||||
|
||||
if (settingKey == key)
|
||||
return settingValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (OperatingSystem.IsMacOS())
|
||||
{
|
||||
throw new PlatformNotSupportedException("TODO: Implement reading bplist file from mac os");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string? getRegistryKey(string registryPath, string keyName)
|
||||
|
@ -116,15 +159,12 @@ namespace Vita.ContentManager
|
|||
{
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
using(RegistryKey? qcmaKey = Registry.CurrentUser.OpenSubKey(@"Software\codestation\qcma"))
|
||||
{
|
||||
return getRegistryKey(@"Software\codestation\qcma", "appsPath");
|
||||
}
|
||||
return getRegistryKey(@"Software\codestation\qcma", "appsPath");
|
||||
}
|
||||
else if (OperatingSystem.IsLinux())
|
||||
{
|
||||
string qcmaConfigPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".config", "codestation", "qcma.conf");
|
||||
// TODO: read file
|
||||
string qcmaConf = getQcmaConfFile();
|
||||
return getQcmaConfigSetting(qcmaConf, "appsPath");
|
||||
}
|
||||
else if (OperatingSystem.IsMacOS())
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue