예제 #1
0
        public static async Task DownloadTitle(string id, string outputDir, string contentType, string version)
        {
            #region Setup

            var workingId = id.ToUpper();

            if (contentType == "Patch")
            {
                workingId = $"0005000E{workingId.Substring(8)}";

                if (Settings.Cemu173Patch)
                {
                    outputDir = Path.Combine(Settings.BasePatchDir, workingId.Substring(8));
                }
            }

            if (contentType == "DLC")
            {
                workingId = $"0005000C{workingId.Substring(8)}";

                if (Settings.Cemu173Patch)
                {
                    outputDir = Path.Combine(Settings.BasePatchDir, workingId.Substring(8), "aoc");
                }
            }

            Title title;
            if ((title = SearchById(workingId)) == null)
            {
                throw new Exception("Could not locate the title key");
            }

            var key  = title.Key;
            var name = title.Name;
            if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(name))
            {
                return;
            }

            if (!Directory.Exists(outputDir))
            {
                Directory.CreateDirectory(outputDir);
            }

            var str    = $"Download {contentType} content to the following location?\n\"{outputDir}\"";
            var result = MessageBox.Show(str, name, MessageBoxButtons.YesNo);

            if (result != DialogResult.Yes)
            {
                return;
            }

            Toolbelt.AppendLog($"Output Directory '{outputDir}'");

            #endregion

            #region TMD

            Toolbelt.AppendLog("  - Loading TMD...");
            TMD tmd = null;

            var nusUrls = new List <string>
            {
                "http://ccs.cdn.wup.shop.nintendo.net/ccs/download/",
                "http://nus.cdn.shop.wii.com/ccs/download/",
                "http://ccs.cdn.c.shop.nintendowifi.net/ccs/download/"
            };

            foreach (var nusUrl in nusUrls)
            {
                string titleUrl = $"{nusUrl}{workingId}/";
                tmd = await LoadTmd(id, key, outputDir, titleUrl, version);

                if (tmd != null)
                {
                    break;
                }
            }

            if (tmd == null)
            {
                TextLog.MesgLog.WriteError("Could not locate TMD. Is this content request valid?");
                return;
            }

            #endregion

            #region Ticket

            Toolbelt.AppendLog("Generating Ticket...");

            var tikData = MapleTicket.Create(SearchById(id));
            if (tikData == null)
            {
                throw new Exception("Invalid ticket data. Verify Title ID.");
            }

            var ticket = Ticket.Load(tikData);
            ticket.Save(Path.Combine(outputDir, "cetk"));

            #endregion

            #region Content

            Toolbelt.AppendLog($"[+] [{contentType}] {name} v{tmd.TitleVersion}");
            Toolbelt.SetStatus($"Output Directory: {outputDir}");

            foreach (var nusUrl in nusUrls)
            {
                var url = nusUrl + workingId;
                if (await DownloadContent(tmd, outputDir, url) != 1)
                {
                    continue;
                }

                Toolbelt.AppendLog(string.Empty);
                Toolbelt.AppendLog("  - Decrypting Content");
                Toolbelt.AppendLog("  + This may take a minute. Please wait...");
                Toolbelt.SetStatus("Decrypting Content. This may take a minute. Please wait...", Color.OrangeRed);

                if (await Toolbelt.CDecrypt(outputDir) != 0)
                {
                    CleanUp(outputDir, tmd);
                    Toolbelt.AppendLog($"Error while decrypting {name}");
                    return;
                }

                CleanUp(outputDir, tmd);
                break;
            }

            #endregion

            Web.ResetDownloadProgressChanged();
            Toolbelt.AppendLog($"[+] [{contentType}] {name} v{tmd.TitleVersion} Finished.");
            Toolbelt.SetStatus($"[+] [{contentType}] {name} v{tmd.TitleVersion} Finished.");
        }
예제 #2
0
        private static void DownloadTitle(string id, string outputDir, string contentType, string version)
        {
            #region Setup

            var workingId = id.ToUpper();

            //download dlc if applicable
            if (contentType == "DLC")
            {
                workingId = $"0005000C{workingId.Substring(8).ToUpper()}";
            }

            //download patch if applicable
            if (contentType == "Patch")
            {
                workingId = $"0005000E{workingId.Substring(8).ToUpper()}";
            }

            var title = Database.FindTitleKey(workingId);
            if (title.titleKey.Length != 32)
            {
                throw new Exception("Could not locate the title key");
            }

            var key  = title.titleKey;
            var name = title.name;
            if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(name))
            {
                return;
            }

            var result = MessageBoxResult.Cancel;
            var str    = $"Download {contentType} content to the following location?\n\"{outputDir}\"";
            Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal,
                                                  new Action(() => { result = MessageBox.Show(Application.Current.MainWindow, str, name, MessageBoxButton.YesNo); }));
            if (result != MessageBoxResult.Yes)
            {
                return;
            }

            if (!Directory.Exists(outputDir))
            {
                Directory.CreateDirectory(outputDir);
            }

            Toolbelt.AppendLog($"Output Directory '{outputDir}'");

            #endregion

            #region TMD

            Toolbelt.AppendLog("  - Loading TMD...");
            TMD tmd = null;

            var nusUrls = new List <string>
            {
                "http://ccs.cdn.wup.shop.nintendo.net/ccs/download/",
                "http://nus.cdn.shop.wii.com/ccs/download/",
                "http://ccs.cdn.c.shop.nintendowifi.net/ccs/download/"
            };

            foreach (var nusUrl in nusUrls)
            {
                var titleUrl = $"{nusUrl}{workingId}/";
                tmd = LoadTmd(workingId, key, outputDir, titleUrl, version);

                if (tmd != null)
                {
                    break;
                }
            }

            if (tmd == null)
            {
                TextLog.MesgLog.WriteError("Could not locate TMD. Is this content request valid?");
                return;
            }

            #endregion

            #region Ticket

            Toolbelt.AppendLog("Generating Ticket...");

            var tikData = MapleTicket.Create(Database.FindTitleKey(workingId));
            if (tikData == null)
            {
                throw new Exception("Invalid ticket data. Verify Title ID.");
            }

            var ticket = Ticket.Load(tikData);
            ticket.Save(Path.Combine(outputDir, "cetk"));

            #endregion

            #region Content

            Toolbelt.AppendLog($"[+] [{contentType}] {name} v{tmd.TitleVersion}");
            Toolbelt.SetStatus($"Output Directory: {outputDir}");

            foreach (var nusUrl in nusUrls)
            {
                var url = nusUrl + workingId;
                if (DownloadContent(tmd, outputDir, url) != 1)
                {
                    continue;
                }

                Toolbelt.AppendLog(string.Empty);
                Toolbelt.AppendLog("  - Decrypting Content");
                Toolbelt.AppendLog("  + This may take a minute. Please wait...");
                Toolbelt.SetStatus("Decrypting Content. This may take a minute. Please wait...", Color.OrangeRed);

                if (Toolbelt.CDecrypt(outputDir) != 0)
                {
                    CleanUp(outputDir, tmd);
                    Toolbelt.AppendLog($"Error while decrypting {name}");
                    return;
                }

                CleanUp(outputDir, tmd);
                break;
            }

            #endregion

            Web.ResetDownloadProgressChanged();
            Toolbelt.AppendLog($"[+] [{contentType}] {name} v{tmd.TitleVersion} Finished.");
            Toolbelt.SetStatus($"[+] [{contentType}] {name} v{tmd.TitleVersion} Finished.");
        }
예제 #3
0
        /// <summary>
        /// Grabs a title from NUS, you can define several store types.
        /// Leave the title version empty for the latest.
        /// </summary>
        /// <param name="titleId"></param>
        /// <param name="titleVersion"></param>
        /// <param name="outputDir"></param>
        /// <param name="storeTypes"></param>
        public void DownloadTitle(string titleId, string titleVersion, string outputDir, StoreType[] storeTypes)
        {
            FireDebug("Downloading Title {0} v{1}...", titleId, (string.IsNullOrEmpty(titleVersion)) ? "[Latest]" : titleVersion);

            if (storeTypes.Length < 1)
            {
                FireDebug("  No store types were defined..."); throw new Exception("You must at least define one store type!");
            }

            var titleInfo = Database.GetTitle(titleId);

            string titleUrl  = $"{nusUrl}{titleId}/";
            string titleUrl2 = $"{nusUrl2}{titleId}/";

            bool storeEncrypted = false;
            bool storeDecrypted = false;

            FireProgress(0);

            foreach (StoreType st in storeTypes)
            {
                switch (st)
                {
                case StoreType.DecryptedContent:
                    FireDebug("    [=] Storing Decrypted Content...");
                    storeDecrypted = true;
                    break;

                case StoreType.EncryptedContent:
                    FireDebug("    [=] Storing Encrypted Content...");
                    storeEncrypted = true;
                    break;

                case StoreType.All:
                    FireDebug("    [=] Storing Decrypted Content...");
                    FireDebug("    [=] Storing Encrypted Content...");
                    FireDebug("    [=] Storing WAD...");
                    storeDecrypted = true;
                    storeEncrypted = true;
                    break;

                case StoreType.Empty:
                    break;
                }
            }

            FireDebug("  - Checking for Internet connection...");
            if (!CheckInet())
            {
                FireDebug("   + Connection not found...");
                throw new Exception("You're not connected to the internet!");
            }

            if (!Directory.Exists(outputDir))
            {
                Directory.CreateDirectory(outputDir);
            }
            if (!Directory.Exists(Path.Combine(outputDir, titleInfo.Name)))
            {
                Directory.CreateDirectory(Path.Combine(outputDir, titleInfo.Name));
            }
            outputDir = Path.Combine(outputDir, titleInfo.Name);

            string tmdFile = "tmd" + (string.IsNullOrEmpty(titleVersion) ? string.Empty : string.Format(".{0}", titleVersion));

            //Download TMD
            FireDebug("  - Downloading TMD...");
            TMD tmd;

            byte[] tmdFileWithCerts;
            try
            {
                tmdFileWithCerts = wcNus.DownloadData(titleUrl + tmdFile);
                tmd = TMD.Load(tmdFileWithCerts);
            }
            catch (Exception ex) { FireDebug("   + Downloading TMD Failed..."); throw new Exception("Downloading TMD Failed:\n" + ex.Message); }

            //Parse TMD
            FireDebug("  - Parsing TMD...");

            if (string.IsNullOrEmpty(titleVersion))
            {
                FireDebug("    + Title Version: {0}", tmd.TitleVersion);
            }
            FireDebug("    + {0} Contents", tmd.NumOfContents);

            if (!Directory.Exists(Path.Combine(outputDir, tmd.TitleVersion.ToString())))
            {
                Directory.CreateDirectory(Path.Combine(outputDir, tmd.TitleVersion.ToString()));
            }
            outputDir = Path.Combine(outputDir, tmd.TitleVersion.ToString());

            titleversion = tmd.TitleVersion;

            File.WriteAllBytes(Path.Combine(outputDir, tmdFile), tmdFileWithCerts);

            FireProgress(5);

            //Download cetk
            FireDebug("  - Downloading Ticket...");
            try
            {
                wcNus.DownloadFile(Path.Combine(titleUrl, "cetk"), Path.Combine(outputDir, "cetk"));
            }
            catch (Exception ex)
            {
                try
                {
                    if (titleInfo.Ticket == "1")
                    {
                        var cetkUrl = $"{WII_TIK_URL}{titleId.ToLower()}.tik";
                        wcNus.DownloadFile(cetkUrl, Path.Combine(outputDir, "cetk"));
                    }
                }
                catch
                {
                    continueWithoutTicket = false;
                    if (!continueWithoutTicket || !storeEncrypted)
                    {
                        FireDebug("   + Downloading Ticket Failed...");
                        throw new Exception("Downloading Ticket Failed:\n" + ex.Message);
                    }

                    if (!(File.Exists(Path.Combine(outputDir, "cetk"))))
                    {
                        storeDecrypted = false;
                    }
                }
            }

            FireProgress(10);

            // Parse Ticket
            Ticket tik = new Ticket();

            if (File.Exists(Path.Combine(outputDir, "cetk")))
            {
                FireDebug("   + Parsing Ticket...");
                tik = Ticket.Load(Path.Combine(outputDir, "cetk"));

                // DSi ticket? Must make sure to use DSi Key :D
                if (nusUrl == DSI_NUS_URL)
                {
                    tik.DSiTicket = true;
                }
            }
            else
            {
                FireDebug("   + Ticket Unavailable...");
            }

            string[] encryptedContents = new string[tmd.NumOfContents];

            //Download Content
            for (int i = 0; i < tmd.NumOfContents; i++)
            {
                Form1.token.ThrowIfCancellationRequested();

                var size = Toolbelt.SizeSuffix(tmd.Contents[i].Size);
                FireDebug("  - Downloading Content #{0} of {1}... ({2} bytes)", i + 1, tmd.NumOfContents, size);
                FireProgress(((i + 1) * 60 / tmd.NumOfContents) + 10);

                var contentPath = Path.Combine(outputDir, tmd.Contents[i].ContentID.ToString("x8"));
                if (useLocalFiles && Toolbelt.IsValid(tmd.Contents[i], contentPath))
                {
                    FireDebug("   + Using Local File, Skipping..."); continue;
                }

                try
                {
                    var downloadUrl = titleUrl + tmd.Contents[i].ContentID.ToString("x8");
                    var outputdir   = Path.Combine(outputDir, tmd.Contents[i].ContentID.ToString("x8"));
                    wcNus.DownloadFile(downloadUrl, outputdir);

                    encryptedContents[i] = tmd.Contents[i].ContentID.ToString("x8");
                }
                catch (Exception ex)
                {
                    FireDebug("  - Downloading Content #{0} of {1} failed...", i + 1, tmd.NumOfContents);
                    throw new Exception("Downloading Content Failed:\n" + ex.Message);
                }
            }

            //Decrypt Content
            if (storeDecrypted)
            {
                FireDebug("  - Decrypting Content...");
                Toolbelt.CDecrypt(this, outputDir);
            }

            //Delete not wanted files
            if (!storeEncrypted)
            {
                FireDebug("  - Deleting Encrypted Contents...");
                for (int i = 0; i < tmd.Contents.Length; i++)
                {
                    if (File.Exists(Path.Combine(outputDir, tmd.Contents[i].ContentID.ToString("x8"))))
                    {
                        File.Delete(Path.Combine(outputDir, tmd.Contents[i].ContentID.ToString("x8")));
                    }
                }
            }

            if (!storeDecrypted && !storeEncrypted)
            {
                FireDebug("  - Deleting TMD and Ticket...");
                File.Delete(Path.Combine(outputDir, tmdFile));
                File.Delete(Path.Combine(outputDir, "cetk"));
            }

            FireDebug("Downloading Title {0} v{1} Finished...", titleId, tmd.TitleVersion /*(string.IsNullOrEmpty(titleVersion)) ? "[Latest]" : titleVersion*/);
            FireProgress(100);
        }