Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions LibOrbisPkg/PKG/Enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ public enum ContentType : int
AL = 0x1C,
/* pkg_ps4_delta_patch */
DP = 0x1E,
/* pkg_ps5_app */
PS5GD = 0x20,
/* pkg_ps5_ac */
PS5AC = 0x21,
/* pkg_ps5_ac_nodata */
PS5AL = 0x22,
/* pkg_ps5_delta_patch */
PS5DP = 0x23,
};

public enum IROTag : int
Expand Down Expand Up @@ -682,6 +690,8 @@ public enum EntryId : uint
KEYMAP_RP__30__008_PNG = 0x000017F7,
KEYMAP_RP__30__009_PNG = 0x000017F8,
KEYMAP_RP__30__010_PNG = 0x000017F9,
// prospero
PARAM_JSON = 0x00002000,
};
public static class EntryNames
{
Expand Down
3 changes: 3 additions & 0 deletions LibOrbisPkg/PKG/Pkg.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ public class Pkg
public GenericEntry ChunkSha;
public GenericEntry ChunkXml;

// prospero
public GenericEntry ParamJson;

public List<Entry> Entries;

// Constants
Expand Down
8 changes: 8 additions & 0 deletions LibOrbisPkg/PKG/PkgReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ public Pkg ReadPkg()
}
catch (Exception) { }
break;
case EntryId.PARAM_JSON:
s.Position = entry.DataOffset;
pkg.ParamJson = new GenericEntry(EntryId.PARAM_JSON)
{
FileData = s.ReadBytes((int)entry.DataSize),
meta = entry,
};
break;
}
}
return pkg;
Expand Down
72 changes: 54 additions & 18 deletions PkgEditor/Views/PkgView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using System.IO.MemoryMappedFiles;
using LibOrbisPkg.PFS;
using LibOrbisPkg.SFO;
using System.Text.Json.Nodes;

namespace PkgEditor.Views
{
Expand Down Expand Up @@ -44,8 +45,16 @@ public PkgView(string path)
pkg = new PkgReader(s).ReadPkg();
try
{
using (var s = pkgFile.CreateViewStream((long)pkg.Header.pfs_image_offset, (long)pkg.Header.pfs_image_size, MemoryMappedFileAccess.Read))
ObjectPreview(PfsHeader.ReadFromStream(s), pfsHeaderTreeView);
// we can't currently read PFS out of prospero packages
if (pkg.Header.content_type < ContentType.PS5GD)
{
using (var s = pkgFile.CreateViewStream((long)pkg.Header.pfs_image_offset, (long)pkg.Header.pfs_image_size, MemoryMappedFileAccess.Read))
ObjectPreview(PfsHeader.ReadFromStream(s), pfsHeaderTreeView);
}
}
catch (UnauthorizedAccessException)
{
MessageBox.Show("This PKG file is likely incomplete! Please use the 'Combine PKG parts' tool first.");
}
catch (Exception e)
{
Expand All @@ -60,23 +69,50 @@ public PkgView(string path)
}
}
contentIdTextBox.Text = pkg.Header.content_id;
titleTextBox.Text = pkg.ParamSfo.ParamSfo["TITLE"]?.ToString();
sizeLabel.Text = FileView.HumanReadableFileSize((long)pkg.Header.package_size);
var category = pkg.ParamSfo.ParamSfo["CATEGORY"].ToString();
typeLabel.Text = SfoData.SfoTypes.Where(x => x.Category == category).FirstOrDefault() is SfoType t ? t.Description : "Unknown";
versionLabel.Text = pkg.ParamSfo.ParamSfo["VERSION"]?.ToString();
if (pkg.ParamSfo.ParamSfo["APP_VER"] is Utf8Value v)
{
appVerLabel.Text = v.Value;
}
else
{
appVerLabelLabel.Visible = false;
appVerLabel.Visible = false;
// PS4 uses PARAM.SFO, prospero uses param.json
if (pkg.Header.content_type < ContentType.PS5GD)
{
titleTextBox.Text = pkg.ParamSfo.ParamSfo["TITLE"]?.ToString();
sizeLabel.Text = FileView.HumanReadableFileSize((long)pkg.Header.package_size);
var category = pkg.ParamSfo.ParamSfo["CATEGORY"].ToString();
typeLabel.Text = SfoData.SfoTypes.Where(x => x.Category == category).FirstOrDefault() is SfoType t ? t.Description : "Unknown";
versionLabel.Text = pkg.ParamSfo.ParamSfo["VERSION"]?.ToString();
if (pkg.ParamSfo.ParamSfo["APP_VER"] is Utf8Value v)
{
appVerLabel.Text = v.Value;
}
else
{
appVerLabelLabel.Visible = false;
appVerLabel.Visible = false;
}
var sfoEditor = new SFOView(pkg.ParamSfo.ParamSfo, true);
sfoEditor.Dock = DockStyle.Fill;
tabPage1.Controls.Add(sfoEditor);
} else if (pkg.ParamJson != null)
{
string jsonStr = Encoding.UTF8.GetString(pkg.ParamJson.FileData);
JsonNode paramData = JsonNode.Parse(jsonStr);
string defaultLanguage = (string)paramData["localizedParameters"]["defaultLanguage"];
// TODO: how do we get category
titleTextBox.Text = (string)paramData["localizedParameters"][defaultLanguage]["titleName"];
sizeLabel.Text = FileView.HumanReadableFileSize((long)pkg.Header.package_size);
versionLabel.Text = (string)paramData["contentVersion"];
if (paramData["masterVersion"] != null)
{
appVerLabel.Text = (string)paramData["masterVersion"];
} else
{
appVerLabelLabel.Visible = false;
appVerLabel.Visible = false;
}
// we can't do any of this for prospero content
button2.Visible = false; // can't export GP4
mainTabControl.TabPages.Remove(tabPage1); // no SFO tab
mainTabControl.TabPages.Remove(tabPage2); // no digests tab
mainTabControl.TabPages.Remove(filesTab); // no files tab
pkgHeaderTabControl.TabPages.Remove(outerPfsHeaderTabPage); // can't look at PFS
}
var sfoEditor = new SFOView(pkg.ParamSfo.ParamSfo, true);
sfoEditor.Dock = DockStyle.Fill;
tabPage1.Controls.Add(sfoEditor);


if (pkg.CheckPasscode("00000000000000000000000000000000"))
Expand Down
Loading