mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Group titles by main application
This commit is contained in:
parent
44fb0d39d4
commit
ca815312d3
4 changed files with 122 additions and 15 deletions
|
@ -27,6 +27,9 @@ namespace hactoolnet
|
||||||
Console.WriteLine("Listing titles");
|
Console.WriteLine("Listing titles");
|
||||||
ListTitles(sdfs);
|
ListTitles(sdfs);
|
||||||
|
|
||||||
|
Console.WriteLine("Listing applications");
|
||||||
|
ListApplications(sdfs);
|
||||||
|
|
||||||
//DecryptNax0(sdfs, "C0628FB07A89E9050BDA258F74868E8D");
|
//DecryptNax0(sdfs, "C0628FB07A89E9050BDA258F74868E8D");
|
||||||
//DecryptTitle(sdfs, 0x010023900AEE0000);
|
//DecryptTitle(sdfs, 0x010023900AEE0000);
|
||||||
}
|
}
|
||||||
|
@ -151,5 +154,38 @@ namespace hactoolnet
|
||||||
Console.WriteLine("");
|
Console.WriteLine("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ListApplications(SdFs sdfs)
|
||||||
|
{
|
||||||
|
foreach (var app in sdfs.Applications.Values.OrderBy(x => x.Name))
|
||||||
|
{
|
||||||
|
Console.WriteLine($"{app.Name} v{app.DisplayVersion}");
|
||||||
|
|
||||||
|
long totalSize = 0;
|
||||||
|
if (app.Main != null)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Software: {Util.GetBytesReadable(app.Main.GetSize())}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (app.Patch != null)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Update Data: {Util.GetBytesReadable(app.Patch.GetSize())}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (app.AddOnContent.Count > 0)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"DLC: {Util.GetBytesReadable(app.AddOnContent.Sum(x => x.GetSize()))}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (app.Nacp?.UserTotalSaveDataSize > 0)
|
||||||
|
Console.WriteLine($"User save: {Util.GetBytesReadable(app.Nacp.UserTotalSaveDataSize)}");
|
||||||
|
if (app.Nacp?.DeviceTotalSaveDataSize > 0)
|
||||||
|
Console.WriteLine($"System save: {Util.GetBytesReadable(app.Nacp.DeviceTotalSaveDataSize)}");
|
||||||
|
if (app.Nacp?.BcatSaveDataSize > 0)
|
||||||
|
Console.WriteLine($"BCAT save: {Util.GetBytesReadable(app.Nacp.BcatSaveDataSize)}");
|
||||||
|
|
||||||
|
Console.WriteLine("");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ namespace libhac
|
||||||
switch (Type)
|
switch (Type)
|
||||||
{
|
{
|
||||||
case TitleType.Application:
|
case TitleType.Application:
|
||||||
|
ApplicationTitleId = TitleId;
|
||||||
PatchTitleId = reader.ReadUInt64();
|
PatchTitleId = reader.ReadUInt64();
|
||||||
MinimumSystemVersion = new TitleVersion(reader.ReadUInt32(), true);
|
MinimumSystemVersion = new TitleVersion(reader.ReadUInt32(), true);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -6,6 +6,17 @@ namespace libhac
|
||||||
{
|
{
|
||||||
public NacpLang[] Languages { get; } = new NacpLang[0x10];
|
public NacpLang[] Languages { get; } = new NacpLang[0x10];
|
||||||
public string Version { get; }
|
public string Version { get; }
|
||||||
|
public ulong AddOnContentBaseId { get; }
|
||||||
|
public ulong SaveDataOwnerId { get; }
|
||||||
|
public long UserAccountSaveDataSize { get; }
|
||||||
|
public long UserAccountSaveDataJournalSize { get; }
|
||||||
|
public long DeviceSaveDataSize { get; }
|
||||||
|
public long DeviceSaveDataJournalSize { get; }
|
||||||
|
public long BcatSaveDataSize { get; }
|
||||||
|
|
||||||
|
public long TotalSaveDataSize { get; }
|
||||||
|
public long UserTotalSaveDataSize { get; }
|
||||||
|
public long DeviceTotalSaveDataSize { get; }
|
||||||
|
|
||||||
public Nacp(BinaryReader reader)
|
public Nacp(BinaryReader reader)
|
||||||
{
|
{
|
||||||
|
@ -18,6 +29,18 @@ namespace libhac
|
||||||
|
|
||||||
reader.BaseStream.Position = start + 0x3060;
|
reader.BaseStream.Position = start + 0x3060;
|
||||||
Version = reader.ReadUtf8Z();
|
Version = reader.ReadUtf8Z();
|
||||||
|
reader.BaseStream.Position = start + 0x3070;
|
||||||
|
AddOnContentBaseId = reader.ReadUInt64();
|
||||||
|
SaveDataOwnerId = reader.ReadUInt64();
|
||||||
|
UserAccountSaveDataSize = reader.ReadInt64();
|
||||||
|
UserAccountSaveDataJournalSize = reader.ReadInt64();
|
||||||
|
DeviceSaveDataSize = reader.ReadInt64();
|
||||||
|
DeviceSaveDataJournalSize = reader.ReadInt64();
|
||||||
|
BcatSaveDataSize = reader.ReadInt64();
|
||||||
|
|
||||||
|
UserTotalSaveDataSize = UserAccountSaveDataSize + UserAccountSaveDataJournalSize;
|
||||||
|
DeviceTotalSaveDataSize = DeviceSaveDataSize + DeviceSaveDataJournalSize;
|
||||||
|
TotalSaveDataSize = UserTotalSaveDataSize + DeviceTotalSaveDataSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ namespace libhac
|
||||||
|
|
||||||
public Dictionary<string, Nca> Ncas { get; } = new Dictionary<string, Nca>(StringComparer.OrdinalIgnoreCase);
|
public Dictionary<string, Nca> Ncas { get; } = new Dictionary<string, Nca>(StringComparer.OrdinalIgnoreCase);
|
||||||
public Dictionary<ulong, Title> Titles { get; } = new Dictionary<ulong, Title>();
|
public Dictionary<ulong, Title> Titles { get; } = new Dictionary<ulong, Title>();
|
||||||
|
public Dictionary<ulong, Application> Applications { get; } = new Dictionary<ulong, Application>();
|
||||||
|
|
||||||
private List<Nax0> Nax0s { get; } = new List<Nax0>();
|
private List<Nax0> Nax0s { get; } = new List<Nax0>();
|
||||||
|
|
||||||
|
@ -35,6 +36,7 @@ namespace libhac
|
||||||
OpenAllNcas();
|
OpenAllNcas();
|
||||||
ReadTitles();
|
ReadTitles();
|
||||||
ReadControls();
|
ReadControls();
|
||||||
|
CreateApplications();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OpenAllNcas()
|
private void OpenAllNcas()
|
||||||
|
@ -68,7 +70,7 @@ namespace libhac
|
||||||
{
|
{
|
||||||
nca = new Nca(Keyset, stream, false);
|
nca = new Nca(Keyset, stream, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
nca.NcaId = Path.GetFileNameWithoutExtension(file);
|
nca.NcaId = Path.GetFileNameWithoutExtension(file);
|
||||||
var extention = nca.Header.ContentType == ContentType.Meta ? ".cnmt.nca" : ".nca";
|
var extention = nca.Header.ContentType == ContentType.Meta ? ".cnmt.nca" : ".nca";
|
||||||
nca.Filename = nca.NcaId + extention;
|
nca.Filename = nca.NcaId + extention;
|
||||||
|
@ -147,6 +149,23 @@ namespace libhac
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CreateApplications()
|
||||||
|
{
|
||||||
|
foreach (var title in Titles.Values.Where(x => x.Metadata.Type >= TitleType.Application))
|
||||||
|
{
|
||||||
|
var meta = title.Metadata;
|
||||||
|
ulong appId = meta.ApplicationTitleId;
|
||||||
|
|
||||||
|
if (!Applications.TryGetValue(appId, out var app))
|
||||||
|
{
|
||||||
|
app = new Application();
|
||||||
|
Applications.Add(appId, app);
|
||||||
|
}
|
||||||
|
|
||||||
|
app.AddTitle(title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal static Stream OpenSplitNcaStream(string path)
|
internal static Stream OpenSplitNcaStream(string path)
|
||||||
{
|
{
|
||||||
List<string> files = new List<string>();
|
List<string> files = new List<string>();
|
||||||
|
@ -218,44 +237,72 @@ namespace libhac
|
||||||
public Nca MetaNca { get; internal set; }
|
public Nca MetaNca { get; internal set; }
|
||||||
public Nca ProgramNca { get; internal set; }
|
public Nca ProgramNca { get; internal set; }
|
||||||
public Nca ControlNca { get; internal set; }
|
public Nca ControlNca { get; internal set; }
|
||||||
|
|
||||||
|
public long GetSize()
|
||||||
|
{
|
||||||
|
return Metadata.ContentEntries
|
||||||
|
.Where(x => x.Type < CnmtContentType.UpdatePatch)
|
||||||
|
.Sum(x => x.Size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Application
|
public class Application
|
||||||
{
|
{
|
||||||
public Title Main { get; private set; }
|
public Title Main { get; private set; }
|
||||||
public Title Patch { get; private set; }
|
public Title Patch { get; private set; }
|
||||||
public List<Title> AddOnContent { get; private set; }
|
public List<Title> AddOnContent { get; } = new List<Title>();
|
||||||
|
|
||||||
|
public ulong TitleId { get; private set; }
|
||||||
|
public TitleVersion Version { get; private set; }
|
||||||
|
public Nacp Nacp { get; private set; }
|
||||||
|
|
||||||
public string Name { get; private set; }
|
public string Name { get; private set; }
|
||||||
public string Version { get; private set; }
|
public string DisplayVersion { get; private set; }
|
||||||
|
|
||||||
public void SetMainTitle(Title title)
|
public void AddTitle(Title title)
|
||||||
{
|
{
|
||||||
Main = title;
|
if (TitleId != 0 && title.Metadata.ApplicationTitleId != TitleId)
|
||||||
|
throw new InvalidDataException("Title IDs do not match");
|
||||||
|
TitleId = title.Metadata.ApplicationTitleId;
|
||||||
|
|
||||||
|
switch (title.Metadata.Type)
|
||||||
|
{
|
||||||
|
case TitleType.Application:
|
||||||
|
Main = title;
|
||||||
|
break;
|
||||||
|
case TitleType.Patch:
|
||||||
|
Patch = title;
|
||||||
|
break;
|
||||||
|
case TitleType.AddOnContent:
|
||||||
|
AddOnContent.Add(title);
|
||||||
|
break;
|
||||||
|
case TitleType.DeltaTitle:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPatchTitle(Title title)
|
private void UpdateInfo()
|
||||||
{
|
|
||||||
if (title.Metadata.Type != TitleType.Patch) throw new InvalidDataException("Title is not a patch");
|
|
||||||
Patch = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateName()
|
|
||||||
{
|
{
|
||||||
if (Patch != null)
|
if (Patch != null)
|
||||||
{
|
{
|
||||||
Name = Patch.Name;
|
Name = Patch.Name;
|
||||||
Version = Patch.Control?.Version ?? "";
|
Version = Patch.Version;
|
||||||
|
DisplayVersion = Patch.Control?.Version ?? "";
|
||||||
|
Nacp = Patch.Control;
|
||||||
}
|
}
|
||||||
else if (Main != null)
|
else if (Main != null)
|
||||||
{
|
{
|
||||||
Name = Main.Name;
|
Name = Main.Name;
|
||||||
Version = Main.Control?.Version ?? "";
|
Version = Main.Version;
|
||||||
|
DisplayVersion = Main.Control?.Version ?? "";
|
||||||
|
Nacp = Main.Control;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Name = "";
|
Name = "";
|
||||||
Version = "";
|
DisplayVersion = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue