/////////////////////////////////////////// // NUS Downloader: Form1.cs // // $Rev:: $ // // $Author:: $ // // $Date:: $ // /////////////////////////////////////////// /////////////////////////////////////// // Copyright (C) 2010 // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see /////////////////////////////////////// using System; using System.Windows.Forms; using System.IO; using System.Net; using System.Security.Cryptography; using System.Xml; using System.Drawing; using System.Text.RegularExpressions; using System.ComponentModel; using System.Threading; using System.Text; using System.Diagnostics; namespace NUS_Downloader { partial class Form1 : Form { private readonly string CURRENT_DIR = Directory.GetCurrentDirectory(); #if DEBUG private static string svnversion = "$Rev$"; private static string version = String.Format("SVN r{0}", ((int.Parse(svnversion.Replace("$"+"R"+"e"+"v"+": ","").Replace(" "+"$","")))+1)); #else // TODO: Always remember to change version! private string version = "v2.0"; #endif private static bool dsidecrypt = false; // Cross-thread Windows Formsing private delegate void AddToolStripItemToStripCallback( ToolStripMenuItem menulist, ToolStripMenuItem[] additionitems); private delegate void WriteStatusCallback(string Update, Color writecolor); private delegate void BootChecksCallback(); private delegate void SetEnableForDownloadCallback(bool enabled); private delegate void SetPropertyThreadSafeCallback(System.ComponentModel.Component what, object setto, string property); private delegate string OfficialWADNamingCallback(string whut); private string WAD_Saveas_Filename; // TODO: OOP scripting /*private string script_filename; private bool script_mode = false; private string[] nusentries;*/ // Proxy stuff... private string proxy_url; private string proxy_usr; private string proxy_pwd; // Database thread private BackgroundWorker fds; // Scripts Thread private BackgroundWorker scriptsWorker; // Colours for status box private System.Drawing.Color normalcolor = Color.FromName("Black"); private System.Drawing.Color warningcolor = Color.FromName("DarkGoldenrod"); private System.Drawing.Color errorcolor = Color.FromName("Crimson"); private System.Drawing.Color infocolor = Color.FromName("RoyalBlue"); // This is the standard entry to the GUI public Form1() { InitializeComponent(); GUISetup(); BootChecks(); } // CLI Mode public Form1(string[] args) { InitializeComponent(); //Application.DoEvents(); Debug.WriteLine("CLI Parameters passed"); GUISetup(); if ((args.Length == 1) && (File.Exists(args[0]))) { BootChecks(); string script_content = File.ReadAllText(args[0]); FileInfo script_file = new FileInfo(args[0]); script_content += String.Format(";{0}", script_file.Name.Replace("." + script_file.Extension, "")); BackgroundWorker scripter = new BackgroundWorker(); scripter.DoWork += new DoWorkEventHandler(RunScriptBg); scripter.RunWorkerAsync(script_content); } else if (args.Length >= 2) { RunCommandMode(args); Environment.Exit(0); //this.Close(); } else { BootChecks(); } /* Fix proxy entry. if (!(String.IsNullOrEmpty(proxy_url))) while (String.IsNullOrEmpty(proxy_pwd)) Thread.Sleep(1000); if ((args.Length == 1) && (args[0] == "folderfix")) { // Organizing folders from past NUSD releases... BackgroundWorker folder_fixer = new BackgroundWorker(); folder_fixer.DoWork += new DoWorkEventHandler(ReorganizePreviousFolderStructure); folder_fixer.RunWorkerCompleted += new RunWorkerCompletedEventHandler(ReorganizePreviousFolderStructure_Completed); Debug.WriteLine("folderfix active"); WriteStatus("Organizing your old folder structure..."); folder_fixer.RunWorkerAsync(); }*/ } private void RunCommandMode(string[] args) { // CLI mode, inspired and taken from wiiNinja's mod. // Initialize the checkboxes and radio boxes packbox.Checked = false; // Create wad - default OFF localuse.Checked = true; // Use local content if already downloaded - default ON decryptbox.Checked = false; keepenccontents.Checked = false; consoleCBox.SelectedIndex = 0; // 0 is Wii, 1 is DS // Clear 3 items in ios patches list. This feature is not supported in the command line version at this time. iosPatchCheckbox.Checked = false; iosPatchesListBox.SetItemChecked(0, false); iosPatchesListBox.SetItemChecked(1, false); iosPatchesListBox.SetItemChecked(2, false); Console.WriteLine("NUS Downloader - v{0}", version); if (args.Length < 2) { Console.WriteLine("Usage:"); Console.WriteLine(" nusd [optionalArgs]"); Console.WriteLine("\nWhere:"); Console.WriteLine(" titleID = The ID of the title to be downloaded"); Console.WriteLine(" titleVersion = The version of the title to be downloaded"); Console.WriteLine(" Use \"*\" (no quotes) to get the latest version"); Console.WriteLine(" OptionalArgs:"); Console.WriteLine(" packwad = A wad file will be generated"); Console.WriteLine(" localuse = Use local contents if available"); Console.WriteLine(" decrypt = Create decrypted contents"); Console.WriteLine(" keepencrypt = Keep encrypted contents"); } else { for (int i = 0; i < args.Length; i++) { Console.WriteLine("{0}", args[i]); switch (i) { case 0: // First command line argument is ALWAYS the TitleID titleidbox.Text = args[i]; break; case 1: // Second command line argument is ALWAYS the TitleVersion. // User may specify a "*" to retrieve the latest version if (args[i] == "*") titleversion.Text = ""; else titleversion.Text = args[i]; break; default: // Any other arguments beyond the 2nd one are considered optional if (args[i] == "packwad") packbox.Checked = true; else if (args[i] == "localuse") localuse.Checked = true; else if (args[i] == "decrypt") decryptbox.Checked = true; else if (args[i] == "keepencrypt") keepenccontents.Checked = true; else Console.WriteLine("\n>>>> Warning: Unrecognized command line argument: {0}. This option is ignored...", args[i]); break; } } // Do this to set the wad file name UpdatePackedName(); // Call to get the files from server NUSDownloader_DoWork(null, null); Console.WriteLine("\nSuccessfully downloaded the title {0} version {1}", args[0], args[1]); } } private void GUISetup() { this.Font = new System.Drawing.Font("Tahoma", 8); this.MaximumSize = this.MinimumSize = this.Size; // Lock size down PATCHOW :D if (Type.GetType("Mono.Runtime") != null) { saveaswadbtn.Text = "Save As"; clearButton.Text = "Clear"; keepenccontents.Text = "Keep Enc. Contents"; clearButton.Left -= 41; } else statusbox.Font = new System.Drawing.Font("Microsoft Sans Serif", 7); statusbox.SelectionColor = statusbox.ForeColor = normalcolor; if (version.StartsWith("SVN")) { WriteStatus("!!!!! THIS IS A DEBUG BUILD FROM SVN !!!!!"); WriteStatus("Features CAN and WILL be broken in this build!"); WriteStatus("Devs: REMEMBER TO CHANGE TO THE RELEASE CONFIGURATION AND CHANGE VERSION NUMBER BEFORE BUILDING!"); WriteStatus("\r\n"); } // Database BGLoader this.fds = new BackgroundWorker(); this.fds.DoWork += new DoWorkEventHandler(DoAllDatabaseyStuff); this.fds.RunWorkerCompleted += new RunWorkerCompletedEventHandler(DoAllDatabaseyStuff_Completed); this.fds.ProgressChanged += new ProgressChangedEventHandler(DoAllDatabaseyStuff_ProgressChanged); this.fds.WorkerReportsProgress = true; // Scripts BGLoader this.scriptsWorker = new BackgroundWorker(); this.scriptsWorker.DoWork += new DoWorkEventHandler(OrganizeScripts); this.scriptsWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(scriptsWorker_RunWorkerCompleted); } private void Form1_Load(object sender, EventArgs e) { this.Text = String.Format("NUSD - {0}", version); ; this.Size = this.MinimumSize; consoleCBox.SelectedIndex = 0; } private bool NUSDFileExists(string filename) { return File.Exists(Path.Combine(CURRENT_DIR, filename)); } /// /// Checks certain file existances, etc. /// /// private void BootChecks() { //Check if correct thread... if (this.InvokeRequired) { Debug.WriteLine("InvokeRequired..."); BootChecksCallback bcc = new BootChecksCallback(BootChecks); this.Invoke(bcc); return; } // Check for DSi common key bin file... if (NUSDFileExists("dsikey.bin") == true) { WriteStatus("DSi Common Key detected."); dsidecrypt = true; } // Check for database.xml if (NUSDFileExists("database.xml") == false) { WriteStatus("Database.xml not found. Title database not usable!"); /*databaseButton.Click -= new System.EventHandler(this.button4_Click); databaseButton.Click += new System.EventHandler(this.updateDatabaseToolStripMenuItem_Click); databaseButton.Text = "Download DB"; */ DatabaseEnabled(false); updateDatabaseToolStripMenuItem.Enabled = true; updateDatabaseToolStripMenuItem.Visible = true; updateDatabaseToolStripMenuItem.Text = "Download Database"; } else { Database db = new Database(); db.LoadDatabaseToStream(Path.Combine(CURRENT_DIR, "database.xml")); string version = db.GetDatabaseVersion(); WriteStatus("Database.xml detected."); WriteStatus(" - Version: " + version); updateDatabaseToolStripMenuItem.Text = "Update Database"; //databaseButton.Enabled = false; //databaseButton.Text = "DB Loading"; databaseButton.Text = " [ ]"; databaseButton.Image = Properties.Resources.arrow_ticker; // Load it up... this.fds.RunWorkerAsync(); } // Load scripts (local) RunScriptOrganizer(); // Check for Proxy Settings file... if (NUSDFileExists("proxy.txt") == true) { WriteStatus("Proxy settings detected."); string[] proxy_file = File.ReadAllLines(Path.Combine(CURRENT_DIR, "proxy.txt")); proxy_url = proxy_file[0]; // If proxy\nuser\npassword if (proxy_file.Length > 2) { proxy_usr = proxy_file[1]; proxy_pwd = proxy_file[2]; } else if (proxy_file.Length > 1) { proxy_usr = proxy_file[1]; SetAllEnabled(false); ProxyVerifyBox.Visible = true; ProxyVerifyBox.Enabled = true; ProxyPwdBox.Enabled = true; SaveProxyBtn.Enabled = true; ProxyVerifyBox.Select(); } } } private void DoAllDatabaseyStuff(object sender, System.ComponentModel.DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; ClearDatabaseStrip(); FillDatabaseStrip(worker); LoadRegionCodes(); FillDatabaseScripts(); ShowInnerToolTips(false); } private void DoAllDatabaseyStuff_Completed(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e) { //this.databaseButton.Enabled = true; this.databaseButton.Text = "Database..."; this.databaseButton.Image = null; /* if (this.KoreaMassUpdate.HasDropDownItems || this.PALMassUpdate.HasDropDownItems || this.NTSCMassUpdate.HasDropDownItems) { this.scriptsbutton.Enabled = true; }*/ } private void DoAllDatabaseyStuff_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e) { if (e.ProgressPercentage == 25) databaseButton.Text = " [. ]"; else if (e.ProgressPercentage == 50) databaseButton.Text = " [.. ]"; else if (e.ProgressPercentage == 75) databaseButton.Text = " [... ]"; else if (e.ProgressPercentage == 100) databaseButton.Text = " [....]"; } private void RunScriptOrganizer() { this.scriptsWorker.RunWorkerAsync(); } private void SetAllEnabled(bool enabled) { for (int a = 0; a < this.Controls.Count; a++) { try { this.Controls[a].Enabled = enabled; } catch { // ... } } } /* /// /// Gets the database version. /// /// The database file. /// private string GetDatabaseVersion(string file) { // Read version of Database.xml XmlDocument xDoc = new XmlDocument(); if (file.Contains("<")) xDoc.LoadXml(file); else { if (File.Exists(file)) { xDoc.Load(file); } else { return "None Found"; } } XmlNodeList DatabaseList = xDoc.GetElementsByTagName("database"); XmlAttributeCollection Attributes = DatabaseList[0].Attributes; return Attributes[0].Value; }*/ private void extrasMenuButton_Click(object sender, EventArgs e) { // Show extras menu extrasStrip.Text = "Showing"; extrasStrip.Show(Extrasbtn, 2, (2+Extrasbtn.Height)); { System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer(); timer.Interval = 52; timer.Tick += new EventHandler(contextmenusTimer_Tick); timer.Start(); } } /// /// Loads the title info from TMD. /// private void LoadTitleFromTMD() { // Show dialog for opening TMD file... OpenFileDialog opentmd = new OpenFileDialog(); opentmd.Filter = "TMD Files|*tmd*"; opentmd.Title = "Open TMD"; if (opentmd.ShowDialog() != DialogResult.Cancel) { libWiiSharp.TMD tmdLocal = new libWiiSharp.TMD(); tmdLocal.LoadFile(opentmd.FileName); WriteStatus(String.Format("TMD Loaded ({0} blocks)", tmdLocal.GetNandBlocks())); titleidbox.Text = tmdLocal.TitleID.ToString("X16"); WriteStatus("Title ID: " + tmdLocal.TitleID.ToString("X16")); titleversion.Text = tmdLocal.TitleVersion.ToString(); WriteStatus("Version: " + tmdLocal.TitleVersion); if (tmdLocal.StartupIOS.ToString("X") != "0") WriteStatus("Requires: IOS" + int.Parse(tmdLocal.StartupIOS.ToString("X").Substring(7, 2).ToString(), System.Globalization.NumberStyles.HexNumber)); WriteStatus("Content Count: " + tmdLocal.NumOfContents); for (int a = 0; a < tmdLocal.Contents.Length; a++) { WriteStatus(String.Format(" Content {0}: {1} ({2} bytes)", a, tmdLocal.Contents[a].ContentID.ToString("X8"), tmdLocal.Contents[a].Size.ToString())); WriteStatus(String.Format(" - Index: {0}", tmdLocal.Contents[a].Index.ToString())); WriteStatus(String.Format(" - Type: {0}", tmdLocal.Contents[a].Type.ToString())); WriteStatus(String.Format(" - Hash: {0}...", DisplayBytes(tmdLocal.Contents[a].Hash, String.Empty).Substring(0, 8))); } WriteStatus("TMD information parsed!"); } } /// /// Writes the status to the statusbox. /// /// The update. /// The color to use for writing text into the text box. public void WriteStatus(string Update, Color writecolor) { // Check if thread-safe if (statusbox.InvokeRequired) { Debug.WriteLine("InvokeRequired..."); WriteStatusCallback wsc = new WriteStatusCallback(WriteStatus); this.Invoke(wsc, new object[] { Update, writecolor }); return; } // Small function for writing text to the statusbox... int startlen = statusbox.TextLength; if (statusbox.Text == "") statusbox.Text = Update; else statusbox.AppendText("\r\n" + Update); int endlen = statusbox.TextLength; // Set the color statusbox.Select(startlen, endlen - startlen); statusbox.SelectionColor = writecolor; // Scroll to end of text box. statusbox.SelectionStart = statusbox.TextLength; statusbox.SelectionLength = 0; statusbox.ScrollToCaret(); // Also write to console Console.WriteLine(Update); } /// /// Writes the status to the statusbox. /// /// The update. public void WriteStatus(string Update) { WriteStatus(Update, normalcolor); } /// /// Reads the type of the Title ID. /// /// The TitleID. private void ReadIDType(string ttlid) { /* Wiibrew TitleID Info... # 3 00000001: Essential system titles # 4 00010000 and 00010004 : Disc-based games # 5 00010001: Downloaded channels * 5.1 000010001-Cxxx : Commodore 64 Games * 5.2 000010001-Exxx : NeoGeo Games * 5.3 000010001-Fxxx : NES Games * 5.4 000010001-Hxxx : Channels * 5.5 000010001-Jxxx : SNES Games * 5.6 000010001-Nxxx : Nintendo 64 Games * 5.7 000010001-Wxxx : WiiWare # 6 00010002: System channels # 7 00010004: Game channels and games that use them # 8 00010005: Downloaded Game Content # 9 00010008: "Hidden" channels */ if (ttlid.Substring(0, 8) == "00000001") WriteStatus("ID Type: System Title. BE CAREFUL!", warningcolor); else if ((ttlid.Substring(0, 8) == "00010000") || (ttlid.Substring(0, 8) == "00010004")) WriteStatus("ID Type: Disc-Based Game. Unlikely NUS Content!"); else if (ttlid.Substring(0, 8) == "00010001") WriteStatus("ID Type: Downloaded Channel. Possible NUS Content."); else if (ttlid.Substring(0, 8) == "00010002") WriteStatus("ID Type: System Channel. BE CAREFUL!", warningcolor); else if (ttlid.Substring(0, 8) == "00010004") WriteStatus("ID Type: Game Channel. Unlikely NUS Content!"); else if (ttlid.Substring(0, 8) == "00010005") WriteStatus("ID Type: Downloaded Game Content. Unlikely NUS Content!"); else if (ttlid.Substring(0, 8) == "00010008") WriteStatus("ID Type: 'Hidden' Channel. Unlikely NUS Content!"); else WriteStatus("ID Type: Unknown. Unlikely NUS Content!"); } private void DownloadBtn_Click(object sender, EventArgs e) { if (titleidbox.Text == String.Empty) { // Prevent mass deletion and fail WriteStatus("Please enter a Title ID!", errorcolor); return; } else if (!(packbox.Checked) && !(decryptbox.Checked) && !(keepenccontents.Checked)) { // Prevent pointless running by n00bs. WriteStatus("Running with your current settings will produce no output!", errorcolor); WriteStatus(" - To amend this, look below and check an output type.", errorcolor); return; }/* else if (!(script_mode)) { try { if (!statusbox.Lines[0].StartsWith(" ---")) SetTextThreadSafe(statusbox, " --- " + titleidbox.Text + " ---"); } catch // No lines present... { SetTextThreadSafe(statusbox, " --- " + titleidbox.Text + " ---"); } }*/ else WriteStatus(" --- " + titleidbox.Text + " ---"); // Running Downloads in background so no form freezing NUSDownloader.RunWorkerAsync(); } private void SetTextThreadSafe(System.Windows.Forms.Control what, string setto) { SetPropertyThreadSafe(what, "Name", setto); } private void SetPropertyThreadSafe(System.ComponentModel.Component what, object setto, string property) { if (this.InvokeRequired) { SetPropertyThreadSafeCallback sptscb = new SetPropertyThreadSafeCallback(SetPropertyThreadSafe); try { this.Invoke(sptscb, new object[] { what, setto, property }); } catch (Exception) { // FFFFF! } return; } what.GetType().GetProperty(property).SetValue(what, setto, null); //what.Text = setto; } private void NUSDownloader_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) { Control.CheckForIllegalCrossThreadCalls = false; // this function would need major rewriting to get rid of this... WriteStatus("Starting NUS Download. Please be patient!", infocolor); SetEnableforDownload(false); downloadstartbtn.Text = "Starting NUS Download!"; // WebClient configuration WebClient nusWC = new WebClient(); nusWC = ConfigureWithProxy(nusWC); nusWC.Headers.Add("User-Agent", "wii libnup/1.0"); // Set UserAgent to Wii value // Create\Configure NusClient libWiiSharp.NusClient nusClient = new libWiiSharp.NusClient(); nusClient.ConfigureNusClient(nusWC); nusClient.UseLocalFiles = localuse.Checked; nusClient.ContinueWithoutTicket = true; // Server if (consoleCBox.SelectedIndex == 0) nusClient.SetToWiiServer(); else if (consoleCBox.SelectedIndex == 1) nusClient.SetToDSiServer(); // Events nusClient.Debug += new EventHandler(nusClient_Debug); nusClient.Progress += new EventHandler(nusClient_Progress); libWiiSharp.StoreType[] storeTypes = new libWiiSharp.StoreType[3]; if (packbox.Checked) storeTypes[0] = libWiiSharp.StoreType.WAD; else storeTypes[0] = libWiiSharp.StoreType.Empty; if (decryptbox.Checked) storeTypes[1] = libWiiSharp.StoreType.DecryptedContent; else storeTypes[1] = libWiiSharp.StoreType.Empty; if (keepenccontents.Checked) storeTypes[2] = libWiiSharp.StoreType.EncryptedContent; else storeTypes[2] = libWiiSharp.StoreType.Empty; string wadName; if (String.IsNullOrEmpty(WAD_Saveas_Filename)) wadName = wadnamebox.Text; else wadName = WAD_Saveas_Filename; try { nusClient.DownloadTitle(titleidbox.Text, titleversion.Text, Path.Combine(CURRENT_DIR, "titles"), wadName, storeTypes); } catch (Exception ex) { WriteStatus("Download failed: \"" + ex.Message + " ):\"", errorcolor); } if (iosPatchCheckbox.Checked == true) { // Apply patches then... bool didpatch = false; int noofpatches = 0; string appendpatch = ""; // Okay, it's checked. libWiiSharp.IosPatcher iosp = new libWiiSharp.IosPatcher(); libWiiSharp.WAD ioswad = new libWiiSharp.WAD(); wadName = wadName.Replace("[v]", nusClient.TitleVersion.ToString()); if (wadName.Contains(Path.DirectorySeparatorChar.ToString()) || wadName.Contains(Path.AltDirectorySeparatorChar.ToString())) ioswad.LoadFile(wadName); else ioswad.LoadFile(Path.Combine(Path.Combine(Path.Combine(Path.Combine(CURRENT_DIR, "titles"), titleidbox.Text), nusClient.TitleVersion.ToString()), wadName)); try { iosp.LoadIOS(ref ioswad); } catch (Exception) { WriteStatus("NUS Download Finished.", infocolor); return; } foreach (object checkItem in iosPatchesListBox.CheckedItems) { // ensure not 'indeterminate' if (iosPatchesListBox.GetItemCheckState(iosPatchesListBox.Items.IndexOf(checkItem)).ToString() == "Checked") { switch (checkItem.ToString()) { case "Trucha bug": noofpatches = iosp.PatchFakeSigning(); if (noofpatches > 0) { WriteStatus(" - Patched in fake-signing:", infocolor); if (noofpatches > 1) appendpatch = "es"; else appendpatch = ""; WriteStatus(String.Format(" {0} patch{1} applied.", noofpatches, appendpatch)); didpatch = true; } else WriteStatus(" - Could not patch fake-signing", errorcolor); break; case "ES_Identify": noofpatches = iosp.PatchEsIdentify(); if (noofpatches > 0) { WriteStatus(" - Patched in ES_Identify:", infocolor); if (noofpatches > 1) appendpatch = "es"; else appendpatch = ""; WriteStatus(String.Format(" {0} patch{1} applied.", noofpatches, appendpatch)); didpatch = true; } else WriteStatus(" - Could not patch ES_Identify", errorcolor); break; case "NAND permissions": noofpatches = iosp.PatchNandPermissions(); if (noofpatches > 0) { WriteStatus(" - Patched in NAND permissions:", infocolor); if (noofpatches > 1) appendpatch = "es"; else appendpatch = ""; WriteStatus(String.Format(" {0} patch{1} applied.", noofpatches, appendpatch)); didpatch = true; } else WriteStatus(" - Could not patch NAND permissions", errorcolor); break; } } else { // WriteStatus(iosPatchesListBox.GetItemCheckState(iosPatchesListBox.Items.IndexOf(checkItem)).ToString()); } } if (didpatch) { wadName = wadName.Replace(".wad",".patched.wad"); try { if (wadName.Contains(Path.DirectorySeparatorChar.ToString()) || wadName.Contains(Path.AltDirectorySeparatorChar.ToString())) ioswad.Save(wadName); else ioswad.Save(Path.Combine(Path.Combine(Path.Combine(Path.Combine(CURRENT_DIR, "titles"), titleidbox.Text), nusClient.TitleVersion.ToString()), wadName)); WriteStatus(String.Format("Patched WAD saved as: {0}", Path.GetFileName(wadName)), infocolor); } catch (Exception ex) { WriteStatus(String.Format("Couldn't save patched WAD: \"{0}\" :(",ex.Message), errorcolor); } } } WriteStatus("NUS Download Finished."); } void nusClient_Progress(object sender, ProgressChangedEventArgs e) { dlprogress.Value = e.ProgressPercentage; } void nusClient_Debug(object sender, libWiiSharp.MessageEventArgs e) { WriteStatus(e.Message); } private void NUSDownloader_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { WAD_Saveas_Filename = String.Empty; SetEnableforDownload(true); downloadstartbtn.Text = "Start NUS Download!"; dlprogress.Value = 0; if (IsWin7()) dlprogress.ShowInTaskbar = false; } private void consoleCBox_SelectedIndexChanged(object sender, EventArgs e) { if (consoleCBox.SelectedIndex == 0) { // Can pack WADs / Decrypt packbox.Enabled = true; decryptbox.Enabled = true; } if (consoleCBox.SelectedIndex == 1) { // Cannot Pack WADs packbox.Checked = false; packbox.Enabled = false; // Can decrypt if dsikey exists... if (dsidecrypt == false) { decryptbox.Checked = false; decryptbox.Enabled = false; } wadnamebox.Enabled = false; wadnamebox.Text = ""; } } private void packbox_CheckedChanged(object sender, EventArgs e) { if (packbox.Checked == true) { wadnamebox.Enabled = true; saveaswadbtn.Enabled = true; // Change WAD name if applicable UpdatePackedName(); } else { wadnamebox.Enabled = false; saveaswadbtn.Enabled = false; wadnamebox.Text = String.Empty; if (iosPatchCheckbox.Checked) iosPatchCheckbox.Checked = false; } } private void titleidbox_TextChanged(object sender, EventArgs e) { UpdatePackedName(); EnablePatchIOSBox(); } private void titleversion_TextChanged(object sender, EventArgs e) { UpdatePackedName(); } private void EnablePatchIOSBox() { iosPatchCheckbox.Enabled = TitleIsIOS(titleidbox.Text); if (iosPatchCheckbox.Enabled == false) iosPatchCheckbox.Checked = false; } private bool TitleIsIOS(string titleid) { if (titleid.Length != 16) return false; if ((titleid == "0000000100000001") || (titleid == "0000000100000002")) return false; if (titleid.Substring(0, 14) == "00000001000000") return true; return false; } /// /// Displays the bytes. /// /// The bytes. /// What separates the bytes /// public string DisplayBytes(byte[] bytes, string spacer) { string output = ""; for (int i = 0; i < bytes.Length; ++i) { output += bytes[i].ToString("X2") + spacer; } return output; } private void DatabaseButton_Click(object sender, EventArgs e) { // Open Database button menu... databaseStrip.Text = "Showing"; databaseStrip.Show(databaseButton, 2, (2+databaseButton.Height)); //if (!e.Equals(EventArgs.Empty)) { System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer(); timer.Interval = 50; timer.Tick += new EventHandler(contextmenusTimer_Tick); timer.Start(); } } void contextmenusTimer_Tick(object sender, EventArgs e) { if (SystemMenuList.Pressed || IOSMenuList.Pressed || VCMenuList.Pressed || WiiWareMenuList.Pressed || RegionCodesList.Pressed || scriptsLocalMenuEntry.Pressed || scriptsDatabaseToolStripMenuItem.Pressed || emulateUpdate.Pressed) return; if (databaseButton.ClientRectangle.Contains(databaseButton.PointToClient(MousePosition)) && ((System.Windows.Forms.Timer)sender).Interval != 50) { databaseStrip.Close(); scriptsStrip.Close(); extrasStrip.Close(); DatabaseButton_Click(sender, EventArgs.Empty); ((System.Windows.Forms.Timer)sender).Stop(); } if (scriptsbutton.ClientRectangle.Contains(scriptsbutton.PointToClient(MousePosition)) && ((System.Windows.Forms.Timer)sender).Interval != 51) { databaseStrip.Close(); scriptsStrip.Close(); extrasStrip.Close(); scriptsbutton_Click(sender, EventArgs.Empty); ((System.Windows.Forms.Timer)sender).Stop(); } if (Extrasbtn.ClientRectangle.Contains(Extrasbtn.PointToClient(MousePosition)) && ((System.Windows.Forms.Timer)sender).Interval != 52) { databaseStrip.Close(); scriptsStrip.Close(); extrasStrip.Close(); extrasMenuButton_Click(sender, EventArgs.Empty); ((System.Windows.Forms.Timer)sender).Stop(); } //Debug.Write(((databaseStrip.Text == "Hidden").ToString() + (extrasStrip.Text == "Hidden").ToString() + (scriptsStrip.Text == "Hidden").ToString())); if ((databaseStrip.Visible == false) && (extrasStrip.Visible == false) && (scriptsStrip.Visible == false)) ((System.Windows.Forms.Timer)sender).Stop(); } /// /// Clears the database strip. /// private void ClearDatabaseStrip() { object[] thingstoclear = new object[] { SystemMenuList, IOSMenuList, WiiWareMenuList, VCMenuList, // Now Virtual Console C64MenuList, NeoGeoMenuList, NESMenuList, SNESMenuList, N64MenuList, TurboGrafx16MenuList, TurboGrafxCDMenuList, MSXMenuList, SegaMSMenuList, GenesisMenuList, VCArcadeMenuList }; foreach (System.Windows.Forms.ToolStripMenuItem tsmiclear in thingstoclear) { if (tsmiclear.Name != "VCMenuList") // Don't clear the VC Menu... tsmiclear.DropDownItems.Clear(); /* if (tsmiclear.OwnerItem != VCMenuList) // and don't disable the VC menu subparts... tsmiclear.Enabled = false;*/ } } /// /// Fills the database strip with the local database.xml file. /// private void FillDatabaseStrip(BackgroundWorker worker) { // Something needs to be done to remove this i guess //Control.CheckForIllegalCrossThreadCalls = false; // Set fake items visible and real ones not. Only way to stop buggy enabled stuff. SetPropertyThreadSafe(SystemMenuList, false, "Visible"); SetPropertyThreadSafe(IOSMenuList, false, "Visible"); SetPropertyThreadSafe(VCMenuList, false, "Visible"); SetPropertyThreadSafe(WiiWareMenuList, false, "Visible"); SetPropertyThreadSafe(systemFakeMenuItem, true, "Visible"); SetPropertyThreadSafe(iosFakeMenuItem, true, "Visible"); SetPropertyThreadSafe(vcFakeMenuItem, true, "Visible"); SetPropertyThreadSafe(wwFakeMenuItem, true, "Visible"); Database databaseObj = new Database(); databaseObj.LoadDatabaseToStream(Path.Combine(CURRENT_DIR, "database.xml")); ToolStripMenuItem[] systemItems = databaseObj.LoadSystemTitles(); for (int a = 0; a < systemItems.Length; a++) { systemItems[a].DropDownItemClicked += new ToolStripItemClickedEventHandler(DatabaseItem_Clicked); for (int b = 0; b < systemItems[a].DropDownItems.Count; b++) { ToolStripMenuItem syslowerentry = (ToolStripMenuItem)systemItems[a].DropDownItems[b]; if (syslowerentry.DropDownItems.Count > 0) { syslowerentry.DropDownItemClicked += new ToolStripItemClickedEventHandler(DatabaseItem_Clicked); } } //AddToolStripItemToStrip(SystemMenuList, systemItems[a]); //SystemMenuList.DropDownItems.Add(systemItems[a]); } Array.Sort(systemItems, delegate(ToolStripMenuItem tsmi1, ToolStripMenuItem tsmi2) { return tsmi1.Text .Substring(18, tsmi1.Text.Length - 19).CompareTo(tsmi2.Text.Substring(18, tsmi2.Text.Length - 19)); }); AddToolStripItemToStrip(SystemMenuList, systemItems); SetPropertyThreadSafe(systemFakeMenuItem, false, "Visible"); SetPropertyThreadSafe(SystemMenuList, true, "Visible"); Debug.WriteLine("Database: SysTitles added"); worker.ReportProgress(25); ToolStripMenuItem[] iosItems = databaseObj.LoadIosTitles(); for (int a = 0; a < iosItems.Length; a++) { iosItems[a].DropDownItemClicked += new ToolStripItemClickedEventHandler(DatabaseItem_Clicked); //AddToolStripItemToStrip(IOSMenuList, iosItems[a]); //IOSMenuList.DropDownItems.Add(iosItems[a]); } AddToolStripItemToStrip(IOSMenuList, iosItems); SetPropertyThreadSafe(iosFakeMenuItem, false, "Visible"); SetPropertyThreadSafe(IOSMenuList, true, "Visible"); Debug.WriteLine("Database: IosTitles added"); worker.ReportProgress(50); ToolStripMenuItem[][] vcItems = databaseObj.LoadVirtualConsoleTitles(); for (int a = 0; a < vcItems.Length; a++) { for (int b = 0; b < vcItems[a].Length; b++) { vcItems[a][b].DropDownItemClicked += new ToolStripItemClickedEventHandler(DatabaseItem_Clicked); for (int c = 0; c < vcItems[a][b].DropDownItems.Count; c++) { ToolStripMenuItem lowerentry = (ToolStripMenuItem)vcItems[a][b].DropDownItems[c]; lowerentry.DropDownItemClicked += new ToolStripItemClickedEventHandler(DatabaseItem_Clicked); } } Array.Sort(vcItems[a], delegate(ToolStripMenuItem tsmi1, ToolStripMenuItem tsmi2) { return tsmi1.Text .Substring(18, tsmi1.Text.Length - 19).CompareTo(tsmi2.Text.Substring(18, tsmi2.Text.Length - 19)); }); AddToolStripItemToStrip((ToolStripMenuItem)VCMenuList.DropDownItems[a], vcItems[a]); } SetPropertyThreadSafe(vcFakeMenuItem, false, "Visible"); SetPropertyThreadSafe(VCMenuList, true, "Visible"); Debug.WriteLine("Database: VCTitles added"); worker.ReportProgress(75); ToolStripMenuItem[] wwItems = databaseObj.LoadWiiWareTitles(); for (int a = 0; a < wwItems.Length; a++) { wwItems[a].DropDownItemClicked += new ToolStripItemClickedEventHandler(DatabaseItem_Clicked); for (int b = 0; b < wwItems[a].DropDownItems.Count; b++) { ToolStripMenuItem lowerentry = (ToolStripMenuItem)wwItems[a].DropDownItems[b]; if (lowerentry.DropDownItems.Count > 0) { lowerentry.DropDownItemClicked += new ToolStripItemClickedEventHandler(DatabaseItem_Clicked); } } //AddToolStripItemToStrip(WiiWareMenuList, wwItems[a]); //WiiWareMenuList.DropDownItems.Add(wwItems[a]); } Array.Sort(wwItems, delegate(ToolStripMenuItem tsmi1, ToolStripMenuItem tsmi2) { return tsmi1.Text .Substring(18, tsmi1.Text.Length - 19).CompareTo(tsmi2.Text.Substring(18, tsmi2.Text.Length - 19)); }); AddToolStripItemToStrip(WiiWareMenuList, wwItems); SetPropertyThreadSafe(wwFakeMenuItem, false, "Visible"); SetPropertyThreadSafe(WiiWareMenuList, true, "Visible"); Debug.WriteLine("Database: WiiWareTitles added"); worker.ReportProgress(100); } /// /// Adds the tool strip item to strip. /// /// The type. /// The additionitem. /// The attributes. // private void AddToolStripItemToStrip(ToolStripMenuItem menulist, ToolStripMenuItem additionitem) private void AddToolStripItemToStrip(ToolStripMenuItem menulist, ToolStripMenuItem[] additionitems) { //Control.CheckForIllegalCrossThreadCalls = false; //Debug.WriteLine(String.Format("Adding item")); if (this.InvokeRequired) { //Debug.WriteLine("InvokeRequired..."); AddToolStripItemToStripCallback atsitsc = new AddToolStripItemToStripCallback(AddToolStripItemToStrip); this.Invoke(atsitsc, new object[] { menulist, additionitems }); return; } menulist.DropDownItems.AddRange(additionitems); /* // Do not sort IOS menu (alphabetization fail) if (menulist.Text == IOSMenuList.Text) { menulist.DropDownItems.Add(additionitem); return; } if (menulist.DropDownItems.Count < 1) { menulist.DropDownItems.Add(additionitem); return; } // Sorting of items by name 18 chars in... //try //{ for (int a = 0; a < menulist.DropDownItems.Count; a++) { if (menulist.DropDownItems[a].Text .Substring(18, menulist.DropDownItems[a].Text.Length - 19) .CompareTo(additionitem.Text.Substring(18, additionitem.Text.Length - 19)) == 1) { menulist.DropDownItems.Insert((a), additionitem); return; } } //} //catch (Exception) //{ //Debug.WriteLine("Tryfail at : " + additionitem.Text); //menulist.DropDownItems.Add(additionitem); //}*/ //menulist.DropDownItems.Add(additionitem); } /// /// Mods WAD names to be official. /// /// The titlename. public string OfficialWADNaming(string titlename) { if (titlename == "MIOS") titlename = "RVL-mios-[v].wad"; else if (titlename.Contains("IOS")) titlename = titlename + "-64-[v].wad"; else if (titlename.Contains("System Menu")) titlename = "RVL-WiiSystemmenu-[v].wad"; else if (titlename.Contains("System Menu")) titlename = "RVL-WiiSystemmenu-[v].wad"; else if (titlename == "BC") titlename = "RVL-bc-[v].wad"; else if (titlename.Contains("Mii Channel")) titlename = "RVL-NigaoeNR-[v].wad"; else if (titlename.Contains("Shopping Channel")) titlename = "RVL-Shopping-[v].wad"; else if (titlename.Contains("Weather Channel")) titlename = "RVL-Weather-[v].wad"; else titlename = titlename + "-NUS-[v].wad"; if (wadnamebox.InvokeRequired) { OfficialWADNamingCallback ownc = new OfficialWADNamingCallback(OfficialWADNaming); wadnamebox.Invoke(ownc, new object[] { titlename }); return titlename; } wadnamebox.Text = titlename; if (titleversion.Text != "") wadnamebox.Text = wadnamebox.Text.Replace("[v]", "v" + titleversion.Text); return titlename; } /* private void upditem_itemclicked(object sender, ToolStripItemClickedEventArgs e) { WriteStatus("Preparing to run download script..."); //script_mode = true; SetTextThreadSafe(statusbox, ""); //WriteStatus("Starting script download. Please be patient!"); string[] NUS_Entries = e.ClickedItem.AccessibleDescription.Split('\n'); // TODO: Find somewhere better to put this. AND FAST! for (int i = 0; i < NUS_Entries.Length; i++) { WriteStatus(NUS_Entries[i]); } script_filename = "\000"; nusentries = NUS_Entries; BackgroundWorker scripter = new BackgroundWorker(); scripter.DoWork += new DoWorkEventHandler(RunScript); scripter.RunWorkerAsync(); }*/ public void DatabaseItem_Clicked(object sender, ToolStripItemClickedEventArgs e) { Regex IdandTitle = new Regex(@"[0-9A-Z]*\s-\s.*"); Regex RegionEntry = new Regex(@"[0-9A-Z][0-9A-Z] \(.*\)"); Regex VersionEntry = new Regex(@"v[0-9]*.*"); // This item is a Titleid - Descname entry if (IdandTitle.IsMatch(e.ClickedItem.Text)) { string text = e.ClickedItem.Text.Replace(" - ", "~"); string[] values = text.Split('~'); titleidbox.Text = values[0]; statusbox.Text = String.Format(" --- {0} ---", values[1]); titleversion.Text = String.Empty; if ((e.ClickedItem.Image) == (Database.orange) || (e.ClickedItem.Image) == (Database.redorange)) { WriteStatus("Note: This title has no ticket and cannot be packed/decrypted!"); packbox.Checked = false; decryptbox.Checked = false; } // Check for danger item if ((e.ClickedItem.Image) == (Database.redgreen) || (e.ClickedItem.Image) == (Database.redorange)) WriteStatus("\n" + e.ClickedItem.ToolTipText); } // Region ClickedItem if (RegionEntry.IsMatch(e.ClickedItem.Text)) { string text = e.ClickedItem.OwnerItem.Text.Replace(" - ", "~"); string[] values = text.Split('~'); titleidbox.Text = values[0]; statusbox.Text = String.Format(" --- {0} ---", values[1]); titleversion.Text = String.Empty; // Put 'XX' into title ID titleidbox.Text = titleidbox.Text.Replace("XX", e.ClickedItem.Text.Substring(0, 2)); if ((e.ClickedItem.OwnerItem.Image) == (Database.orange) || (e.ClickedItem.OwnerItem.Image) == (Database.redorange)) { WriteStatus("Note: This title has no ticket and cannot be packed/decrypted!"); packbox.Checked = false; decryptbox.Checked = false; } // Check for danger item if ((e.ClickedItem.OwnerItem.Image) == (Database.redgreen) || (e.ClickedItem.OwnerItem.Image) == (Database.redorange)) WriteStatus("\n" + e.ClickedItem.OwnerItem.ToolTipText); } // Version ClickedItem if (VersionEntry.IsMatch(e.ClickedItem.Text) || e.ClickedItem.Text == "Latest Version") { if (RegionEntry.IsMatch(e.ClickedItem.OwnerItem.Text)) { string text = e.ClickedItem.OwnerItem.OwnerItem.Text.Replace(" - ", "~"); string[] values = text.Split('~'); titleidbox.Text = values[0]; statusbox.Text = String.Format(" --- {0} ---", values[1]); // Put 'XX' into title ID titleidbox.Text = titleidbox.Text.Replace("XX", e.ClickedItem.OwnerItem.Text.Substring(0, 2)); } else { string text = e.ClickedItem.OwnerItem.Text.Replace(" - ", "~"); string[] values = text.Split('~'); titleidbox.Text = values[0]; statusbox.Text = String.Format(" --- {0} ---", values[1]); } // Set version if (e.ClickedItem.Text == "Latest Version") titleversion.Text = String.Empty; else { string[] version = e.ClickedItem.Text.Replace("v", "").Split(' '); titleversion.Text = version[0]; } if (RegionEntry.IsMatch(e.ClickedItem.OwnerItem.Text)) { if ((e.ClickedItem.OwnerItem.OwnerItem.Image) == (Database.orange) || (e.ClickedItem.OwnerItem.OwnerItem.Image) == (Database.redorange)) { WriteStatus("Note: This title has no ticket and cannot be packed/decrypted!"); packbox.Checked = false; decryptbox.Checked = false; } // Check for danger item if ((e.ClickedItem.OwnerItem.OwnerItem.Image) == (Database.redgreen) || (e.ClickedItem.OwnerItem.OwnerItem.Image) == (Database.redorange)) WriteStatus("\n" + e.ClickedItem.OwnerItem.OwnerItem.ToolTipText); } else { if ((e.ClickedItem.OwnerItem.Image) == (Database.orange) || (e.ClickedItem.OwnerItem.Image) == (Database.redorange)) { WriteStatus("Note: This title has no ticket and cannot be packed/decrypted!"); packbox.Checked = false; decryptbox.Checked = false; } // Check for danger item if ((e.ClickedItem.OwnerItem.Image) == (Database.redgreen) || (e.ClickedItem.OwnerItem.Image) == (Database.redorange)) WriteStatus("\n" + e.ClickedItem.OwnerItem.ToolTipText); } } } /// /// Gathers the region based on index /// /// The index. /// XmlDocument with database inside /// Region desc private string RegionFromIndex(int index, XmlDocument databasexml) { /* Typical Region XML * 41 (All/System) 44 (German) 45 (USA/NTSC) 46 (French) 4A (Japan) 4B (Korea) 4C (Japanese Import to Europe/Australia/PAL) 4D (American Import to Europe/Australia/PAL) 4E (Japanese Import to USA/NTSC) 50 (Europe/PAL) 51 (Korea w/ Japanese Language) 54 (Korea w/ English Language) 58 (Some Homebrew) */ XmlNodeList XMLRegionList = databasexml.GetElementsByTagName("REGIONS"); XmlNodeList ChildrenOfTheNode = XMLRegionList[0].ChildNodes; // For each child node (region node) for (int z = 0; z < ChildrenOfTheNode.Count; z++) { // Gather attributes (index='x') XmlAttributeCollection XMLAttributes = ChildrenOfTheNode[z].Attributes; // Return value of node if index matches if (Convert.ToInt32(XMLAttributes[0].Value) == index) return ChildrenOfTheNode[z].InnerText; } return "XX (Error)"; } /// /// Loads the region codes. /// private void LoadRegionCodes() { // TODO: make this check InvokeRequired... if (this.InvokeRequired) { BootChecksCallback bcc = new BootChecksCallback(LoadRegionCodes); this.Invoke(bcc); return; } Database databaseObj = new Database(); databaseObj.LoadDatabaseToStream(Path.Combine(CURRENT_DIR, "database.xml")); ToolStripMenuItem[] regionItems = databaseObj.LoadRegionCodes(); // For each child node (region node) for (int z = 0; z < regionItems.Length; z++) { RegionCodesList.DropDownItems.Add(regionItems[z].Text); } } private void RegionCodesList_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e) { if (titleidbox.Text.Length == 16) titleidbox.Text = titleidbox.Text.Substring(0, 14) + e.ClickedItem.Text.Substring(0, 2); } /// /// Removes the illegal characters. /// /// removes the illegal chars /// legal string private static string RemoveIllegalCharacters(string databasestr) { // Database strings must contain filename-legal characters. foreach (char illegalchar in System.IO.Path.GetInvalidFileNameChars()) { if (databasestr.Contains(illegalchar.ToString())) databasestr = databasestr.Replace(illegalchar, '-'); } return databasestr; } private void ClearStatusbox(object sender, EventArgs e) { // Clear Statusbox.text statusbox.Text = ""; } /// /// Makes everything disabled/enabled. /// /// if set to true [enabled]. private void SetEnableforDownload(bool enabled) { if (this.InvokeRequired) { SetEnableForDownloadCallback sefdcb = new SetEnableForDownloadCallback(SetEnableforDownload); this.Invoke(sefdcb, new object[] { enabled }); return; } // Disable things the user should not mess with during download... downloadstartbtn.Enabled = enabled; titleidbox.Enabled = enabled; titleversion.Enabled = enabled; Extrasbtn.Enabled = enabled; databaseButton.Enabled = enabled; packbox.Enabled = enabled; localuse.Enabled = enabled; saveaswadbtn.Enabled = enabled; decryptbox.Enabled = enabled; keepenccontents.Enabled = enabled; scriptsbutton.Enabled = enabled; consoleCBox.Enabled = enabled; iosPatchCheckbox.Enabled = enabled; } /// /// Makes tooltips disappear in the database, as many contain danger tag info. /// /// if set to true [enabled]. private void ShowInnerToolTips(bool enabled) { // Force tooltips to GTFO in sub menus... foreach (ToolStripItem item in databaseStrip.Items) { try { ToolStripMenuItem menuitem = (ToolStripMenuItem) item; menuitem.DropDown.ShowItemToolTips = false; } catch (Exception) { // Do nothing, some objects will not cast. } } foreach (ToolStripItem item in scriptsStrip.Items) { try { ToolStripMenuItem menuitem = (ToolStripMenuItem)item; menuitem.DropDown.ShowItemToolTips = false; } catch (Exception) { // Do nothing, some objects will not cast. } } } /// /// Updates the name of the packed WAD in the textbox. /// private void UpdatePackedName() { // Change WAD name if applicable string title_name = null; if ((titleidbox.Enabled == true) && (packbox.Checked == true)) { if (titleversion.Text != "") { wadnamebox.Text = titleidbox.Text + "-NUS-v" + titleversion.Text + ".wad"; } else { wadnamebox.Text = titleidbox.Text + "-NUS-[v]" + titleversion.Text + ".wad"; } if ((File.Exists("database.xml") == true) && (titleidbox.Text.Length == 16)) title_name = NameFromDatabase(titleidbox.Text); if (title_name != null) { wadnamebox.Text = wadnamebox.Text.Replace(titleidbox.Text, title_name); OfficialWADNaming(title_name); } } wadnamebox.Text = RemoveIllegalCharacters(wadnamebox.Text); } /// /// Determines whether OS is win7. /// /// /// true if OS = win7; otherwise, false. /// private static bool IsWin7() { return (Environment.OSVersion.VersionString.Contains("6.1") == true); } private byte[] NewIntegertoByteArray(int theInt, int arrayLen) { byte[] resultArray = new byte[arrayLen]; for (int i = arrayLen - 1; i >= 0; i--) { resultArray[i] = (byte) ((theInt >> (8*i)) & 0xFF); } Array.Reverse(resultArray); // Fix duplication, rewrite extra to 0x00; if (arrayLen > 4) { for (int i = 0; i < (arrayLen - 4); i++) { resultArray[i] = 0x00; } } return resultArray; } private WebClient ConfigureWithProxy(WebClient client) { // Proxy if (!(String.IsNullOrEmpty(proxy_url))) { WebProxy customproxy = new WebProxy(); customproxy.Address = new Uri(proxy_url); if (String.IsNullOrEmpty(proxy_usr)) customproxy.UseDefaultCredentials = true; else { NetworkCredential cred = new NetworkCredential(); cred.UserName = proxy_usr; if (!(String.IsNullOrEmpty(proxy_pwd))) cred.Password = proxy_pwd; customproxy.Credentials = cred; } client.Proxy = customproxy; WriteStatus(" - Custom proxy settings applied!"); } else { try { client.Proxy = WebRequest.GetSystemWebProxy(); client.UseDefaultCredentials = true; } catch (NotImplementedException) { // Linux support WriteStatus("This operating system does not support automatic system proxy usage. Operating without a proxy..."); } } return client; } /// /// Retrieves the new database via WiiBrew. /// /// Database as a String private void RetrieveNewDatabase(object sender, DoWorkEventArgs e) { // Retrieve Wiibrew database page source code WebClient databasedl = new WebClient(); // Proxy databasedl = ConfigureWithProxy(databasedl); string wiibrewsource = databasedl.DownloadString("http://www.wiibrew.org/wiki/NUS_Downloader/database?cachesmash=" + System.DateTime.Now.ToString()); // Strip out HTML wiibrewsource = Regex.Replace(wiibrewsource, @"<(.|\n)*?>", ""); // Shrink to fix only the database string startofdatabase = "<database v"; string endofdatabase = "</database>"; wiibrewsource = wiibrewsource.Substring(wiibrewsource.IndexOf(startofdatabase), wiibrewsource.Length - wiibrewsource.IndexOf(startofdatabase)); wiibrewsource = wiibrewsource.Substring(0, wiibrewsource.IndexOf(endofdatabase) + endofdatabase.Length); // Fix ", <, >, and spaces wiibrewsource = wiibrewsource.Replace("<", "<"); wiibrewsource = wiibrewsource.Replace(">", ">"); wiibrewsource = wiibrewsource.Replace(""", '"'.ToString()); wiibrewsource = wiibrewsource.Replace(" ", " "); // Shouldn't occur, but they happen... // Return parsed xml database... e.Result = wiibrewsource; } private void RetrieveNewDatabase_Completed(object sender, RunWorkerCompletedEventArgs e) { string database = e.Result.ToString(); try { Database db = new Database(); db.LoadDatabaseToStream(Path.Combine(CURRENT_DIR, "database.xml")); string currentversion = db.GetDatabaseVersion(); string onlineversion = Database.GetDatabaseVersion(database); WriteStatus(" - Database successfully parsed!"); WriteStatus(" - Current Database Version: " + currentversion); WriteStatus(" - Online Database Version: " + onlineversion); if (currentversion == onlineversion) { WriteStatus(" - You have the latest database version!"); return; } } catch (FileNotFoundException) { WriteStatus(" - Database does not yet exist."); WriteStatus(" - Online Database Version: " + Database.GetDatabaseVersion(database)); } bool isCreation = false; if (File.Exists("database.xml")) { WriteStatus(" - Overwriting your current database.xml..."); WriteStatus(" - The old database will become 'olddatabase.xml' in case the new one is faulty."); string olddatabase = File.ReadAllText("database.xml"); File.WriteAllText("olddatabase.xml", olddatabase); File.Delete("database.xml"); File.WriteAllText("database.xml", database); } else { WriteStatus(" - database.xml has been created."); File.WriteAllText("database.xml", database); isCreation = true; } // Load it up... this.fds.RunWorkerAsync(); if (isCreation) { WriteStatus("Database successfully created!"); databaseButton.Visible = true; //databaseButton.Enabled = false; updateDatabaseToolStripMenuItem.Text = "Download Database"; } else { WriteStatus("Database successfully updated!"); } } private void updateDatabaseToolStripMenuItem_Click(object sender, EventArgs e) { statusbox.Text = ""; WriteStatus("Updating your database.xml from Wiibrew.org"); BackgroundWorker dbFetcher = new BackgroundWorker(); dbFetcher.DoWork += new DoWorkEventHandler(RetrieveNewDatabase); dbFetcher.RunWorkerCompleted += new RunWorkerCompletedEventHandler(RetrieveNewDatabase_Completed); dbFetcher.RunWorkerAsync(); } private void loadInfoFromTMDToolStripMenuItem_Click(object sender, EventArgs e) { // Extras menu -> Load TMD... LoadTitleFromTMD(); } /// /// Sends the SOAP request to NUS. /// /// The Request /// public string SendSOAPRequest(string soap_xml) { System.Net.HttpWebRequest req = (System.Net.HttpWebRequest) System.Net.HttpWebRequest.Create("http://nus.shop.wii.com:80/nus/services/NetUpdateSOAP"); req.Method = "POST"; req.UserAgent = "wii libnup/1.0"; req.Headers.Add("SOAPAction", '"' + "urn:nus.wsapi.broadon.com/" + '"'); // Proxy if (!(String.IsNullOrEmpty(proxy_url))) { WebProxy customproxy = new WebProxy(); customproxy.Address = new Uri(proxy_url); if (String.IsNullOrEmpty(proxy_usr)) customproxy.UseDefaultCredentials = true; else { NetworkCredential cred = new NetworkCredential(); cred.UserName = proxy_usr; if (!(String.IsNullOrEmpty(proxy_pwd))) cred.Password = proxy_pwd; customproxy.Credentials = cred; } req.Proxy = customproxy; WriteStatus(" - Custom proxy settings applied!"); } else { req.Proxy = WebRequest.GetSystemWebProxy(); req.UseDefaultCredentials = true; } Stream writeStream = req.GetRequestStream(); UTF8Encoding encoding = new UTF8Encoding(); byte[] bytes = encoding.GetBytes(soap_xml); req.ContentType = "text/xml; charset=utf-8"; //req.ContentLength = bytes.Length; writeStream.Write(bytes, 0, bytes.Length); writeStream.Close(); Application.DoEvents(); try { string result; System.Net.HttpWebResponse resp = (System.Net.HttpWebResponse) req.GetResponse(); using (Stream responseStream = resp.GetResponseStream()) { using (StreamReader readStream = new StreamReader(responseStream, Encoding.UTF8)) { result = readStream.ReadToEnd(); } } req.Abort(); Application.DoEvents(); return result; } catch (Exception ex) { req.Abort(); return ex.Message.ToString(); } } private void emulateUpdate_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e) { // Begin Wii System Update statusbox.Text = ""; WriteStatus("Starting Wii System Update..."); scriptsStrip.Close(); string deviceID = "4362227770"; string messageID = "13198105123219138"; string attr = "2"; string RegionID = e.ClickedItem.Text.Substring(0, 3); if (RegionID == "JAP") // Japan fix, only region not w/ 1st 3 letters same as ID. RegionID = "JPN"; string CountryCode = RegionID.Substring(0, 2); /* [14:26] RegionID: USA, Country: US; RegionID: JPN, Country: JP; RegionID: EUR, Country: EU; RegionID: KOR, Country: KO; */ string soap_req = "\n" + "\n\n" + "1.0\n" + messageID + "\n" + deviceID + "\n" + "" + RegionID + "\n" + CountryCode + "\n\n0000000100000001\n" + "2\n\n\n0000000100000002\n" + "33\n\n\n0000000100000009\n" + "516\n\n" + attr + "\n\n" + "\n\n"; WriteStatus(" - Sending SOAP Request to NUS..."); WriteStatus(" - Region: " + RegionID); string update_xml = SendSOAPRequest(soap_req); if (update_xml != null) WriteStatus(" - Recieved Update Info!"); else { WriteStatus(" - Fail."); return; } WriteStatus(" - Title information:"); string script_text = ""; XmlDocument xDoc = new XmlDocument(); xDoc.LoadXml(update_xml); XmlNodeList TitleList = xDoc.GetElementsByTagName("TitleVersion"); for (int a = 0; a < TitleList.Count; a++) { XmlNodeList TitleInfo = TitleList[a].ChildNodes; string TitleID = ""; string Version = ""; for (int b = 0; b < TitleInfo.Count; b++) { switch (TitleInfo[b].Name) { case "TitleId": TitleID = TitleInfo[b].InnerText; break; case "Version": Version = TitleInfo[b].InnerText; break; default: break; } } WriteStatus(String.Format(" - {0} [v{1}]", TitleID, Version)); if ((NUSDFileExists("database.xml") == true) && ((!(String.IsNullOrEmpty(NameFromDatabase(TitleID)))))) //statusbox.Text += String.Format(" [{0}]", NameFromDatabase(TitleID)); WriteStatus(String.Format(" [{0}]", NameFromDatabase(TitleID))); script_text += String.Format("{0} {1}\n", TitleID, DisplayBytes(NewIntegertoByteArray(Convert.ToInt32(Version), 2), "")); } WriteStatus(" - Outputting results to NUS script..."); if (!(Directory.Exists(Path.Combine(CURRENT_DIR, "scripts")))) { Directory.CreateDirectory(Path.Combine(CURRENT_DIR, "scripts")); WriteStatus(" - Created 'scripts\' directory."); } string time = RemoveIllegalCharacters(DateTime.Now.ToShortTimeString()); File.WriteAllText( String.Format(Path.Combine(CURRENT_DIR, Path.Combine("scripts","{0}_Update_{1}_{2}_{3} at {4}.nus")), RegionID, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Year, time), script_text); WriteStatus(" - Script written!"); scriptsLocalMenuEntry.Enabled = false; this.scriptsWorker.RunWorkerAsync(); WriteStatus(" - Run this script if you feel like downloading the update!"); // TODO: run the script... } /// /// Looks for a title's name by TitleID in Database. /// /// The titleid. /// Existing name; else null private string NameFromDatabase(string titleid) { // DANGER: BAD h4x HERE!! // Fix MIOS/BC naming if (titleid == "0000000100000101") return "MIOS"; else if (titleid == "0000000100000100") return "BC"; XmlDocument xDoc = new XmlDocument(); xDoc.Load("database.xml"); // Variables string[] XMLNodeTypes = new string[4] {"SYS", "IOS", "VC", "WW"}; // Loop through XMLNodeTypes for (int i = 0; i < XMLNodeTypes.Length; i++) // FOR THE FOUR TYPES OF NODES { XmlNodeList XMLSpecificNodeTypeList = xDoc.GetElementsByTagName(XMLNodeTypes[i]); for (int x = 0; x < XMLSpecificNodeTypeList.Count; x++) // FOR EACH ITEM IN THE LIST OF A NODE TYPE { bool found_it = false; // Lol. XmlNodeList ChildrenOfTheNode = XMLSpecificNodeTypeList[x].ChildNodes; for (int z = 0; z < ChildrenOfTheNode.Count; z++) // FOR EACH CHILD NODE { switch (ChildrenOfTheNode[z].Name) { case "titleID": if (ChildrenOfTheNode[z].InnerText == titleid) found_it = true; else if ((ChildrenOfTheNode[z].InnerText.Substring(0, 14) + "XX") == (titleid.Substring(0, 14) + "XX") && (titleid.Substring(0, 14) != "00000001000000")) found_it = true; else found_it = false; break; default: break; } } if (found_it) { for (int z = 0; z < ChildrenOfTheNode.Count; z++) // FOR EACH CHILD NODE { switch (ChildrenOfTheNode[z].Name) { case "name": return ChildrenOfTheNode[z].InnerText; default: break; } } } } } return null; } private void packbox_EnabledChanged(object sender, EventArgs e) { saveaswadbtn.Enabled = packbox.Enabled; //deletecontentsbox.Enabled = packbox.Enabled; } private void SaveProxyBtn_Click(object sender, EventArgs e) { if ((String.IsNullOrEmpty(ProxyURL.Text)) && (String.IsNullOrEmpty(ProxyUser.Text)) && ((File.Exists(Path.Combine(CURRENT_DIR, "proxy.txt"))))) { File.Delete(Path.Combine(CURRENT_DIR, "proxy.txt")); proxyBox.Visible = false; proxy_usr = ""; proxy_url = ""; proxy_pwd = ""; WriteStatus("Proxy settings deleted!"); return; } else if ((String.IsNullOrEmpty(ProxyURL.Text)) && (String.IsNullOrEmpty(ProxyUser.Text)) && ((!(File.Exists(Path.Combine(CURRENT_DIR, "proxy.txt")))))) { proxyBox.Visible = false; WriteStatus("No proxy settings saved!"); return; } string proxy_file = ""; if (!(String.IsNullOrEmpty(ProxyURL.Text))) { proxy_file += ProxyURL.Text + "\n"; proxy_url = ProxyURL.Text; } if (!(String.IsNullOrEmpty(ProxyUser.Text))) { proxy_file += ProxyUser.Text; proxy_usr = ProxyUser.Text; } if (!(String.IsNullOrEmpty(proxy_file))) { File.WriteAllText(Path.Combine(CURRENT_DIR, "proxy.txt"), proxy_file); WriteStatus("Proxy settings saved!"); } proxyBox.Visible = false; SetAllEnabled(false); ProxyVerifyBox.Visible = true; ProxyVerifyBox.Enabled = true; ProxyPwdBox.Enabled = true; SaveProxyBtn.Enabled = true; ProxyVerifyBox.Select(); } private void proxySettingsToolStripMenuItem_Click(object sender, EventArgs e) { // Check for Proxy Settings file... if (File.Exists(Path.Combine(CURRENT_DIR, "proxy.txt")) == true) { string[] proxy_file = File.ReadAllLines(Path.Combine(CURRENT_DIR, "proxy.txt")); ProxyURL.Text = proxy_file[0]; if (proxy_file.Length > 1) { ProxyUser.Text = proxy_file[1]; } } proxyBox.Visible = true; } private void SaveProxyPwdButton_Click(object sender, EventArgs e) { proxy_pwd = ProxyPwdBox.Text; ProxyVerifyBox.Visible = false; SetAllEnabled(true); } private void ProxyPwdBox_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar == Convert.ToChar(Keys.Enter)) SaveProxyPwdButton_Click("LOLWUT", EventArgs.Empty); } private void ProxyAssistBtn_Click(object sender, EventArgs e) { MessageBox.Show("If you are behind a proxy, set these settings to get through to NUS." + " If you have an alternate port for accessing your proxy, add ':' followed by the port."); } private void loadNUSScriptToolStripMenuItem_Click(object sender, EventArgs e) { // Open a NUS script. OpenFileDialog ofd = new OpenFileDialog(); ofd.Multiselect = false; ofd.Filter = "NUS Scripts|*.nus|All Files|*.*"; if (Directory.Exists(Path.Combine(CURRENT_DIR, "scripts"))) ofd.InitialDirectory = Path.Combine(CURRENT_DIR, "scripts"); ofd.Title = "Load a NUS/Wiimpersonator script."; if (ofd.ShowDialog() != DialogResult.Cancel) { string script_content = File.ReadAllText(ofd.FileName); FileInfo script_file = new FileInfo(ofd.FileName); script_content += String.Format(";{0}", script_file.Name.Replace("." + script_file.Extension, "")); BackgroundWorker scripter = new BackgroundWorker(); scripter.DoWork += new DoWorkEventHandler(RunScriptBg); scripter.RunWorkerAsync(script_content); } } /// /// Runs a NUS script (BG). /// /// The sender. /// The instance containing the event data. private void RunScriptBg(object sender, System.ComponentModel.DoWorkEventArgs e) { char ArgsSplitChar = ';'; string[] scriptArgs = e.Argument.ToString().Split(ArgsSplitChar); if (scriptArgs.Length < 2) RunScript(scriptArgs[0], "random"); else { RunScript(scriptArgs[0], RemoveIllegalCharacters(scriptArgs[1])); } /* script_mode = true; SetTextThreadSafe(statusbox, ""); WriteStatus("Starting script download. Please be patient!"); if (!File.Exists(Path.Combine(CURRENT_DIR, "output_" + Path.GetFileNameWithoutExtension(script_filename)))) Directory.CreateDirectory(Path.Combine(CURRENT_DIR, "output_" + Path.GetFileNameWithoutExtension(script_filename))); string[] NUS_Entries; if (script_filename != "\000") { NUS_Entries = File.ReadAllLines(script_filename); } else { NUS_Entries = nusentries; } WriteStatus(String.Format(" - Script loaded ({0} Titles)", NUS_Entries.Length)); for (int a = 0; a < NUS_Entries.Length; a++) { // Download the title WriteStatus(String.Format("===== Running Download ({0}/{1}) =====", a + 1, NUS_Entries.Length)); string[] title_info = NUS_Entries[a].Split(' '); // don't let the delete issue reappear... if (string.IsNullOrEmpty(title_info[0])) break; // WebClient configuration WebClient nusWC = new WebClient(); nusWC = ConfigureWithProxy(nusWC); nusWC.Headers.Add("User-Agent", "wii libnup/1.0"); // Set UserAgent to Wii value // Create\Configure NusClient libWiiSharp.NusClient nusClient = new libWiiSharp.NusClient(); nusClient.ConfigureNusClient(nusWC); nusClient.UseLocalFiles = localuse.Checked; nusClient.ContinueWithoutTicket = true; nusClient.Debug += new EventHandler(nusClient_Debug); libWiiSharp.StoreType[] storeTypes = new libWiiSharp.StoreType[1]; // There's no harm in outputting everything i suppose storeTypes[0] = libWiiSharp.StoreType.All; int title_version = int.Parse(title_info[1], System.Globalization.NumberStyles.HexNumber); string wadName = NameFromDatabase(title_info[0]); if (wadName != null) wadName = OfficialWADNaming(wadName); else wadName = title_info[0] + "-NUS-v" + title_version + ".wad"; nusClient.DownloadTitle(title_info[0], title_version.ToString(), Path.Combine(CURRENT_DIR, ("output_" + Path.GetFileNameWithoutExtension(script_filename))), wadName, storeTypes); /* SetTextThreadSafe(titleidbox, title_info[0]); SetTextThreadSafe(titleversion, Convert.ToString(256* (byte.Parse(title_info[1].Substring(0, 2), System.Globalization.NumberStyles.HexNumber)))); SetTextThreadSafe(titleversion, Convert.ToString(Convert.ToInt32(titleversion.Text) + byte.Parse(title_info[1].Substring(2, 2), System.Globalization.NumberStyles.HexNumber))); button3_Click("Scripter", EventArgs.Empty); Thread.Sleep(1000); while (NUSDownloader.IsBusy) { Thread.Sleep(1000); } } script_mode = false; WriteStatus("Script completed!");*/ } private void scriptsbutton_Click(object sender, EventArgs e) { // Show scripts menu scriptsStrip.Text = "Showing"; scriptsStrip.Show(scriptsbutton, 2, (2+scriptsbutton.Height)); //if (!e.Equals(EventArgs.Empty)) { System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer(); timer.Interval = 51; timer.Tick += new EventHandler(contextmenusTimer_Tick); timer.Start(); } } private void DatabaseEnabled(bool enabled) { for (int a = 0; a < databaseStrip.Items.Count; a++) { databaseStrip.Items[a].Enabled = enabled; databaseStrip.Items[a].Visible = enabled; } for (int b = 0; b < VCMenuList.DropDownItems.Count; b++) { VCMenuList.DropDownItems[b].Enabled = true; VCMenuList.DropDownItems[b].Visible = true; } } void scriptsWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { scriptsLocalMenuEntry.Enabled = true; } void OrganizeScripts(object sender, DoWorkEventArgs e) { //throw new NotImplementedException(); if (Directory.Exists(Path.Combine(CURRENT_DIR, "scripts")) == false) { WriteStatus("Scripts directory not found..."); WriteStatus("- Creating it."); Directory.CreateDirectory(Path.Combine(CURRENT_DIR, "scripts")); } // Clear any entries from previous runthrough if (scriptsLocalMenuEntry.DropDownItems.Count > 0) { // TODO: i suppose this is bad amiright Control.CheckForIllegalCrossThreadCalls = false; scriptsLocalMenuEntry.DropDownItems.Clear(); } // Add directories w/ scripts in \scripts\ foreach (string directory in Directory.GetDirectories(Path.Combine(CURRENT_DIR, "scripts"), "*", SearchOption.TopDirectoryOnly)) { if (Directory.GetFiles(directory, "*.nus", SearchOption.TopDirectoryOnly).Length > 0) { DirectoryInfo dinfo = new DirectoryInfo(directory); ToolStripMenuItem folder_item = new ToolStripMenuItem(); folder_item.Text = dinfo.Name + Path.DirectorySeparatorChar; folder_item.Image = Properties.Resources.folder_table; foreach (string nusscript in Directory.GetFiles(directory, "*.nus", SearchOption.TopDirectoryOnly)) { FileInfo finfo = new FileInfo(nusscript); ToolStripMenuItem nus_script_item = new ToolStripMenuItem(); nus_script_item.Text = finfo.Name; nus_script_item.Image = Properties.Resources.script_start; folder_item.DropDownItems.Add(nus_script_item); nus_script_item.Click += new EventHandler(nus_script_item_Click); } scriptsLocalMenuEntry.DropDownItems.Add(folder_item); } } // Add scripts in \scripts\ foreach (string nusscript in Directory.GetFiles(Path.Combine(CURRENT_DIR, "scripts"), "*.nus", SearchOption.TopDirectoryOnly)) { FileInfo finfo = new FileInfo(nusscript); ToolStripMenuItem nus_script_item = new ToolStripMenuItem(); nus_script_item.Text = finfo.Name; nus_script_item.Image = Properties.Resources.script_start; scriptsLocalMenuEntry.DropDownItems.Add(nus_script_item); nus_script_item.Click += new EventHandler(nus_script_item_Click); } } private void aboutNUSDToolStripMenuItem_Click(object sender, EventArgs e) { // Display About Text... statusbox.Text = ""; WriteStatus("NUS Downloader (NUSD)"); WriteStatus("You are running version: " + version); if (version.StartsWith("SVN")) WriteStatus("SVN BUILD: DO NOT REPORT BROKEN FEATURES!"); WriteStatus("This application created by WB3000"); WriteStatus("Various sections contributed by lukegb"); WriteStatus(String.Empty); /* if (NUSDFileExists("key.bin") == false) WriteStatus("Wii Decryption: Need (key.bin)"); else WriteStatus("Wii Decryption: OK"); if (NUSDFileExists("kkey.bin") == false) WriteStatus("Wii Korea Decryption: Need (kkey.bin)"); else WriteStatus("Wii Korea Decryption: OK"); */ if (NUSDFileExists("dsikey.bin") == false) WriteStatus("DSi Decryption: Need (dsikey.bin)"); else WriteStatus("DSi Decryption: OK"); if (NUSDFileExists("database.xml") == false) WriteStatus("Database: Need (database.xml)"); else WriteStatus("Database: OK"); if (IsWin7()) WriteStatus("Windows 7 Features: Enabled"); WriteStatus(""); WriteStatus("Special thanks to:"); WriteStatus(" * Crediar for his wadmaker tool + source, and for the advice!"); WriteStatus(" * Leathl for libWiiSharp."); WriteStatus(" * SquidMan/Galaxy/comex/Xuzz for advice/sources."); WriteStatus(" * Pasta for database compilation assistance."); WriteStatus(" * Napo7 for testing proxy usage."); WriteStatus(" * Wyatt O'Day for the Windows7ProgressBar Control."); WriteStatus(" * Famfamfam for the Silk Icon Set."); WriteStatus(" * #WiiDev for answering the tough questions."); WriteStatus(" * Anyone who helped beta test!"); } private void checkBox1_CheckedChanged(object sender, EventArgs e) { SaveProxyPwdPermanentBtn.Enabled = checkBox1.Checked; } private void SaveProxyPwdPermanentBtn_Click(object sender, EventArgs e) { proxy_pwd = ProxyPwdBox.Text; string proxy_file = File.ReadAllText(Path.Combine(CURRENT_DIR, "proxy.txt")); proxy_file += String.Format("\n{0}", proxy_pwd); File.WriteAllText(Path.Combine(CURRENT_DIR, "proxy.txt"), proxy_file); ProxyVerifyBox.Visible = false; SetAllEnabled(true); WriteStatus("To delete all traces of proxy settings, delete the proxy.txt file!"); } private void clearButton_MouseEnter(object sender, EventArgs e) { // expand clear button /*button3.Left = 194; button3.Size = new System.Drawing.Size(68, 21);*/ clearButton.Text = "Clear"; //button3.ImageAlign = ContentAlignment.MiddleLeft; } private void clearButton_MouseLeave(object sender, EventArgs e) { // shrink clear button /*button3.Left = 239; button3.Size = new System.Drawing.Size(23, 21);*/ if (Type.GetType ("Mono.Runtime") == null) clearButton.Text = String.Empty; //button3.ImageAlign = ContentAlignment.MiddleCenter; } private void saveaswadbtn_MouseEnter(object sender, EventArgs e) { /*saveaswadbtn.Left = 190; saveaswadbtn.Size = new Size(72, 22);*/ saveaswadbtn.Text = "Save As"; /*saveaswadbtn.ImageAlign = ContentAlignment.MiddleLeft;*/ } private void saveaswadbtn_MouseLeave(object sender, EventArgs e) { /*saveaswadbtn.Left = 230; saveaswadbtn.Size = new Size(32, 22);*/ if (Type.GetType("Mono.Runtime") == null) saveaswadbtn.Text = String.Empty; //saveaswadbtn.ImageAlign = ContentAlignment.MiddleCenter; } void nus_script_item_Click(object sender, EventArgs e) { ToolStripMenuItem tsmi = (ToolStripMenuItem)sender; string folderpath = ""; if (!tsmi.OwnerItem.Equals(this.scriptsLocalMenuEntry)) { folderpath = Path.Combine(tsmi.OwnerItem.Text, folderpath); } folderpath = Path.Combine(this.CURRENT_DIR, Path.Combine("scripts", Path.Combine(folderpath, tsmi.Text))); string script_content = File.ReadAllText(folderpath); script_content += String.Format(";{0}", tsmi.Text.Replace(".nus", "")); BackgroundWorker scripter = new BackgroundWorker(); scripter.DoWork += new DoWorkEventHandler(RunScriptBg); scripter.RunWorkerAsync(script_content); } private void saveaswadbtn_Click(object sender, EventArgs e) { SaveFileDialog wad_saveas = new SaveFileDialog(); wad_saveas.Title = "Save WAD File..."; wad_saveas.Filter = "WAD Files|*.wad|All Files|*.*"; wad_saveas.AddExtension = true; DialogResult dres = wad_saveas.ShowDialog(); if (dres != DialogResult.Cancel) WAD_Saveas_Filename = wad_saveas.FileName; } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { // This prevents errors when exiting before the database is parsed. // This is also probably not the best way to accomplish this... Environment.Exit(0); } private void iosPatchCheckbox_CheckedChanged(object sender, EventArgs e) { if (iosPatchCheckbox.Checked == true) { //packbox.Enabled = false; packbox.Checked = true; SetAllEnabled(false); iosPatchGroupBox.Visible = true; iosPatchGroupBox.Enabled = true; iosPatchesListBox.Enabled = true; iosPatchGroupBoxOKbtn.Enabled = true; } } private void iosPatchGroupBoxOKbtn_Click(object sender, EventArgs e) { SetAllEnabled(true); iosPatchGroupBox.Visible = false; if (iosPatchesListBox.CheckedIndices.Count == 0) // Uncheck the checkbox to indicate no patches iosPatchCheckbox.Checked = false; } private void FillDatabaseScripts() { SetPropertyThreadSafe(scriptsDatabaseToolStripMenuItem, false, "Visible"); Database databaseObj = new Database(); databaseObj.LoadDatabaseToStream(Path.Combine(CURRENT_DIR, "database.xml")); ToolStripMenuItem[] scriptItems = databaseObj.LoadScripts(); for (int a = 0; a < scriptItems.Length; a++) { scriptItems[a].Click += new EventHandler(ScriptItem_Clicked); //AddToolStripItemToStrip(scriptsDatabaseToolStripMenuItem, scriptItems[a]); //SystemMenuList.DropDownItems.Add(systemItems[a]); } AddToolStripItemToStrip(scriptsDatabaseToolStripMenuItem, scriptItems); SetPropertyThreadSafe(scriptsDatabaseToolStripMenuItem, true, "Enabled"); SetPropertyThreadSafe(scriptsDatabaseToolStripMenuItem, true, "Visible"); } public void ScriptItem_Clicked(object sender, EventArgs e) { // Scripts from database are stored in tooltips... ToolStripMenuItem tsmi = (ToolStripMenuItem)sender; string script_content = tsmi.ToolTipText; script_content += String.Format(";{0}", tsmi.Text); BackgroundWorker scripter = new BackgroundWorker(); scripter.DoWork += new DoWorkEventHandler(RunScriptBg); scripter.RunWorkerAsync(script_content); } void ReorganizePreviousFolderStructure(object sender, DoWorkEventArgs e) { // 0000000000000000v000\* become titles\0000000000000000\v000\* Regex TitleDirectoryRegex = new Regex(@"[a-zA-Z0-9]{16}v?([0-9]*)?"); if (Directory.Exists(Path.Combine(CURRENT_DIR, "titles")) == false) Directory.CreateDirectory(Path.Combine(CURRENT_DIR, "titles")); string[] directories = Directory.GetDirectories(CURRENT_DIR, "*", SearchOption.TopDirectoryOnly); Debug.WriteLine("Dirs: " + directories.Length); foreach (string directory in directories) { Debug.WriteLine("ff: " + directory); DirectoryInfo dinfo = new DirectoryInfo(directory); // name is XXXXXXXXXXXXXXXXvYYYY if (TitleDirectoryRegex.IsMatch(dinfo.Name.ToString()) && dinfo.Name.Contains("v")) { string[] title_info = dinfo.Name.Split('v'); string titleid_dir = Path.Combine(Path.Combine(CURRENT_DIR, "titles"), title_info[0]); string newfull_dir = Path.Combine(titleid_dir, String.Format("{0}", title_info[1])); if (Directory.Exists(titleid_dir) == false) Directory.CreateDirectory(titleid_dir); if (Directory.Exists(newfull_dir) == false) Directory.CreateDirectory(newfull_dir); string[] files = Directory.GetFiles(directory, "*", SearchOption.TopDirectoryOnly); foreach (string file in files) { FileInfo titlefile = new FileInfo(file); if (File.Exists(Path.Combine(newfull_dir, titlefile.Name)) == false) titlefile.MoveTo(Path.Combine(newfull_dir, titlefile.Name)); } if (dinfo.GetFiles().Length <= 0 && dinfo.GetDirectories().Length <= 0) Directory.Delete(directory); } else if (TitleDirectoryRegex.IsMatch(dinfo.Name.ToString())) { string titleid_dir = Path.Combine(Path.Combine(CURRENT_DIR, "titles"), dinfo.Name.ToString()); libWiiSharp.TMD tmdfile = new libWiiSharp.TMD(); int count = 0; string[] tmdfiles = Directory.GetFiles(directory, "*tmd*", SearchOption.TopDirectoryOnly); if (tmdfiles.Length > 1) continue; //Too many TMD files ? foreach (string file in tmdfiles) { if (file.Contains("tmd")) { tmdfile.LoadFile(file); count++; } } if (count == 0) continue; string version = tmdfile.TitleVersion.ToString(); string newfull_dir = Path.Combine(titleid_dir, String.Format("{0}", version)); if (Directory.Exists(titleid_dir) == false) Directory.CreateDirectory(titleid_dir); if (Directory.Exists(newfull_dir) == false) Directory.CreateDirectory(newfull_dir); string[] files = Directory.GetFiles(directory, "*", SearchOption.TopDirectoryOnly); foreach (string file in files) { FileInfo titlefile = new FileInfo(file); if (File.Exists(Path.Combine(newfull_dir, titlefile.Name)) == false) titlefile.MoveTo(Path.Combine(newfull_dir, titlefile.Name)); } if (dinfo.GetFiles().Length <= 0 && dinfo.GetDirectories().Length <= 0) Directory.Delete(directory); } } } void ReorganizePreviousFolderStructure_Completed(object sender, RunWorkerCompletedEventArgs e) { WriteStatus(" - Operation complete!"); } private void RunScript(string scriptstr, string scriptname) { // Form and folder stuffs SetTextThreadSafe(statusbox, ""); WriteStatus("Starting script download. Please be patient!"); string scriptdir; if (scriptname == "random") scriptdir = Path.Combine(Path.Combine(CURRENT_DIR, "scripts"), RandomString(7) + "_output"); else scriptdir = Path.Combine(Path.Combine(CURRENT_DIR, "scripts"), scriptname + "_output"); if (!File.Exists(scriptdir)) Directory.CreateDirectory(scriptdir); // Parse entries string[] NUS_Entries = scriptstr.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); WriteStatus(String.Format(" - Script loaded ({0} Titles)", NUS_Entries.Length)); WriteStatus(" - Output: " + scriptdir.Replace(CURRENT_DIR, "")); for (int a = 0; a < NUS_Entries.Length; a++) { // Download the title WriteStatus(String.Format("===== Running Download ({0}/{1}) =====", a + 1, NUS_Entries.Length)); string[] title_info = NUS_Entries[a].Split(' '); // don't let the delete issue reappear... if (string.IsNullOrEmpty(title_info[0])) continue; // WebClient configuration WebClient nusWC = new WebClient(); nusWC = ConfigureWithProxy(nusWC); nusWC.Headers.Add("User-Agent", "wii libnup/1.0"); // Set UserAgent to Wii value // Create\Configure NusClient libWiiSharp.NusClient nusClient = new libWiiSharp.NusClient(); nusClient.ConfigureNusClient(nusWC); nusClient.UseLocalFiles = localuse.Checked; nusClient.ContinueWithoutTicket = true; nusClient.Debug += new EventHandler(nusClient_Debug); libWiiSharp.StoreType[] storeTypes = new libWiiSharp.StoreType[1]; // There's no harm in outputting everything i suppose storeTypes[0] = libWiiSharp.StoreType.All; int title_version = int.Parse(title_info[1], System.Globalization.NumberStyles.HexNumber); string wadName = NameFromDatabase(title_info[0]); if (wadName != null) wadName = OfficialWADNaming(wadName); else wadName = title_info[0] + "-NUS-v" + title_version + ".wad"; nusClient.DownloadTitle(title_info[0], title_version.ToString(), scriptdir, wadName, storeTypes); } WriteStatus("Script completed!"); } // Random string function for temp foldernames in RunScript. // Probably going to be removed TODO private readonly Random _rng = new Random(); private const string _chars = "abcdefghijklmnopqrstuvwxyz"; private string RandomString(int size) { char[] buffer = new char[size]; for (int i = 0; i < size; i++) { buffer[i] = _chars[_rng.Next(_chars.Length)]; } return new string(buffer); } void Form1_MouseWheel(object sender, System.Windows.Forms.MouseEventArgs e) { //Debug.WriteLine("Delta: " + e.Delta.ToString()); if (SystemMenuList.DropDown.DisplayRectangle.Contains(e.Location) || SystemMenuList.DropDown.Bounds.Contains(e.Location) || WiiWareMenuList.DropDown.DisplayRectangle.Contains(e.Location) || WiiWareMenuList.DropDown.Bounds.Contains(e.Location) || VCMenuList.DropDown.DisplayRectangle.Contains(e.Location) || VCMenuList.DropDown.Bounds.Contains(e.Location) || IOSMenuList.DropDown.DisplayRectangle.Contains(e.Location) || IOSMenuList.DropDown.Bounds.Contains(e.Location)) { if (e.Delta > 0) { System.Windows.Forms.SendKeys.Send("{UP}"); System.Windows.Forms.SendKeys.Send("{UP}"); System.Windows.Forms.SendKeys.Send("{UP}"); System.Windows.Forms.SendKeys.Send("{UP}"); System.Windows.Forms.SendKeys.Send("{UP}"); } else { System.Windows.Forms.SendKeys.Send("{DOWN}"); System.Windows.Forms.SendKeys.Send("{DOWN}"); System.Windows.Forms.SendKeys.Send("{DOWN}"); System.Windows.Forms.SendKeys.Send("{DOWN}"); System.Windows.Forms.SendKeys.Send("{DOWN}"); } } } private void openNUSDDirectoryToolStripMenuItem_Click(object sender, EventArgs e) { // Opens the directory NUSD is working in... (CURREND_DIR) Process.Start(CURRENT_DIR); } private void mainPageToolStripMenuItem_Click(object sender, EventArgs e) { Process.Start("http://www.wiibrew.org/wiki/NUS_Downloader"); } private void databasePageToolStripMenuItem_Click(object sender, EventArgs e) { Process.Start("http://www.wiibrew.org/wiki/NUS_Downloader/database"); } private void extrasStrip_Opening(object sender, CancelEventArgs e) { // Show additional features based on held keys... #if DEBUG moreExtrasToolStripMenuItem.Visible = true; #else moreExtrasToolStripMenuItem.Visible = Control.ModifierKeys == Keys.Control; // If Ctrl Pressed. #endif } private void runFolderFixToolStripMenuItem_Click(object sender, EventArgs e) { // Run folderfix to make \titles\ // Organizing folders from past NUSD releases... BackgroundWorker folder_fixer = new BackgroundWorker(); folder_fixer.DoWork += new DoWorkEventHandler(ReorganizePreviousFolderStructure); folder_fixer.RunWorkerCompleted += new RunWorkerCompletedEventHandler(ReorganizePreviousFolderStructure_Completed); Debug.WriteLine("folderfix active"); WriteStatus("Organizing your old folder structure..."); folder_fixer.RunWorkerAsync(); } private void removeNUSDFilesFoldersToolStripMenuItem_Click(object sender, EventArgs e) { // Extras thing, remove all of NUSD files... if (MessageBox.Show("This will delete all the files\folders you have downloaded from NUS! Are you sure you want to do this?", "Wait a second!", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != System.Windows.Forms.DialogResult.Yes) return; if (Directory.Exists(Path.Combine(CURRENT_DIR, "titles"))) Directory.Delete(Path.Combine(CURRENT_DIR, "titles"), true); if (Directory.Exists(Path.Combine(CURRENT_DIR, "scripts"))) Directory.Delete(Path.Combine(CURRENT_DIR, "scripts"), true); if (File.Exists(Path.Combine(CURRENT_DIR, "database.xml"))) File.Delete(Path.Combine(CURRENT_DIR, "database.xml")); if (File.Exists(Path.Combine(CURRENT_DIR, "olddatabase.xml"))) File.Delete(Path.Combine(CURRENT_DIR, "olddatabase.xml")); if (File.Exists(Path.Combine(CURRENT_DIR, "proxy.txt"))) File.Delete(Path.Combine(CURRENT_DIR, "proxy.txt")); if (File.Exists(Path.Combine(CURRENT_DIR, "key.bin"))) File.Delete(Path.Combine(CURRENT_DIR, "key.bin")); if (File.Exists(Path.Combine(CURRENT_DIR, "kkey.bin"))) File.Delete(Path.Combine(CURRENT_DIR, "kkey.bin")); if (File.Exists(Path.Combine(CURRENT_DIR, "dsikey.bin"))) File.Delete(Path.Combine(CURRENT_DIR, "dsikey.bin")); } private void anyStrip_Closed(object sender, ToolStripDropDownClosedEventArgs e) { ((ContextMenuStrip)sender).Text = "Hidden"; //Debug.Write(((ContextMenuStrip)sender).Name); } private void localTicketInventoryToolStripMenuItem_Click(object sender, EventArgs e) { // Alters icons if tickets exist locally... WriteStatus("Adding ticket information to database entries..."); ToolStripMenuItem[] Lists = new ToolStripMenuItem[4] { SystemMenuList, IOSMenuList, VCMenuList, WiiWareMenuList }; for (int l = 0; l < Lists.Length; l++) { for (int a = 0; a < Lists[l].DropDownItems.Count; a++) { if (Lists[l].DropDownItems[a].Text.Length < 16) continue; string itemTitleId = Lists[l].DropDownItems[a].Text.Substring(0, 16); string itemDir = Path.Combine(Path.Combine(CURRENT_DIR, "titles"), itemTitleId); if (Directory.Exists(itemDir) == false) continue; string[] files = Directory.GetFiles(itemDir, "cetk", SearchOption.AllDirectories); if (files.Length > 0) { if (Lists[l].DropDownItems[a].Image == Database.green) Lists[l].DropDownItems[a].Image = Database.green_blue; if (Lists[l].DropDownItems[a].Image == Database.orange) Lists[l].DropDownItems[a].Image = Database.orange_blue; if (Lists[l].DropDownItems[a].Image == Database.redorange) Lists[l].DropDownItems[a].Image = Database.redorange_blue; if (Lists[l].DropDownItems[a].Image == Database.redgreen) Lists[l].DropDownItems[a].Image = Database.redgreen_blue; } } } WriteStatus(" - Operation completed!"); } private void donateToolStripMenuItem_Click(object sender, EventArgs e) { //TODO: Organize how this will work... Process.Start("http://wb3000.atspace.name/donations.html"); } } }