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");
|
||||
ListTitles(sdfs);
|
||||
|
||||
Console.WriteLine("Listing applications");
|
||||
ListApplications(sdfs);
|
||||
|
||||
//DecryptNax0(sdfs, "C0628FB07A89E9050BDA258F74868E8D");
|
||||
//DecryptTitle(sdfs, 0x010023900AEE0000);
|
||||
}
|
||||
|
@ -151,5 +154,38 @@ namespace hactoolnet
|
|||
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)
|
||||
{
|
||||
case TitleType.Application:
|
||||
ApplicationTitleId = TitleId;
|
||||
PatchTitleId = reader.ReadUInt64();
|
||||
MinimumSystemVersion = new TitleVersion(reader.ReadUInt32(), true);
|
||||
break;
|
||||
|
|
|
@ -6,6 +6,17 @@ namespace libhac
|
|||
{
|
||||
public NacpLang[] Languages { get; } = new NacpLang[0x10];
|
||||
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)
|
||||
{
|
||||
|
@ -18,6 +29,18 @@ namespace libhac
|
|||
|
||||
reader.BaseStream.Position = start + 0x3060;
|
||||
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<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>();
|
||||
|
||||
|
@ -35,6 +36,7 @@ namespace libhac
|
|||
OpenAllNcas();
|
||||
ReadTitles();
|
||||
ReadControls();
|
||||
CreateApplications();
|
||||
}
|
||||
|
||||
private void OpenAllNcas()
|
||||
|
@ -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)
|
||||
{
|
||||
List<string> files = new List<string>();
|
||||
|
@ -218,44 +237,72 @@ namespace libhac
|
|||
public Nca MetaNca { get; internal set; }
|
||||
public Nca ProgramNca { 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 Title Main { 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 Version { get; private set; }
|
||||
public string DisplayVersion { get; private set; }
|
||||
|
||||
public void SetMainTitle(Title title)
|
||||
public void AddTitle(Title 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;
|
||||
}
|
||||
|
||||
public void SetPatchTitle(Title title)
|
||||
{
|
||||
if (title.Metadata.Type != TitleType.Patch) throw new InvalidDataException("Title is not a patch");
|
||||
break;
|
||||
case TitleType.Patch:
|
||||
Patch = title;
|
||||
break;
|
||||
case TitleType.AddOnContent:
|
||||
AddOnContent.Add(title);
|
||||
break;
|
||||
case TitleType.DeltaTitle:
|
||||
break;
|
||||
}
|
||||
|
||||
private void UpdateName()
|
||||
UpdateInfo();
|
||||
}
|
||||
|
||||
private void UpdateInfo()
|
||||
{
|
||||
if (Patch != null)
|
||||
{
|
||||
Name = Patch.Name;
|
||||
Version = Patch.Control?.Version ?? "";
|
||||
Version = Patch.Version;
|
||||
DisplayVersion = Patch.Control?.Version ?? "";
|
||||
Nacp = Patch.Control;
|
||||
}
|
||||
else if (Main != null)
|
||||
{
|
||||
Name = Main.Name;
|
||||
Version = Main.Control?.Version ?? "";
|
||||
Version = Main.Version;
|
||||
DisplayVersion = Main.Control?.Version ?? "";
|
||||
Nacp = Main.Control;
|
||||
}
|
||||
else
|
||||
{
|
||||
Name = "";
|
||||
Version = "";
|
||||
DisplayVersion = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue