mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Make sure meta nca is included in title
This commit is contained in:
parent
e4d9b46e60
commit
f583d01248
4 changed files with 65 additions and 5 deletions
|
@ -1,6 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using libhac;
|
using libhac;
|
||||||
|
@ -20,10 +18,12 @@ namespace hactoolnet
|
||||||
ListTitles(sdfs);
|
ListTitles(sdfs);
|
||||||
|
|
||||||
//DecryptNax0(sdfs, "C0628FB07A89E9050BDA258F74868E8D");
|
//DecryptNax0(sdfs, "C0628FB07A89E9050BDA258F74868E8D");
|
||||||
|
DecryptTitle(sdfs, 0x0100000000010800);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DecryptNax0(SdFs sdFs, string name)
|
static void DecryptNax0(SdFs sdFs, string name)
|
||||||
{
|
{
|
||||||
|
if (!sdFs.Ncas.ContainsKey(name)) return;
|
||||||
var nca = sdFs.Ncas[name];
|
var nca = sdFs.Ncas[name];
|
||||||
using (var output = new FileStream($"{nca.NcaId}.nca", FileMode.Create))
|
using (var output = new FileStream($"{nca.NcaId}.nca", FileMode.Create))
|
||||||
using (var progress = new ProgressBar())
|
using (var progress = new ProgressBar())
|
||||||
|
@ -35,6 +35,25 @@ namespace hactoolnet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void DecryptTitle(SdFs sdFs, ulong titleId)
|
||||||
|
{
|
||||||
|
var title = sdFs.Titles[titleId];
|
||||||
|
var dirName = $"{titleId:X16}v{title.Version.Version}";
|
||||||
|
|
||||||
|
Directory.CreateDirectory(dirName);
|
||||||
|
|
||||||
|
foreach (var nca in title.Ncas)
|
||||||
|
{
|
||||||
|
using (var output = new FileStream(Path.Combine(dirName, nca.Filename), FileMode.Create))
|
||||||
|
using (var progress = new ProgressBar())
|
||||||
|
{
|
||||||
|
progress.LogMessage($"Writing {nca.Filename}");
|
||||||
|
nca.Stream.Position = 0;
|
||||||
|
nca.Stream.CopyStream(output, nca.Stream.Length, progress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static SdFs LoadSdFs(string[] args)
|
static SdFs LoadSdFs(string[] args)
|
||||||
{
|
{
|
||||||
var keyset = ExternalKeys.ReadKeyFile(args[0]);
|
var keyset = ExternalKeys.ReadKeyFile(args[0]);
|
||||||
|
@ -60,7 +79,7 @@ namespace hactoolnet
|
||||||
foreach (var content in title.Metadata.ContentEntries)
|
foreach (var content in title.Metadata.ContentEntries)
|
||||||
{
|
{
|
||||||
Console.WriteLine(
|
Console.WriteLine(
|
||||||
$" {BitConverter.ToString(content.NcaId).Replace("-", "")}.nca {content.Type} {Util.GetBytesReadable(content.Size)}");
|
$" {content.NcaId.ToHexString()}.nca {content.Type} {Util.GetBytesReadable(content.Size)}");
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("");
|
Console.WriteLine("");
|
||||||
|
|
|
@ -9,6 +9,7 @@ namespace libhac
|
||||||
{
|
{
|
||||||
public NcaHeader Header { get; private set; }
|
public NcaHeader Header { get; private set; }
|
||||||
public string NcaId { get; set; }
|
public string NcaId { get; set; }
|
||||||
|
public string Filename { get; set; }
|
||||||
public bool HasRightsId { get; private set; }
|
public bool HasRightsId { get; private set; }
|
||||||
public int CryptoType { get; private set; }
|
public int CryptoType { get; private set; }
|
||||||
public byte[][] DecryptedKeys { get; } = Util.CreateJaggedArray<byte[][]>(4, 0x10);
|
public byte[][] DecryptedKeys { get; } = Util.CreateJaggedArray<byte[][]>(4, 0x10);
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace libhac
|
||||||
ReadTitles();
|
ReadTitles();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OpenAllNcas()
|
private void OpenAllNcas()
|
||||||
{
|
{
|
||||||
foreach (var file in Files)
|
foreach (var file in Files)
|
||||||
{
|
{
|
||||||
|
@ -43,6 +43,8 @@ namespace libhac
|
||||||
Nax0s.Add(nax0);
|
Nax0s.Add(nax0);
|
||||||
nca = new Nca(Keyset, nax0.Stream, false);
|
nca = new Nca(Keyset, nax0.Stream, false);
|
||||||
nca.NcaId = Path.GetFileNameWithoutExtension(file);
|
nca.NcaId = Path.GetFileNameWithoutExtension(file);
|
||||||
|
var extention = nca.Header.ContentType == ContentType.Meta ? ".cnmt.nca" : ".nca";
|
||||||
|
nca.Filename = nca.NcaId + extention;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -53,7 +55,7 @@ namespace libhac
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReadTitles()
|
private void ReadTitles()
|
||||||
{
|
{
|
||||||
foreach (var nca in Ncas.Values.Where(x => x.Header.ContentType == ContentType.Meta))
|
foreach (var nca in Ncas.Values.Where(x => x.Header.ContentType == ContentType.Meta))
|
||||||
{
|
{
|
||||||
|
@ -68,6 +70,18 @@ namespace libhac
|
||||||
title.Id = metadata.TitleId;
|
title.Id = metadata.TitleId;
|
||||||
title.Version = new TitleVersion(metadata.TitleVersion);
|
title.Version = new TitleVersion(metadata.TitleVersion);
|
||||||
title.Metadata = metadata;
|
title.Metadata = metadata;
|
||||||
|
title.Ncas.Add(nca);
|
||||||
|
|
||||||
|
foreach (var content in metadata.ContentEntries)
|
||||||
|
{
|
||||||
|
var ncaId = content.NcaId.ToHexString();
|
||||||
|
|
||||||
|
if (Ncas.TryGetValue(ncaId, out Nca contentNca))
|
||||||
|
{
|
||||||
|
title.Ncas.Add(contentNca);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Titles.Add(title.Id, title);
|
Titles.Add(title.Id, title);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,6 +177,32 @@ namespace libhac
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static readonly uint[] Lookup32 = CreateLookup32();
|
||||||
|
|
||||||
|
private static uint[] CreateLookup32()
|
||||||
|
{
|
||||||
|
var result = new uint[256];
|
||||||
|
for (int i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
string s = i.ToString("X2");
|
||||||
|
result[i] = s[0] + ((uint)s[1] << 16);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string ToHexString(this byte[] bytes)
|
||||||
|
{
|
||||||
|
var lookup32 = Lookup32;
|
||||||
|
var result = new char[bytes.Length * 2];
|
||||||
|
for (int i = 0; i < bytes.Length; i++)
|
||||||
|
{
|
||||||
|
var val = lookup32[bytes[i]];
|
||||||
|
result[2 * i] = (char)val;
|
||||||
|
result[2 * i + 1] = (char)(val >> 16);
|
||||||
|
}
|
||||||
|
return new string(result);
|
||||||
|
}
|
||||||
|
|
||||||
internal static long MediaToReal(long media)
|
internal static long MediaToReal(long media)
|
||||||
{
|
{
|
||||||
return MediaSize * media;
|
return MediaSize * media;
|
||||||
|
|
Loading…
Reference in a new issue