From a1063aa08df6a8b99cc00e2810f9c7fcd29b4a53 Mon Sep 17 00:00:00 2001 From: Alex Barney Date: Wed, 6 Feb 2019 13:08:41 -0600 Subject: [PATCH] stash --- src/Net/Cache.cs | 68 +++++++++++++++++++++++++++++++++++++++ src/Net/CliParser.cs | 12 ++----- src/Net/ContentManager.cs | 34 ++++++++++++++++++++ src/Net/NetContext.cs | 7 ++-- src/Net/Options.cs | 3 -- src/Net/Program.cs | 31 +++++++----------- src/Net/Urls.cs | 32 ++++++++++++++++++ 7 files changed, 152 insertions(+), 35 deletions(-) create mode 100644 src/Net/Cache.cs create mode 100644 src/Net/ContentManager.cs create mode 100644 src/Net/Urls.cs diff --git a/src/Net/Cache.cs b/src/Net/Cache.cs new file mode 100644 index 00000000..b08d63d4 --- /dev/null +++ b/src/Net/Cache.cs @@ -0,0 +1,68 @@ +using System.Linq; +using LibHac; +using LibHac.IO; + +namespace Net +{ + public class Cache + { + private IFileSystem CacheFs { get; } + + public Cache(IFileSystem cacheFs) + { + CacheFs = cacheFs; + } + + public bool TryOpenNca(ulong titleId, int version, byte[] ncaId, out IFile file) + { + file = default; + + string titleDir = GetTitleDir(titleId, version); + if (!CacheFs.DirectoryExists(titleDir)) return false; + + string filePath = $"{titleDir}/{ncaId.ToHexString().ToLower()}.nca"); + + if (CacheFs.FileExists(filePath)) + { + file = CacheFs.OpenFile(filePath, OpenMode.Read); + return true; + } + + return false; + } + + public bool TryOpenMetaNca(ulong titleId, int version, out IFile file) + { + file = default; + string titleDir = GetTitleDir(titleId, version); + if (!CacheFs.DirectoryExists(titleDir)) return false; + + IDirectory dir = CacheFs.OpenDirectory(titleDir, OpenDirectoryMode.All); + + DirectoryEntry[] metaFiles = dir.EnumerateEntries("*.cnmt.nca", SearchOptions.Default).ToArray(); + + if (metaFiles.Length == 1) + { + file = CacheFs.OpenFile(metaFiles[0].FullPath, OpenMode.Read); + return true; + } + + if (metaFiles.Length > 1) + { + throw new System.IO.FileNotFoundException($"More than 1 cnmt file exists for {titleId:x16}v{version}"); + } + + return false; + } + + private string GetTitleDir(ulong titleId, int version = -1) + { + if (version >= 0) + { + return $"/{titleId:x16}/{version}"; + } + + return $"/{titleId:x16}"; + } + } +} diff --git a/src/Net/CliParser.cs b/src/Net/CliParser.cs index 2efdf930..b26c5579 100644 --- a/src/Net/CliParser.cs +++ b/src/Net/CliParser.cs @@ -9,15 +9,8 @@ namespace Net { private static readonly CliOption[] CliOptions = { - new CliOption("keyset", 'k', 1, (o, a) => o.Keyfile = a[0]), - new CliOption("titlekeys", 1, (o, a) => o.TitleKeyFile = a[0]), - new CliOption("consolekeys", 1, (o, a) => o.ConsoleKeyFile = a[0]), new CliOption("title", 1, (o, a) => o.TitleId = ParseTitleId(a[0])), new CliOption("version", 1, (o, a) => o.Version = ParseVersion(a[0])), - new CliOption("did", 1, (o, a) => o.DeviceId = ParseTitleId(a[0])), - new CliOption("cert", 1, (o, a) => o.CertFile = a[0]), - new CliOption("commoncert", 1, (o, a) => o.CommonCertFile = a[0]), - new CliOption("token", 1, (o, a) => o.Token = a[0]), new CliOption("metadata", 0, (o, a) => o.GetMetadata = true) }; @@ -62,12 +55,11 @@ namespace Net option.Assigner(options, optionArgs); i += option.ArgsNeeded; } - - + return options; } - private static ulong ParseTitleId(string input) + public static ulong ParseTitleId(string input) { if (input.Length != 16) { diff --git a/src/Net/ContentManager.cs b/src/Net/ContentManager.cs new file mode 100644 index 00000000..49623a72 --- /dev/null +++ b/src/Net/ContentManager.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text; +using LibHac; +using LibHac.IO; + +namespace Net +{ + public class ContentManager + { + private IFileSystem ContentFs { get; } + private Cache ContentCache { get; } + + public ContentManager(IFileSystem contentFs) + { + ContentFs = contentFs; + ContentCache = new Cache(contentFs); + } + + public bool OpenCnmtFile(ulong titleId, int version, out IFile file) + { + if (ContentCache.TryOpenMetaNca(titleId, version, out file)) + { + return true; + } + if (cnmt != null) return cnmt; + + if (Certificate == null) return null; + + DownloadCnmt(titleId, version); + return GetCnmtFileFromCache(titleId, version); + } + } +} diff --git a/src/Net/NetContext.cs b/src/Net/NetContext.cs index b13ba7d3..562c3aa6 100644 --- a/src/Net/NetContext.cs +++ b/src/Net/NetContext.cs @@ -17,7 +17,7 @@ namespace Net private string Token { get; } private string Eid { get; } = "lp1"; private ulong Did { get; } - private string Firmware { get; } = "6.0.0-5.0"; + private string Firmware { get; } = "7.0.0-1.0"; private string CachePath { get; } = "titles"; private Context ToolCtx { get; } public Database Db { get; } @@ -284,8 +284,9 @@ namespace Net try { - if (((HttpWebResponse)request.GetResponse()).StatusCode == HttpStatusCode.OK) - return request.GetResponse(); + var response = (HttpWebResponse) request.GetResponse(); + if (response.StatusCode == HttpStatusCode.OK) + return response; } catch (WebException ex) { diff --git a/src/Net/Options.cs b/src/Net/Options.cs index abbc82aa..72021509 100644 --- a/src/Net/Options.cs +++ b/src/Net/Options.cs @@ -4,9 +4,6 @@ namespace Net { internal class Options { - public string Keyfile; - public string TitleKeyFile; - public string ConsoleKeyFile; public ulong TitleId; public int Version; public ulong DeviceId; diff --git a/src/Net/Program.cs b/src/Net/Program.cs index 6ec7ce11..ec0268bc 100644 --- a/src/Net/Program.cs +++ b/src/Net/Program.cs @@ -10,11 +10,22 @@ namespace Net { public static class Program { + private const string DidFile = "device_id.txt"; + private const string TokenFile = "edge_token.txt"; + private const string CertFile = "nx_tls_client_cert.pfx"; + private const string CommonCertFile = "ShopN.p12"; + public static void Main(string[] args) { Console.OutputEncoding = Encoding.UTF8; var ctx = new Context(); ctx.Options = CliParser.Parse(args); + + ctx.Options.DeviceId = CliParser.ParseTitleId(File.ReadAllText(DidFile)); + ctx.Options.Token = File.ReadAllText(TokenFile); + ctx.Options.CertFile = CertFile; + ctx.Options.CommonCertFile = CommonCertFile; + if (ctx.Options == null) return; using (var logger = new ProgressBar()) @@ -153,26 +164,8 @@ namespace Net string homeKeyFile = Path.Combine(home, ".switch", "prod.keys"); string homeTitleKeyFile = Path.Combine(home, ".switch", "title.keys"); string homeConsoleKeyFile = Path.Combine(home, ".switch", "console.keys"); - string keyFile = ctx.Options.Keyfile; - string titleKeyFile = ctx.Options.TitleKeyFile; - string consoleKeyFile = ctx.Options.ConsoleKeyFile; - if (keyFile == null && File.Exists(homeKeyFile)) - { - keyFile = homeKeyFile; - } - - if (titleKeyFile == null && File.Exists(homeTitleKeyFile)) - { - titleKeyFile = homeTitleKeyFile; - } - - if (consoleKeyFile == null && File.Exists(homeConsoleKeyFile)) - { - consoleKeyFile = homeConsoleKeyFile; - } - - ctx.Keyset = ExternalKeys.ReadKeyFile(keyFile, titleKeyFile, consoleKeyFile, ctx.Logger); + ctx.Keyset = ExternalKeys.ReadKeyFile(homeKeyFile, homeTitleKeyFile, homeConsoleKeyFile, ctx.Logger); } private static List GetTitleIds(string filename) diff --git a/src/Net/Urls.cs b/src/Net/Urls.cs new file mode 100644 index 00000000..29cac50d --- /dev/null +++ b/src/Net/Urls.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Net +{ + public static class Urls + { + private const string Eid = "lp1"; + public static string Did { get; set; } + + public static string GetSuperflyUrl(ulong titleId) + { + return $"https://superfly.hac.{Eid}.d4c.nintendo.net/v1/a/{titleId:x16}/dv"; + } + + public static string GetMetaQueryUrl(ulong titleId, int version) + { + return $"https://atum.hac.{Eid}.d4c.nintendo.net/t/a/{titleId:x16}/{version}?deviceid={Did}"; + } + + public static string GetMetaContentUrl(string ncaId) + { + return $"https://atum.hac.{Eid}.d4c.nintendo.net/c/a/{ncaId}"; + } + + public static string GetContentUrl(string ncaId) + { + return $"https://atum.hac.{Eid}.d4c.nintendo.net/c/c/{ncaId}"; + } + } +}