diff --git a/Boop/App.config b/Boop/App.config index 5fbd0fa..265f943 100644 --- a/Boop/App.config +++ b/Boop/App.config @@ -1,21 +1,21 @@ - + - -
+ +
- + - + 192.168.1.1 - - True + + 8080 - \ No newline at end of file + diff --git a/Boop/Boop.csproj b/Boop/Boop.csproj index 94e0895..1e30141 100644 --- a/Boop/Boop.csproj +++ b/Boop/Boop.csproj @@ -9,10 +9,11 @@ Properties Boop Boop - v4.5.2 + v4.7.2 512 true false + publish\ true Disk @@ -23,10 +24,14 @@ false false true + true 0 - 1.0.1.%2a + 2.0.0.0 false + true true + + AnyCPU @@ -51,21 +56,27 @@ app.manifest - snekicon.ico + snek2icon.ico LocalIntranet - false + true + + + BAACFA82F2A87E86CD927D07ECC4FD8AF8D0A7AB + + + Boop_TemporaryKey.pfx + + + true - - ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll - True - + @@ -76,6 +87,14 @@ + + ..\packages\EmbedIO.1.9.1\lib\net46\Unosquare.Labs.EmbedIO.dll + True + + + ..\packages\Unosquare.Swan.0.16.0\lib\net452\Unosquare.Swan.dll + True + @@ -84,8 +103,6 @@ AboutBox1.cs - - Form @@ -98,26 +115,16 @@ InfoBox.cs - - Form - - - MyIP.cs - - - + Form1.cs InfoBox.cs - - MyIP.cs - ResXFileCodeGenerator Resources.Designer.cs @@ -129,6 +136,7 @@ True + SettingsSingleFileGenerator @@ -149,6 +157,11 @@ + + + + + diff --git a/Boop/CsHTTPRequest.cs b/Boop/CsHTTPRequest.cs deleted file mode 100644 index 58a16ca..0000000 --- a/Boop/CsHTTPRequest.cs +++ /dev/null @@ -1,330 +0,0 @@ -// CsHTTPServer -// -// rmortega77@yahoo.es -// The use of this software is subject to the following agreement -// -// 1. Don't use it to kill. -// 2. Don't use to lie. -// 3. If you learned something give it back. -// 4. If you make money with it, consider sharing with the author. -// 5. If you do not complies with 1 to 5, you may not use this software. -// -// If you have money to spare, and found useful, or funny, or anything -// worth on this software, and want to contribute with future free -// software development. -// You may contact the author at rmortega77@yahoo.es -// Contributions can be from money to hardware spareparts (better), or -// a bug fix (best), or printed bibliografy, or thanks... -// just write me. - -using System; -using System.Net.Sockets; -using System.Text; -using System.Threading; -using System.Collections; -using System.Globalization; -using System.Web; - -namespace rmortega77.CsHTTPServer -{ - enum RState - { - METHOD, URL, URLPARM, URLVALUE, VERSION, - HEADERKEY, HEADERVALUE, BODY, OK - }; - - enum RespState - { - OK = 200, - BAD_REQUEST = 400, - NOT_FOUND = 404 - } - - public struct HTTPRequestStruct - { - public string Method; - public string URL; - public string Version; - public Hashtable Args; - public bool Execute; - public Hashtable Headers; - public int BodySize; - public byte[] BodyData; - } - - public struct HTTPResponseStruct - { - public int status; - public string version; - public Hashtable Headers; - public int BodySize; - public byte[] BodyData; - public System.IO.FileStream fs; - } - - /// - /// Summary description for CsHTTPRequest. - /// - public class CsHTTPRequest - { - private TcpClient client; - - private RState ParserState; - - private HTTPRequestStruct HTTPRequest; - - private HTTPResponseStruct HTTPResponse; - - byte[] myReadBuffer; - - CsHTTPServer Parent; - - public CsHTTPRequest(TcpClient client, CsHTTPServer Parent) - { - this.client = client; - this.Parent = Parent; - - this.HTTPResponse.BodySize = 0; - } - - public void Process() - { - myReadBuffer = new byte[client.ReceiveBufferSize]; - String myCompleteMessage = ""; - int numberOfBytesRead = 0; - - Parent.WriteLog("Connection accepted. Buffer: " + client.ReceiveBufferSize.ToString()); - NetworkStream ns = client.GetStream(); - - string hValue = ""; - string hKey = ""; - - try - { - // binary data buffer index - int bfndx = 0; - - // Incoming message may be larger than the buffer size. - do - { - numberOfBytesRead = ns.Read(myReadBuffer, 0, myReadBuffer.Length); - myCompleteMessage = - String.Concat(myCompleteMessage, Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead)); - - // read buffer index - int ndx = 0; - do - { - switch ( ParserState ) - { - case RState.METHOD: - if (myReadBuffer[ndx] != ' ') - HTTPRequest.Method += (char)myReadBuffer[ndx++]; - else - { - ndx++; - ParserState = RState.URL; - } - break; - case RState.URL: - if (myReadBuffer[ndx] == '?') - { - ndx++; - hKey = ""; - HTTPRequest.Execute = true; - HTTPRequest.Args = new Hashtable(); - ParserState = RState.URLPARM; - } - else if (myReadBuffer[ndx] != ' ') - HTTPRequest.URL += (char)myReadBuffer[ndx++]; - else - { - ndx++; - - HTTPRequest.URL = HttpUtility.UrlDecode(HTTPRequest.URL); - ParserState = RState.VERSION; - } - break; - case RState.URLPARM: - if (myReadBuffer[ndx] == '=') - { - ndx++; - hValue=""; - ParserState = RState.URLVALUE; - } - else if (myReadBuffer[ndx] == ' ') - { - ndx++; - - HTTPRequest.URL = HttpUtility.UrlDecode(HTTPRequest.URL); - ParserState = RState.VERSION; - } - else - { - hKey += (char)myReadBuffer[ndx++]; - } - break; - case RState.URLVALUE: - if (myReadBuffer[ndx] == '&') - { - ndx++; - hKey=HttpUtility.UrlDecode(hKey); - hValue=HttpUtility.UrlDecode(hValue); - HTTPRequest.Args[hKey] = HTTPRequest.Args[hKey] != null ? HTTPRequest.Args[hKey] + ", " + hValue : hValue; - hKey=""; - ParserState = RState.URLPARM; - } - else if (myReadBuffer[ndx] == ' ') - { - ndx++; - hKey=HttpUtility.UrlDecode(hKey); - hValue=HttpUtility.UrlDecode(hValue); - HTTPRequest.Args[hKey] = HTTPRequest.Args[hKey] != null ? HTTPRequest.Args[hKey] + ", " + hValue : hValue; - - HTTPRequest.URL = HttpUtility.UrlDecode(HTTPRequest.URL); - ParserState = RState.VERSION; - } - else - { - hValue += (char)myReadBuffer[ndx++]; - } - break; - case RState.VERSION: - if (myReadBuffer[ndx] == '\r') - ndx++; - else if (myReadBuffer[ndx] != '\n') - HTTPRequest.Version += (char)myReadBuffer[ndx++]; - else - { - ndx++; - hKey = ""; - HTTPRequest.Headers = new Hashtable(); - ParserState = RState.HEADERKEY; - } - break; - case RState.HEADERKEY: - if (myReadBuffer[ndx] == '\r') - ndx++; - else if (myReadBuffer[ndx] == '\n') - { - ndx++; - if (HTTPRequest.Headers["Content-Length"] != null) - { - HTTPRequest.BodySize = Convert.ToInt32(HTTPRequest.Headers["Content-Length"]); - this.HTTPRequest.BodyData = new byte[this.HTTPRequest.BodySize]; - ParserState = RState.BODY; - } - else - ParserState = RState.OK; - - } - else if (myReadBuffer[ndx] == ':') - ndx++; - else if (myReadBuffer[ndx] != ' ') - hKey += (char)myReadBuffer[ndx++]; - else - { - ndx++; - hValue = ""; - ParserState = RState.HEADERVALUE; - } - break; - case RState.HEADERVALUE: - if (myReadBuffer[ndx] == '\r') - ndx++; - else if (myReadBuffer[ndx] != '\n') - hValue += (char)myReadBuffer[ndx++]; - else - { - ndx++; - HTTPRequest.Headers.Add(hKey, hValue); - hKey = ""; - ParserState = RState.HEADERKEY; - } - break; - case RState.BODY: - // Append to request BodyData - Array.Copy(myReadBuffer, ndx, this.HTTPRequest.BodyData, bfndx, numberOfBytesRead - ndx); - bfndx += numberOfBytesRead - ndx; - ndx = numberOfBytesRead; - if ( this.HTTPRequest.BodySize <= bfndx) - { - ParserState = RState.OK; - } - break; - //default: - // ndx++; - // break; - - } - } - while(ndx < numberOfBytesRead); - - } - while(ns.DataAvailable); - - // Print out the received message to the console. - Parent.WriteLog("You received the following message : \n" + - myCompleteMessage); - - HTTPResponse.version = "HTTP/1.1"; - - if (ParserState != RState.OK) - HTTPResponse.status = (int)RespState.BAD_REQUEST; - else - HTTPResponse.status = (int)RespState.OK; - - this.HTTPResponse.Headers = new Hashtable(); - this.HTTPResponse.Headers.Add("Server", Parent.Name); - this.HTTPResponse.Headers.Add("Date", DateTime.Now.ToString("r")); - - // if (HTTPResponse.status == (int)RespState.OK) - this.Parent.OnResponse(ref this.HTTPRequest, ref this.HTTPResponse); - - string HeadersString = this.HTTPResponse.version + " " + this.Parent.respStatus[this.HTTPResponse.status] + "\n"; - - foreach (DictionaryEntry Header in this.HTTPResponse.Headers) - { - HeadersString += Header.Key + ": " + Header.Value + "\n"; - } - - HeadersString += "\n"; - byte[] bHeadersString = Encoding.ASCII.GetBytes(HeadersString); - - // Send headers - ns.Write(bHeadersString, 0, bHeadersString.Length); - - // Send body - if (this.HTTPResponse.BodyData != null) - ns.Write(this.HTTPResponse.BodyData, 0, this.HTTPResponse.BodyData.Length); - - if (this.HTTPResponse.fs != null) - using (this.HTTPResponse.fs) - { - byte[] b = new byte[client.SendBufferSize]; - int bytesRead; - while ((bytesRead = this.HTTPResponse.fs.Read(b,0,b.Length)) > 0) - { - ns.Write(b, 0, bytesRead); - } - - this.HTTPResponse.fs.Close(); - } - - } - catch (Exception e) - { - Parent.WriteLog(e.ToString()); - } - finally - { - ns.Close(); - client.Close(); - if (this.HTTPResponse.fs != null) - this.HTTPResponse.fs.Close(); - Thread.CurrentThread.Abort(); - } - } - - } -} diff --git a/Boop/CsHTTPServer.cs b/Boop/CsHTTPServer.cs deleted file mode 100644 index 171c29e..0000000 --- a/Boop/CsHTTPServer.cs +++ /dev/null @@ -1,149 +0,0 @@ -// CsHTTPServer -// -// rmortega77@yahoo.es -// The use of this software is subject to the following agreement -// -// 1. Don't use it to kill. -// 2. Don't use to lie. -// 3. If you learned something give it back. -// 4. If you make money with it, consider sharing with the author. -// 5. If you do not complies with 1 to 5, you may not use this software. -// -// If you have money to spare, and found useful, or funny, or anything -// worth on this software, and want to contribute with future free -// software development. -// You may contact the author at rmortega77@yahoo.es -// Contributions can be from money to hardware spareparts (better), or -// a bug fix (best), or printed bibliografy, or thanks... -// just write me. - -using System; -using System.Net.Sockets; -using System.Threading; -using System.Collections; -using System.Net; - -//using System.Text; - -namespace rmortega77.CsHTTPServer -{ - /// - /// Summary description for CsHTTPServer. - /// - public abstract class CsHTTPServer - { - private int portNum = 8080; - private TcpListener listener; - System.Threading.Thread Thread; - - public Hashtable respStatus; - - public string Name = "CsHTTPServer/1.0.*"; - - public bool IsAlive - { - get - { - return this.Thread.IsAlive; - } - } - - public CsHTTPServer() - { - // - respStatusInit(); - } - - public CsHTTPServer(int thePort) - { - portNum = thePort; - respStatusInit(); - } - - private void respStatusInit() - { - respStatus = new Hashtable(); - - respStatus.Add(200, "200 Ok"); - respStatus.Add(201, "201 Created"); - respStatus.Add(202, "202 Accepted"); - respStatus.Add(204, "204 No Content"); - - respStatus.Add(301, "301 Moved Permanently"); - respStatus.Add(302, "302 Redirection"); - respStatus.Add(304, "304 Not Modified"); - - respStatus.Add(400, "400 Bad Request"); - respStatus.Add(401, "401 Unauthorized"); - respStatus.Add(403, "403 Forbidden"); - respStatus.Add(404, "404 Not Found"); - - respStatus.Add(500, "500 Internal Server Error"); - respStatus.Add(501, "501 Not Implemented"); - respStatus.Add(502, "502 Bad Gateway"); - respStatus.Add(503, "503 Service Unavailable"); - } - - public void Listen() - { - - bool done = false; - IPAddress ipAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0]; - - //listener = new TcpListener(portNum); - listener = new TcpListener(IPAddress.Any,portNum); - - listener.Start(); - - WriteLog("Listening On: " + portNum.ToString()); - - while (!done) - { - try - { - WriteLog("Waiting for connection..."); - CsHTTPRequest newRequest = new CsHTTPRequest(listener.AcceptTcpClient(),this); - Thread Thread = new Thread(new ThreadStart(newRequest.Process)); - Thread.Name = "HTTP Request"; - Thread.Start(); - } - catch (Exception) - { - //from time to time this went boom boom. So a nice trycatch stops it. - } - } - - } - - public void WriteLog(string EventMessage) - { - Console.WriteLine(EventMessage); - } - - public void Start() - { - // CsHTTPServer HTTPServer = new CsHTTPServer(portNum); - this.Thread = new Thread(new ThreadStart(this.Listen)); - this.Thread.Start(); - } - - public void Stop() - { - listener.Stop(); - this.Thread.Abort(); - } - -/* public void Suspend() - { - this.Thread.Suspend(); - } - - public void Resume() - { - this.Thread.Resume(); - }*/ - - public abstract void OnResponse(ref HTTPRequestStruct rq, ref HTTPResponseStruct rp); - - } -} diff --git a/Boop/Form1.Designer.cs b/Boop/Form1.Designer.cs index 7fd0093..5f2aed5 100644 --- a/Boop/Form1.Designer.cs +++ b/Boop/Form1.Designer.cs @@ -28,329 +28,359 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { - this.components = new System.ComponentModel.Container(); - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); - this.lvFileList = new System.Windows.Forms.ListView(); - this.CiaFile = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.CiaName = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.CiaDesc = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.btnBoop = new System.Windows.Forms.Button(); - this.label1 = new System.Windows.Forms.Label(); - this.txt3DS = new System.Windows.Forms.TextBox(); - this.statusStrip1 = new System.Windows.Forms.StatusStrip(); - this.StatusLabel = new System.Windows.Forms.ToolStripStatusLabel(); - this.btnPickFiles = new System.Windows.Forms.Button(); - this.HomeMadeGettoDivider = new System.Windows.Forms.Label(); - this.linkWhat = new System.Windows.Forms.LinkLabel(); - this.lblIPMarker = new System.Windows.Forms.Label(); - this.lblFileMarker = new System.Windows.Forms.Label(); - this.lblUpdates = new System.Windows.Forms.LinkLabel(); - this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); - this.btnInfo = new System.Windows.Forms.Button(); - this.btnGithub = new System.Windows.Forms.Button(); - this.chkGuess = new System.Windows.Forms.CheckBox(); - this.btnAbout = new System.Windows.Forms.PictureBox(); - this.lblImageVersion = new System.Windows.Forms.Label(); - this.cboLocalIP = new System.Windows.Forms.ComboBox(); - this.label2 = new System.Windows.Forms.Label(); - this.label3 = new System.Windows.Forms.Label(); - this.lblPCIP = new System.Windows.Forms.LinkLabel(); - this.statusStrip1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.btnAbout)).BeginInit(); - this.SuspendLayout(); - // - // lvFileList - // - this.lvFileList.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); + this.lvFileList = new System.Windows.Forms.ListView(); + this.CiaFile = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.CiaName = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.CiaDesc = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.btnBoop = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.txtConsole = new System.Windows.Forms.TextBox(); + this.statusStrip1 = new System.Windows.Forms.StatusStrip(); + this.StatusLabel = new System.Windows.Forms.ToolStripStatusLabel(); + this.btnPickFiles = new System.Windows.Forms.Button(); + this.HomeMadeGettoDivider = new System.Windows.Forms.Label(); + this.linkWhat = new System.Windows.Forms.LinkLabel(); + this.lblIPMarker = new System.Windows.Forms.Label(); + this.lblFileMarker = new System.Windows.Forms.Label(); + this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.btnInfo = new System.Windows.Forms.Button(); + this.btnGithub = new System.Windows.Forms.Button(); + this.lblImageVersion = new System.Windows.Forms.Label(); + this.cboLocalIP = new System.Windows.Forms.ComboBox(); + this.label2 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.lblPCIP = new System.Windows.Forms.LinkLabel(); + this.label4 = new System.Windows.Forms.Label(); + this.txtPort = new System.Windows.Forms.TextBox(); + this.lblPortMarker = new System.Windows.Forms.Label(); + this.linkLabel1 = new System.Windows.Forms.LinkLabel(); + this.picSplash = new System.Windows.Forms.PictureBox(); + this.lblMode = new System.Windows.Forms.Label(); + this.statusStrip1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.picSplash)).BeginInit(); + this.SuspendLayout(); + // + // lvFileList + // + this.lvFileList.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { this.CiaFile, this.CiaName, this.CiaDesc}); - this.lvFileList.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lvFileList.FullRowSelect = true; - this.lvFileList.GridLines = true; - this.lvFileList.Location = new System.Drawing.Point(12, 309); - this.lvFileList.Name = "lvFileList"; - this.lvFileList.Size = new System.Drawing.Size(350, 198); - this.lvFileList.TabIndex = 1; - this.lvFileList.UseCompatibleStateImageBehavior = false; - this.lvFileList.View = System.Windows.Forms.View.Details; - this.lvFileList.SelectedIndexChanged += new System.EventHandler(this.lvFileList_SelectedIndexChanged); - // - // CiaFile - // - this.CiaFile.Text = "File"; - this.CiaFile.Width = 150; - // - // CiaName - // - this.CiaName.Text = "Name"; - this.CiaName.Width = 150; - // - // CiaDesc - // - this.CiaDesc.Text = "Description"; - this.CiaDesc.Width = 300; - // - // btnBoop - // - this.btnBoop.Font = new System.Drawing.Font("Segoe UI", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnBoop.Location = new System.Drawing.Point(12, 513); - this.btnBoop.Name = "btnBoop"; - this.btnBoop.Size = new System.Drawing.Size(350, 42); - this.btnBoop.TabIndex = 2; - this.btnBoop.Text = "BOOP"; - this.btnBoop.UseVisualStyleBackColor = true; - this.btnBoop.Click += new System.EventHandler(this.btnBoop_Click); - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label1.Location = new System.Drawing.Point(12, 243); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(103, 17); - this.label1.TabIndex = 5; - this.label1.Text = "3DS IP address: "; - // - // txt3DS - // - this.txt3DS.Enabled = false; - this.txt3DS.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.txt3DS.Location = new System.Drawing.Point(116, 240); - this.txt3DS.MaxLength = 15; - this.txt3DS.Name = "txt3DS"; - this.txt3DS.Size = new System.Drawing.Size(104, 25); - this.txt3DS.TabIndex = 6; - this.txt3DS.Text = "192.168.1.1"; - this.txt3DS.TextChanged += new System.EventHandler(this.txt3DS_TextChanged); - this.txt3DS.Leave += new System.EventHandler(this.txt3DS_Leave); - // - // statusStrip1 - // - this.statusStrip1.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.lvFileList.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lvFileList.FullRowSelect = true; + this.lvFileList.GridLines = true; + this.lvFileList.Location = new System.Drawing.Point(12, 328); + this.lvFileList.Name = "lvFileList"; + this.lvFileList.Size = new System.Drawing.Size(350, 179); + this.lvFileList.TabIndex = 1; + this.lvFileList.UseCompatibleStateImageBehavior = false; + this.lvFileList.View = System.Windows.Forms.View.Details; + this.lvFileList.SelectedIndexChanged += new System.EventHandler(this.lvFileList_SelectedIndexChanged); + // + // CiaFile + // + this.CiaFile.Text = "File"; + this.CiaFile.Width = 150; + // + // CiaName + // + this.CiaName.Text = "Name"; + this.CiaName.Width = 150; + // + // CiaDesc + // + this.CiaDesc.Text = "Description"; + this.CiaDesc.Width = 300; + // + // btnBoop + // + this.btnBoop.Font = new System.Drawing.Font("Segoe UI", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btnBoop.Location = new System.Drawing.Point(12, 513); + this.btnBoop.Name = "btnBoop"; + this.btnBoop.Size = new System.Drawing.Size(350, 42); + this.btnBoop.TabIndex = 2; + this.btnBoop.Text = "BOOP"; + this.btnBoop.UseVisualStyleBackColor = true; + this.btnBoop.Click += new System.EventHandler(this.btnBoop_Click); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label1.Location = new System.Drawing.Point(12, 259); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(127, 17); + this.label1.TabIndex = 5; + this.label1.Text = "Console IP address: "; + // + // txtConsole + // + this.txtConsole.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.txtConsole.Location = new System.Drawing.Point(144, 256); + this.txtConsole.MaxLength = 15; + this.txtConsole.Name = "txtConsole"; + this.txtConsole.Size = new System.Drawing.Size(104, 25); + this.txtConsole.TabIndex = 6; + this.txtConsole.Text = "192.168.1.1"; + this.txtConsole.TextChanged += new System.EventHandler(this.txt3DS_TextChanged); + this.txtConsole.Leave += new System.EventHandler(this.txt3DS_Leave); + // + // statusStrip1 + // + this.statusStrip1.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.StatusLabel}); - this.statusStrip1.Location = new System.Drawing.Point(0, 561); - this.statusStrip1.Name = "statusStrip1"; - this.statusStrip1.Size = new System.Drawing.Size(373, 22); - this.statusStrip1.TabIndex = 7; - this.statusStrip1.Text = "statusStrip1"; - // - // StatusLabel - // - this.StatusLabel.Name = "StatusLabel"; - this.StatusLabel.Size = new System.Drawing.Size(44, 17); - this.StatusLabel.Text = "Ready"; - // - // btnPickFiles - // - this.btnPickFiles.AutoSize = true; - this.btnPickFiles.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.btnPickFiles.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.btnPickFiles.Location = new System.Drawing.Point(12, 273); - this.btnPickFiles.Name = "btnPickFiles"; - this.btnPickFiles.Size = new System.Drawing.Size(350, 30); - this.btnPickFiles.TabIndex = 0; - this.btnPickFiles.Text = "Pick files"; - this.btnPickFiles.UseVisualStyleBackColor = true; - this.btnPickFiles.Click += new System.EventHandler(this.btnPickFiles_Click); - // - // HomeMadeGettoDivider - // - this.HomeMadeGettoDivider.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; - this.HomeMadeGettoDivider.Location = new System.Drawing.Point(12, 268); - this.HomeMadeGettoDivider.Name = "HomeMadeGettoDivider"; - this.HomeMadeGettoDivider.Size = new System.Drawing.Size(352, 2); - this.HomeMadeGettoDivider.TabIndex = 12; - this.HomeMadeGettoDivider.Text = "label2"; - // - // linkWhat - // - this.linkWhat.AutoSize = true; - this.linkWhat.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.linkWhat.Location = new System.Drawing.Point(226, 243); - this.linkWhat.Name = "linkWhat"; - this.linkWhat.Size = new System.Drawing.Size(127, 17); - this.linkWhat.TabIndex = 13; - this.linkWhat.TabStop = true; - this.linkWhat.Text = "Where is my 3DS IP?"; - this.linkWhat.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkWhat_LinkClicked); - // - // lblIPMarker - // - this.lblIPMarker.BackColor = System.Drawing.Color.Red; - this.lblIPMarker.Location = new System.Drawing.Point(115, 239); - this.lblIPMarker.Name = "lblIPMarker"; - this.lblIPMarker.Size = new System.Drawing.Size(106, 27); - this.lblIPMarker.TabIndex = 14; - this.lblIPMarker.Visible = false; - // - // lblFileMarker - // - this.lblFileMarker.BackColor = System.Drawing.Color.Red; - this.lblFileMarker.Location = new System.Drawing.Point(11, 272); - this.lblFileMarker.Name = "lblFileMarker"; - this.lblFileMarker.Size = new System.Drawing.Size(352, 32); - this.lblFileMarker.TabIndex = 15; - this.lblFileMarker.Visible = false; - // - // lblUpdates - // - this.lblUpdates.AutoSize = true; - this.lblUpdates.Enabled = false; - this.lblUpdates.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lblUpdates.Location = new System.Drawing.Point(12, 7); - this.lblUpdates.Name = "lblUpdates"; - this.lblUpdates.Size = new System.Drawing.Size(132, 17); - this.lblUpdates.TabIndex = 16; - this.lblUpdates.TabStop = true; - this.lblUpdates.Text = "No updates available"; - this.lblUpdates.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.lblUpdates_LinkClicked); - // - // btnInfo - // - this.btnInfo.AutoSize = true; - this.btnInfo.Image = global::Boop.Properties.Resources.info; - this.btnInfo.Location = new System.Drawing.Point(295, 2); - this.btnInfo.Name = "btnInfo"; - this.btnInfo.Size = new System.Drawing.Size(29, 29); - this.btnInfo.TabIndex = 11; - this.toolTip1.SetToolTip(this.btnInfo, "About Boop"); - this.btnInfo.UseVisualStyleBackColor = true; - this.btnInfo.Click += new System.EventHandler(this.btnInfo_Click); - // - // btnGithub - // - this.btnGithub.AutoSize = true; - this.btnGithub.Image = global::Boop.Properties.Resources.github; - this.btnGithub.Location = new System.Drawing.Point(330, 2); - this.btnGithub.Name = "btnGithub"; - this.btnGithub.Size = new System.Drawing.Size(29, 29); - this.btnGithub.TabIndex = 10; - this.toolTip1.SetToolTip(this.btnGithub, "Fork us on GitHub"); - this.btnGithub.UseVisualStyleBackColor = true; - this.btnGithub.Click += new System.EventHandler(this.btnGithub_Click); - // - // chkGuess - // - this.chkGuess.AutoSize = true; - this.chkGuess.Checked = true; - this.chkGuess.CheckState = System.Windows.Forms.CheckState.Checked; - this.chkGuess.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.chkGuess.Location = new System.Drawing.Point(12, 218); - this.chkGuess.Name = "chkGuess"; - this.chkGuess.Size = new System.Drawing.Size(210, 21); - this.chkGuess.TabIndex = 17; - this.chkGuess.Text = "Magically guess 3DS IP adress?"; - this.chkGuess.UseVisualStyleBackColor = true; - this.chkGuess.CheckedChanged += new System.EventHandler(this.chkGuess_CheckedChanged); - // - // btnAbout - // - this.btnAbout.Image = global::Boop.Properties.Resources.Boop1; - this.btnAbout.Location = new System.Drawing.Point(12, 34); - this.btnAbout.Name = "btnAbout"; - this.btnAbout.Size = new System.Drawing.Size(350, 150); - this.btnAbout.TabIndex = 4; - this.btnAbout.TabStop = false; - // - // lblImageVersion - // - this.lblImageVersion.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(72)))), ((int)(((byte)(187)))), ((int)(((byte)(255))))); - this.lblImageVersion.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lblImageVersion.ForeColor = System.Drawing.Color.White; - this.lblImageVersion.ImageAlign = System.Drawing.ContentAlignment.BottomRight; - this.lblImageVersion.Location = new System.Drawing.Point(201, 149); - this.lblImageVersion.Name = "lblImageVersion"; - this.lblImageVersion.Size = new System.Drawing.Size(160, 34); - this.lblImageVersion.TabIndex = 18; - this.lblImageVersion.Text = "0.0.0"; - this.lblImageVersion.TextAlign = System.Drawing.ContentAlignment.BottomRight; - // - // cboLocalIP - // - this.cboLocalIP.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.cboLocalIP.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.cboLocalIP.FormattingEnabled = true; - this.cboLocalIP.Items.AddRange(new object[] { + this.statusStrip1.Location = new System.Drawing.Point(0, 561); + this.statusStrip1.Name = "statusStrip1"; + this.statusStrip1.Size = new System.Drawing.Size(373, 22); + this.statusStrip1.TabIndex = 7; + this.statusStrip1.Text = "statusStrip1"; + // + // StatusLabel + // + this.StatusLabel.Name = "StatusLabel"; + this.StatusLabel.Size = new System.Drawing.Size(44, 17); + this.StatusLabel.Text = "Ready"; + // + // btnPickFiles + // + this.btnPickFiles.AutoSize = true; + this.btnPickFiles.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btnPickFiles.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.btnPickFiles.Location = new System.Drawing.Point(12, 292); + this.btnPickFiles.Name = "btnPickFiles"; + this.btnPickFiles.Size = new System.Drawing.Size(350, 30); + this.btnPickFiles.TabIndex = 0; + this.btnPickFiles.Text = "Pick files"; + this.btnPickFiles.UseVisualStyleBackColor = true; + this.btnPickFiles.Click += new System.EventHandler(this.btnPickFiles_Click); + // + // HomeMadeGettoDivider + // + this.HomeMadeGettoDivider.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; + this.HomeMadeGettoDivider.Location = new System.Drawing.Point(12, 287); + this.HomeMadeGettoDivider.Name = "HomeMadeGettoDivider"; + this.HomeMadeGettoDivider.Size = new System.Drawing.Size(352, 2); + this.HomeMadeGettoDivider.TabIndex = 12; + this.HomeMadeGettoDivider.Text = "label2"; + // + // linkWhat + // + this.linkWhat.AutoSize = true; + this.linkWhat.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.linkWhat.Location = new System.Drawing.Point(259, 259); + this.linkWhat.Name = "linkWhat"; + this.linkWhat.Size = new System.Drawing.Size(110, 17); + this.linkWhat.TabIndex = 13; + this.linkWhat.TabStop = true; + this.linkWhat.Text = "What is an my IP?"; + this.linkWhat.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkWhat_LinkClicked); + // + // lblIPMarker + // + this.lblIPMarker.BackColor = System.Drawing.Color.Red; + this.lblIPMarker.Location = new System.Drawing.Point(143, 255); + this.lblIPMarker.Name = "lblIPMarker"; + this.lblIPMarker.Size = new System.Drawing.Size(106, 27); + this.lblIPMarker.TabIndex = 14; + this.lblIPMarker.Visible = false; + // + // lblFileMarker + // + this.lblFileMarker.BackColor = System.Drawing.Color.Red; + this.lblFileMarker.Location = new System.Drawing.Point(11, 291); + this.lblFileMarker.Name = "lblFileMarker"; + this.lblFileMarker.Size = new System.Drawing.Size(352, 32); + this.lblFileMarker.TabIndex = 15; + this.lblFileMarker.Visible = false; + // + // btnInfo + // + this.btnInfo.AutoSize = true; + this.btnInfo.Image = global::Boop.Properties.Resources.info; + this.btnInfo.Location = new System.Drawing.Point(295, 2); + this.btnInfo.Name = "btnInfo"; + this.btnInfo.Size = new System.Drawing.Size(29, 29); + this.btnInfo.TabIndex = 11; + this.toolTip1.SetToolTip(this.btnInfo, "About Boop"); + this.btnInfo.UseVisualStyleBackColor = true; + this.btnInfo.Click += new System.EventHandler(this.btnInfo_Click); + // + // btnGithub + // + this.btnGithub.AutoSize = true; + this.btnGithub.Image = global::Boop.Properties.Resources.github; + this.btnGithub.Location = new System.Drawing.Point(330, 2); + this.btnGithub.Name = "btnGithub"; + this.btnGithub.Size = new System.Drawing.Size(29, 29); + this.btnGithub.TabIndex = 10; + this.toolTip1.SetToolTip(this.btnGithub, "Fork us on GitHub"); + this.btnGithub.UseVisualStyleBackColor = true; + this.btnGithub.Click += new System.EventHandler(this.btnGithub_Click); + // + // lblImageVersion + // + this.lblImageVersion.BackColor = System.Drawing.Color.Transparent; + this.lblImageVersion.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblImageVersion.ForeColor = System.Drawing.Color.White; + this.lblImageVersion.ImageAlign = System.Drawing.ContentAlignment.BottomRight; + this.lblImageVersion.Location = new System.Drawing.Point(201, 149); + this.lblImageVersion.Name = "lblImageVersion"; + this.lblImageVersion.Size = new System.Drawing.Size(160, 34); + this.lblImageVersion.TabIndex = 18; + this.lblImageVersion.Text = "0.0.0"; + this.lblImageVersion.TextAlign = System.Drawing.ContentAlignment.BottomRight; + // + // cboLocalIP + // + this.cboLocalIP.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cboLocalIP.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.cboLocalIP.FormattingEnabled = true; + this.cboLocalIP.Items.AddRange(new object[] { "666.666.666.666"}); - this.cboLocalIP.Location = new System.Drawing.Point(144, 188); - this.cboLocalIP.Name = "cboLocalIP"; - this.cboLocalIP.Size = new System.Drawing.Size(125, 25); - this.cboLocalIP.TabIndex = 19; - this.cboLocalIP.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged); - // - // label2 - // - this.label2.AutoSize = true; - this.label2.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label2.Location = new System.Drawing.Point(11, 191); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(131, 17); - this.label2.TabIndex = 20; - this.label2.Text = "Computer IP Adress: "; - // - // label3 - // - this.label3.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; - this.label3.Location = new System.Drawing.Point(12, 216); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(352, 2); - this.label3.TabIndex = 21; - this.label3.Text = "label2"; - // - // lblPCIP - // - this.lblPCIP.AutoEllipsis = true; - this.lblPCIP.AutoSize = true; - this.lblPCIP.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lblPCIP.Location = new System.Drawing.Point(273, 191); - this.lblPCIP.Name = "lblPCIP"; - this.lblPCIP.Size = new System.Drawing.Size(86, 17); - this.lblPCIP.TabIndex = 22; - this.lblPCIP.TabStop = true; - this.lblPCIP.Text = "Computer IP?"; - this.lblPCIP.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.lblPCIP_LinkClicked); - // - // Form1 - // - this.AllowDrop = true; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(373, 583); - this.Controls.Add(this.lblPCIP); - this.Controls.Add(this.label3); - this.Controls.Add(this.label2); - this.Controls.Add(this.cboLocalIP); - this.Controls.Add(this.lblImageVersion); - this.Controls.Add(this.chkGuess); - this.Controls.Add(this.lblUpdates); - this.Controls.Add(this.linkWhat); - this.Controls.Add(this.HomeMadeGettoDivider); - this.Controls.Add(this.btnInfo); - this.Controls.Add(this.btnGithub); - this.Controls.Add(this.statusStrip1); - this.Controls.Add(this.txt3DS); - this.Controls.Add(this.label1); - this.Controls.Add(this.btnAbout); - this.Controls.Add(this.btnBoop); - this.Controls.Add(this.lvFileList); - this.Controls.Add(this.btnPickFiles); - this.Controls.Add(this.lblIPMarker); - this.Controls.Add(this.lblFileMarker); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.MaximizeBox = false; - this.Name = "Form1"; - this.Text = "Boop 1.2.0"; - this.Load += new System.EventHandler(this.Form1_Load); - this.DragDrop += new System.Windows.Forms.DragEventHandler(this.Form1_DragDrop); - this.DragEnter += new System.Windows.Forms.DragEventHandler(this.Form1_DragEnter); - this.statusStrip1.ResumeLayout(false); - this.statusStrip1.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.btnAbout)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); + this.cboLocalIP.Location = new System.Drawing.Point(144, 188); + this.cboLocalIP.Name = "cboLocalIP"; + this.cboLocalIP.Size = new System.Drawing.Size(125, 25); + this.cboLocalIP.TabIndex = 19; + this.cboLocalIP.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label2.Location = new System.Drawing.Point(12, 191); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(131, 17); + this.label2.TabIndex = 20; + this.label2.Text = "Computer IP Adress: "; + // + // label3 + // + this.label3.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; + this.label3.Location = new System.Drawing.Point(15, 250); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(352, 2); + this.label3.TabIndex = 21; + this.label3.Text = "label2"; + // + // lblPCIP + // + this.lblPCIP.AutoEllipsis = true; + this.lblPCIP.AutoSize = true; + this.lblPCIP.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblPCIP.Location = new System.Drawing.Point(277, 191); + this.lblPCIP.Name = "lblPCIP"; + this.lblPCIP.Size = new System.Drawing.Size(86, 17); + this.lblPCIP.TabIndex = 22; + this.lblPCIP.TabStop = true; + this.lblPCIP.Text = "Computer IP?"; + this.lblPCIP.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.lblPCIP_LinkClicked); + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label4.Location = new System.Drawing.Point(12, 222); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(101, 17); + this.label4.TabIndex = 23; + this.label4.Text = "Computer Port: "; + // + // txtPort + // + this.txtPort.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.txtPort.Location = new System.Drawing.Point(144, 219); + this.txtPort.MaxLength = 15; + this.txtPort.Name = "txtPort"; + this.txtPort.Size = new System.Drawing.Size(44, 25); + this.txtPort.TabIndex = 24; + this.txtPort.Text = "8080"; + this.txtPort.TextChanged += new System.EventHandler(this.txtPort_TextChanged); + // + // lblPortMarker + // + this.lblPortMarker.BackColor = System.Drawing.Color.Red; + this.lblPortMarker.Location = new System.Drawing.Point(143, 218); + this.lblPortMarker.Name = "lblPortMarker"; + this.lblPortMarker.Size = new System.Drawing.Size(46, 27); + this.lblPortMarker.TabIndex = 25; + this.lblPortMarker.Visible = false; + // + // linkLabel1 + // + this.linkLabel1.AutoEllipsis = true; + this.linkLabel1.AutoSize = true; + this.linkLabel1.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.linkLabel1.Location = new System.Drawing.Point(194, 222); + this.linkLabel1.Name = "linkLabel1"; + this.linkLabel1.Size = new System.Drawing.Size(169, 17); + this.linkLabel1.TabIndex = 26; + this.linkLabel1.TabStop = true; + this.linkLabel1.Text = "and now Port? What is this?"; + this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked); + // + // picSplash + // + this.picSplash.Image = ((System.Drawing.Image)(resources.GetObject("picSplash.Image"))); + this.picSplash.Location = new System.Drawing.Point(12, 34); + this.picSplash.Name = "picSplash"; + this.picSplash.Size = new System.Drawing.Size(350, 150); + this.picSplash.TabIndex = 4; + this.picSplash.TabStop = false; + // + // lblMode + // + this.lblMode.AutoSize = true; + this.lblMode.Font = new System.Drawing.Font("Segoe UI", 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblMode.Location = new System.Drawing.Point(12, 2); + this.lblMode.Name = "lblMode"; + this.lblMode.Size = new System.Drawing.Size(0, 30); + this.lblMode.TabIndex = 27; + // + // Form1 + // + this.AllowDrop = true; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(373, 583); + this.Controls.Add(this.lblMode); + this.Controls.Add(this.linkLabel1); + this.Controls.Add(this.txtPort); + this.Controls.Add(this.lblPortMarker); + this.Controls.Add(this.label4); + this.Controls.Add(this.lblPCIP); + this.Controls.Add(this.label3); + this.Controls.Add(this.label2); + this.Controls.Add(this.cboLocalIP); + this.Controls.Add(this.lblImageVersion); + this.Controls.Add(this.linkWhat); + this.Controls.Add(this.HomeMadeGettoDivider); + this.Controls.Add(this.btnInfo); + this.Controls.Add(this.btnGithub); + this.Controls.Add(this.statusStrip1); + this.Controls.Add(this.txtConsole); + this.Controls.Add(this.label1); + this.Controls.Add(this.picSplash); + this.Controls.Add(this.btnBoop); + this.Controls.Add(this.lvFileList); + this.Controls.Add(this.btnPickFiles); + this.Controls.Add(this.lblIPMarker); + this.Controls.Add(this.lblFileMarker); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MaximizeBox = false; + this.Name = "Form1"; + this.Text = "Boop 1.2.0"; + this.Load += new System.EventHandler(this.Form1_Load); + this.DragDrop += new System.Windows.Forms.DragEventHandler(this.Form1_DragDrop); + this.DragEnter += new System.Windows.Forms.DragEventHandler(this.Form1_DragEnter); + this.statusStrip1.ResumeLayout(false); + this.statusStrip1.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.picSplash)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); } @@ -359,9 +389,9 @@ private void InitializeComponent() private System.Windows.Forms.Button btnPickFiles; private System.Windows.Forms.ListView lvFileList; private System.Windows.Forms.Button btnBoop; - private System.Windows.Forms.PictureBox btnAbout; + private System.Windows.Forms.PictureBox picSplash; private System.Windows.Forms.Label label1; - private System.Windows.Forms.TextBox txt3DS; + private System.Windows.Forms.TextBox txtConsole; private System.Windows.Forms.ColumnHeader CiaFile; private System.Windows.Forms.StatusStrip statusStrip1; private System.Windows.Forms.ToolStripStatusLabel StatusLabel; @@ -371,9 +401,7 @@ private void InitializeComponent() private System.Windows.Forms.LinkLabel linkWhat; private System.Windows.Forms.Label lblIPMarker; private System.Windows.Forms.Label lblFileMarker; - private System.Windows.Forms.LinkLabel lblUpdates; private System.Windows.Forms.ToolTip toolTip1; - private System.Windows.Forms.CheckBox chkGuess; private System.Windows.Forms.ColumnHeader CiaName; private System.Windows.Forms.ColumnHeader CiaDesc; private System.Windows.Forms.Label lblImageVersion; @@ -381,6 +409,11 @@ private void InitializeComponent() private System.Windows.Forms.Label label2; private System.Windows.Forms.Label label3; private System.Windows.Forms.LinkLabel lblPCIP; - } + private System.Windows.Forms.Label label4; + private System.Windows.Forms.TextBox txtPort; + private System.Windows.Forms.Label lblPortMarker; + private System.Windows.Forms.LinkLabel linkLabel1; + private System.Windows.Forms.Label lblMode; + } } diff --git a/Boop/Form1.cs b/Boop/Form1.cs index 5a19e91..e61fa04 100644 --- a/Boop/Form1.cs +++ b/Boop/Form1.cs @@ -10,457 +10,522 @@ using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Windows.Forms; -using rmortega77.CsHTTPServer; +using Unosquare.Labs.EmbedIO; +using Unosquare.Labs.EmbedIO.Modules; +using System.Threading; namespace Boop { - public partial class Form1 : Form - { - CsHTTPServer HTTPServer; - Socket s; //Socket to tell FBI where the server is - string[] FilesToBoop; //Files to be boop'd - string ActiveDir; //Used to mount the server - UpdateChecker UC; // Update checker. - - public Form1() - { - InitializeComponent(); - - Application.ApplicationExit += new EventHandler(this.OnApplicationExit); - - //Drag and drop support - string[] args = Environment.GetCommandLineArgs(); - if (args != null && args.Length > 0) //If drag and drop - { - List Boops = new List(); //Initialize a temporal list. - foreach (string arg in args) - { - if (System.IO.File.Exists(arg)) //Is it a file? - { - if (Path.GetExtension(arg) == ".cia" || Path.GetExtension(arg) == ".tik") //Is it a supported file? - { - Boops.Add(arg); //Add it. - } - } - } - if (Boops.Count > 0) //If we had any supported file - { - FilesToBoop = Boops.ToArray(); //Set them - ProcessFilenames(); //Add them to the list. - } - } - - } - - /// - /// Used as a task to not freeze the thread. (I am not really good with asyncs, maybe there are better ways to do this) - /// - private void CheckForUpdates() - { - UC = new UpdateChecker(); - try - { - if (UC.CheckForUpdates()) - { - this.Invoke((MethodInvoker)delegate - { - lblUpdates.Enabled = true; - lblUpdates.Text = "New version found!"; - }); - } - else - { - this.Invoke((MethodInvoker)delegate - { - lblUpdates.Enabled = false; - lblUpdates.Text = "No updates available"; - }); - } - } - catch (Exception) //Most likely, internet connection is down. - { - this.Invoke((MethodInvoker)delegate - { - lblUpdates.Enabled = false; - lblUpdates.Text = "Error contacting update server"; - }); - } - } - - - private void OnApplicationExit(object sender, EventArgs e) - { - //Individual trycatches to make sure everything is off before leaving. - try - { - HTTPServer.Stop(); - } - catch { } - - try - { - s.Close(); - } - catch { } - - } - - private void btnPickFiles_Click(object sender, EventArgs e) - { - // Create an instance of the open file dialog box. - lblFileMarker.Visible = false; - OpenFileDialog OFD = new OpenFileDialog(); - - // Set filter options and filter index. - OFD.Filter = "FBI compatible files (*.cia, *.tik)|*.cia;*.tik"; - //This doesn't really enforce .cia and .tik but it makes it really hard to open other kind of file. - //Should we enforce it? - - OFD.FilterIndex = 0; - - OFD.Multiselect = true; - - bool? userClickedOK = (OFD.ShowDialog() == DialogResult.OK); - - - // Process input if the user clicked OK. - if (userClickedOK == true) - { - if (OFD.FileNames.Length > 0) { - lvFileList.Items.Clear(); - FilesToBoop = OFD.FileNames; - ProcessFilenames(); // I splited this button in order to reuse the code for the drag and drop support. - } - - } - } - - /// - /// Processes The Files - /// - private void ProcessFilenames() - { - ActiveDir = (Path.GetDirectoryName(FilesToBoop[0])); - - foreach (string item in FilesToBoop) - { - if (ActiveDir == Path.GetDirectoryName(item)) - { - if (Path.GetExtension(item) == ".cia") - { - byte[] desc = new Byte[256]; - - byte[] tit = new Byte[128]; - - using (BinaryReader b = new BinaryReader(File.Open(item, FileMode.Open))) - { - b.BaseStream.Seek(-14016 + 520, SeekOrigin.End); - tit = b.ReadBytes(128); - - b.BaseStream.Seek(-14016 + 520 + 128, SeekOrigin.End); - desc = b.ReadBytes(256); - } - - string[] tmp = new string[3]; - tmp[0] = Path.GetFileName(item); - tmp[1] = Encoding.Unicode.GetString(tit).Trim(); - tmp[2] = Encoding.Unicode.GetString(desc).Trim(); - - - - lvFileList.Items.Add(new ListViewItem(tmp)); - } - else - { - lvFileList.Items.Add(Path.GetFileName(item)); - } - - } - else - { - MessageBox.Show("You picked 2 files that are NOT in the same directory" + Environment.NewLine + "Cross-Directory booping would need the entire computer hosted to the network and that doesn't feel safe in my book." + Environment.NewLine + "Maybe in the future I'll find a way to do this.", "Woah there...", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - - } - } - - private void btnBoop_Click(object sender, EventArgs e) - { - //Try catch will go away in the future. Left in case somebody still has trouble with the server. - - if (NetUtil.IPv4.iIPIndex == -1) - { - MessageBox.Show("Your computer is not connected to a network!" + Environment.NewLine + "If you connected your computer after opening Boop, please restart Boop", "No local network detected", MessageBoxButtons.OK, MessageBoxIcon.Error); - //Added red boxes to point out the errors. - return; - } - - - try - { - //#endif - - //Fastest check first. - if (lvFileList.Items.Count == 0) - { - MessageBox.Show("Add some files first?", "No files to boop", MessageBoxButtons.OK, MessageBoxIcon.Error); - lblFileMarker.Visible = true; //Added red boxes to point out the errors. - return; - } - - - string s3DSip = ""; - if (chkGuess.Checked) - { - setStatusLabel("Guessing 3DS IP adress..."); - s3DSip = NetUtil.IPv4.GetFirst3DS(); - if (s3DSip == "") - { - MessageBox.Show("Cannot detect the 3DS in the network" + Environment.NewLine + "Try writing the IP adress manually", "Connection failed", MessageBoxButtons.OK, MessageBoxIcon.Error); - lblIPMarker.Visible = true; //Added red boxes to point out the errors. - setStatusLabel("Ready"); - return; - } - - } - else - { - if (NetUtil.IPv4.Validate(txt3DS.Text) == false) - { - MessageBox.Show("That doesn't look like an IP address." + Environment.NewLine + "An IP address looks something like this: 192.168.1.6" + Environment.NewLine + "(That is: Numbers DOT numbers DOT numbers DOT numbers)", "Error on the IP address", MessageBoxButtons.OK, MessageBoxIcon.Error); - lblIPMarker.Visible = true; //Added red boxes to point out the errors. - setStatusLabel("Ready"); - return; - } - - s3DSip = txt3DS.Text; - } - - // THE FIREWALL IS NO LONGER POKED! - // THE SNEK IS FREE FROM THE HTTPLISTENER TIRANY! - - setStatusLabel("Opening the new and improved snek server..."); - enableControls(false); - - HTTPServer = new MyServer(8080, ActiveDir); - HTTPServer.Start(); - - - System.Threading.Thread.Sleep(100); - - setStatusLabel("Opening socket to send the file list..."); - - s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - - IAsyncResult result = s.BeginConnect(s3DSip, 5000, null, null); - result.AsyncWaitHandle.WaitOne(5000, true); - - if (!s.Connected) - { - s.Close(); - HTTPServer.Stop(); - MessageBox.Show("Failed to connect to 3DS"+Environment.NewLine+"Please check:"+Environment.NewLine+ "Did you write the right IP adress?" +Environment.NewLine + "Is FBI open and listening?", "Connection failed", MessageBoxButtons.OK, MessageBoxIcon.Error); - lblIPMarker.Visible = true; - setStatusLabel("Ready"); - enableControls(true); - return; - } - - setStatusLabel("Sending the file list..."); - - String message = ""; - - foreach (var CIA in FilesToBoop) - { - message += NetUtil.IPv4.Local + ":8080/" + System.Web.HttpUtility.UrlEncode(Path.GetFileName(CIA)) + "\n"; - //message += NetUtil.IPv4.Local + ":8080/" + Uri.EscapeUriString(Path.GetFileName(CIA)) + "\n"; - } - - //boop the info to the 3ds... - byte[] Largo = BitConverter.GetBytes((uint)Encoding.ASCII.GetBytes(message).Length); - byte[] Adress = Encoding.ASCII.GetBytes(message); - - Array.Reverse(Largo); //Endian fix - - s.Send(AppendTwoByteArrays(Largo, Adress)); - - setStatusLabel("Booping files... Please wait"); - s.BeginReceive(new byte[1], 0,1, 0, new AsyncCallback(GotData), null); //Call me back when the 3ds says something. - -//#if DEBUG - } - catch (Exception ex) - { - //Hopefully, some day we can have all the different exceptions handled... One can dream, right? *-* - MessageBox.Show("Something went really wrong: " + Environment.NewLine + Environment.NewLine + "\"" + ex.Message + "\"" + Environment.NewLine + Environment.NewLine + "If this keeps happening, please take a screenshot of this message and post it on our github." + Environment.NewLine + Environment.NewLine + "The program will close now","Error!",MessageBoxButtons.OK,MessageBoxIcon.Error); - Application.Exit(); - } -//#endif - } - - private void GotData(IAsyncResult ar) - { - - // now we unlock the controls... - //Spooky "thread safe" way to access UI from ASYNC. - this.Invoke((MethodInvoker)delegate - { - enableControls(true); - setStatusLabel("Booping complete!"); - MessageBox.Show("Booping complete!", "Yay!", MessageBoxButtons.OK, MessageBoxIcon.Information); - }); - - s.Close(); - HTTPServer.Stop(); - } - - static byte[] AppendTwoByteArrays(byte[] arrayA, byte[] arrayB) //Aux function to append the 2 byte arrays. - { - byte[] outputBytes = new byte[arrayA.Length + arrayB.Length]; - Buffer.BlockCopy(arrayA, 0, outputBytes, 0, arrayA.Length); - Buffer.BlockCopy(arrayB, 0, outputBytes, arrayA.Length, arrayB.Length); - return outputBytes; - } - - private void Form1_Load(object sender, EventArgs e) - { - cboLocalIP.DataSource = Dns.GetHostEntry(Dns.GetHostName()).AddressList.DefaultIfEmpty(IPAddress.Loopback).Where(ip => ip.AddressFamily == AddressFamily.InterNetwork).Select(ip => ip.ToString()).ToArray(); - - lblImageVersion.Text = UpdateChecker.GetCurrentVersion(); - this.Text = "Boop " + UpdateChecker.GetCurrentVersion(); - new Task(CheckForUpdates).Start(); //Async check for updates - txt3DS.Text = Properties.Settings.Default["saved3DSIP"].ToString(); - chkGuess.Checked = (bool) Properties.Settings.Default["bGuess"]; - txt3DS.Enabled = !chkGuess.Checked; - } - - private void Form1_DragEnter(object sender, DragEventArgs e) - { - if (e.Data.GetDataPresent(DataFormats.FileDrop)) - { - e.Effect = DragDropEffects.Copy; - } - else - { - e.Effect = DragDropEffects.None; - } - } - - - private void Form1_DragDrop(object sender, DragEventArgs e) - { - if (e.Data.GetDataPresent(DataFormats.FileDrop)) - { - - List Boops = new List(); //Initialize a temporal list. - - string[] filePaths = (string[])(e.Data.GetData(DataFormats.FileDrop)); - foreach (string arg in filePaths) - { - - if (System.IO.File.Exists(arg)) //Is it a file? - { - if (Path.GetExtension(arg) == ".cia" || Path.GetExtension(arg) == ".tik") //Is it a supported file? - { - Boops.Add(arg); //Add it. - } - } - - } - - if (Boops.Count > 0) //If we had any supported file - { - lvFileList.Items.Clear(); - FilesToBoop = Boops.ToArray(); //Set them - ProcessFilenames(); //Add them to the list. - } - - } - } - - private void enableControls(bool enabled) - { - btnBoop.Enabled = enabled; - btnPickFiles.Enabled = enabled; - chkGuess.Enabled = enabled; - if (chkGuess.Checked) txt3DS.Enabled = false; else txt3DS.Enabled = enabled; - btnAbout.Enabled = enabled; - } - - private void setStatusLabel(String text) - { - StatusLabel.Text = text; - //Force-update text to appear. If we still crash from #9 we should get where it crashed. - statusStrip1.Invalidate(); - statusStrip1.Refresh(); - } - - private String saveIPAddress(String newIPAddress) - { - newIPAddress = newIPAddress.Trim(); - if (NetUtil.IPv4.Validate(newIPAddress)) - { - Properties.Settings.Default["saved3DSIP"] = newIPAddress; - Properties.Settings.Default.Save(); - } - return newIPAddress; - } - - private void txt3DS_Leave(object sender, EventArgs e) - { - txt3DS.Text = saveIPAddress(txt3DS.Text); - } - - private void txt3DS_TextChanged(object sender, EventArgs e) - { - saveIPAddress(txt3DS.Text); - lblIPMarker.Visible = false; - } - - private void linkWhat_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) //Added help picture to find IP adress. - { - MyIP frmIP = new MyIP(); - frmIP.ShowDialog(); - } - - private void btnGithub_Click(object sender, EventArgs e) //New cooler github button - { - Process.Start(@"https://github.com/miltoncandelero/Boop"); - } - - private void lblUpdates_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) //Go to update page - { - Process.Start(UC.sUrl); - } - - private void btnInfo_Click(object sender, EventArgs e) //New super cool snek about form - { - InfoBox frmInfo = new InfoBox(); - frmInfo.ShowDialog(); - } - - private void chkGuess_CheckedChanged(object sender, EventArgs e) - { - txt3DS.Enabled = !chkGuess.Checked; - Properties.Settings.Default["bGuess"] = chkGuess.Checked; - Properties.Settings.Default.Save(); - } - - private void lvFileList_SelectedIndexChanged(object sender, EventArgs e) - { - //Pls no touching the snek list. - lvFileList.SelectedIndices.Clear(); - } - - private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) - { - NetUtil.IPv4.iIPIndex = cboLocalIP.SelectedIndex; - } - - private void lblPCIP_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) - { - MessageBox.Show("Although the server opens for ALL networks, we need to send only ONE IP address to your 3DS." +Environment.NewLine+ "The program used to pick the first IP and most of the times it grabbed the correct one... and sometimes failed miserably." + Environment.NewLine + "If you are connected to more than one network make sure your IP adress is right.", "Do you even network bro?", MessageBoxButtons.OK, MessageBoxIcon.Information); - } - } + public partial class Form1 : Form + { + const string SWITCH = "Switch"; + const string N3DS = "3DS"; + const string NONE = "none"; + + Task task; + CancellationTokenSource cts; + WebServer newHTTPServer; + Socket s; //Socket to tell FBI where the server is + string[] FilesToBoop; //Files to be boop'd + string ActiveDir; //Used to mount the server + string _consolemode = "none"; + string ConsoleMode + { + get + { + return _consolemode; + } + set + { + if (value == SWITCH) + { + _consolemode = SWITCH; + picSplash.Image = Properties.Resources._switch; + lblMode.Text = "NINTENDO SWITCH MODE"; + lblMode.ForeColor = System.Drawing.Color.FromArgb(0xe60012); + + //Do other changes. + } + else if (value.ToUpper() == N3DS) + { + _consolemode = N3DS; + picSplash.Image = Properties.Resources._3ds; + lblMode.Text = "NINTENDO 3DS MODE"; + lblMode.ForeColor = System.Drawing.Color.FromArgb(0x48bbff); + + //Do other changes. + } + else + { + _consolemode = NONE; + picSplash.Image = Properties.Resources.generic; + lblMode.Text = ""; + //reset the UI. + } + } + } + + public Form1() + { + InitializeComponent(); + + var pos = this.PointToScreen(lblImageVersion.Location); + pos = picSplash.PointToClient(pos); + lblImageVersion.Parent = picSplash; + lblImageVersion.Location = pos; + + Application.ApplicationExit += new EventHandler(this.OnApplicationExit); + + //Drag and drop support + string[] args = Environment.GetCommandLineArgs(); + if (args != null && args.Length > 0) //If drag and drop + { + List Boops = new List(); //Initialize a temporal list. + foreach (string arg in args) + { + if (System.IO.File.Exists(arg)) //Is it a file? + { + if (Path.GetExtension(arg) == ".cia" || Path.GetExtension(arg) == ".tik" || Path.GetExtension(arg) == ".nsp") //Is it a supported file? + { + Boops.Add(arg); //Add it. + } + } + } + if (Boops.Count > 0) //If we had any supported file + { + FilesToBoop = Boops.ToArray(); //Set them + ProcessFilenames(); //Add them to the list. + } + } + + } + + + private void OnApplicationExit(object sender, EventArgs e) + { + //Individual trycatches to make sure everything is off before leaving. + try + { + //Stop the webServer + cts.Cancel(); + //task.Wait(); + newHTTPServer.Dispose(); + } + catch { } + + try + { + s.Close(); + } + catch { } + + } + + private void btnPickFiles_Click(object sender, EventArgs e) + { + // Create an instance of the open file dialog box. + lblFileMarker.Visible = false; + OpenFileDialog OFD = new OpenFileDialog(); + + // Set filter options and filter index. + OFD.Filter = "Boop compatible files (*.nsp, *.cia, *.tik)|*.nsp;*.cia;*.tik|Tinfoil compatible files (*.nsp)|*.nsp|FBI compatible files (*.cia, *.tik)|*.cia;*.tik"; + + OFD.FilterIndex = 0; + + OFD.Multiselect = true; + + bool? userClickedOK = (OFD.ShowDialog() == DialogResult.OK); + + + // Process input if the user clicked OK. + if (userClickedOK == true) + { + if (OFD.FileNames.Length > 0) + { + lvFileList.Items.Clear(); + FilesToBoop = OFD.FileNames; + ProcessFilenames(); // I splited this button in order to reuse the code for the drag and drop support. + } + + } + } + + /// + /// Processes The Files + /// + private void ProcessFilenames() + { + ConsoleMode = NONE; //FREE FOR ALL! + + ActiveDir = (Path.GetDirectoryName(FilesToBoop[0])); + + foreach (string item in FilesToBoop) + { + if (ActiveDir == Path.GetDirectoryName(item)) + { + if (ConsoleMode == NONE) + { + //GUEEEESS THE TYYYPE! + if (Path.GetExtension(item) == ".cia" || Path.GetExtension(item) == ".tik") ConsoleMode = N3DS; + if (Path.GetExtension(item) == ".nsp") ConsoleMode = SWITCH; + } + + + if (ConsoleMode == N3DS) + { + if (Path.GetExtension(item) == ".cia") + { + byte[] desc = new Byte[256]; + + byte[] tit = new Byte[128]; + + using (BinaryReader b = new BinaryReader(File.Open(item, FileMode.Open))) + { + b.BaseStream.Seek(-14016 + 520, SeekOrigin.End); + tit = b.ReadBytes(128); + + b.BaseStream.Seek(-14016 + 520 + 128, SeekOrigin.End); + desc = b.ReadBytes(256); + } + + string[] tmp = new string[3]; + tmp[0] = Path.GetFileName(item); + tmp[1] = Encoding.Unicode.GetString(tit).Trim(); + tmp[2] = Encoding.Unicode.GetString(desc).Trim(); + + + + lvFileList.Items.Add(new ListViewItem(tmp)); + } + else if (Path.GetExtension(item) == ".tik") + { + lvFileList.Items.Add(Path.GetFileName(item)); + } + } + else if (ConsoleMode == SWITCH) + { + if (Path.GetExtension(item) == ".nsp") + { + lvFileList.Items.Add(Path.GetFileName(item)); + //try to get the filename and description! + /* + string[] tmp = new string[3]; + tmp[0] = Path.GetFileName(item); + tmp[1] = Encoding.Unicode.GetString(tit).Trim(); + tmp[2] = Encoding.Unicode.GetString(desc).Trim(); + */ + } + } + } + else + { + MessageBox.Show("You picked 2 files that are NOT in the same directory" + Environment.NewLine + "Cross-Directory booping would need the entire computer hosted to the network and that doesn't feel safe in my book." + Environment.NewLine + "Maybe in the future I'll find a way to do this.", "Woah there...", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + } + } + + private void btnBoop_Click(object sender, EventArgs e) + { + //Try catch will go away in the future. Left in case somebody still has trouble with the server. + + //Reset all red markers. + lblFileMarker.Visible = false; + lblIPMarker.Visible = false; + lblPortMarker.Visible = false; + + if (NetUtil.IPv4.iIPIndex == -1) + { + MessageBox.Show("Your computer is not connected to a network!" + Environment.NewLine + "If you connected your computer after opening Boop, please restart Boop", "No local network detected", MessageBoxButtons.OK, MessageBoxIcon.Error); + //Added red boxes to point out the errors. + return; + } + + try + { + //#endif + + //Fastest check first. + if (lvFileList.Items.Count == 0) + { + MessageBox.Show("Add some files first?", "No files to boop", MessageBoxButtons.OK, MessageBoxIcon.Error); + lblFileMarker.Visible = true; //Added red boxes to point out the errors. + return; + } + + if (NetUtil.IPv4.ValidatePort(txtPort.Text) == false) + { + MessageBox.Show("That doesn't look like an port." + Environment.NewLine + "A port looks something like this: 8080", "Error on the Port number", MessageBoxButtons.OK, MessageBoxIcon.Error); + lblPortMarker.Visible = true; //Added red boxes to point out the errors. + setStatusLabel("Ready"); + return; + } + + if (NetUtil.IPv4.Validate(txtConsole.Text) == false) + { + MessageBox.Show("That doesn't look like an IP address." + Environment.NewLine + "An IP address looks something like this: 192.168.1.6" + Environment.NewLine + "(That is: Numbers DOT numbers DOT numbers DOT numbers)", "Error on the IP address", MessageBoxButtons.OK, MessageBoxIcon.Error); + lblIPMarker.Visible = true; //Added red boxes to point out the errors. + setStatusLabel("Ready"); + return; + } + + string sConsoleIP = txtConsole.Text; + int iLocalPort = int.Parse(txtPort.Text); + + int iConsolePort = 5000; + + if (ConsoleMode == SWITCH) iConsolePort = 2000; + if (ConsoleMode == N3DS) iConsolePort = 5000; + + if (NetUtil.IPv4.PortInUse(iLocalPort) || iLocalPort == iConsolePort) + { + MessageBox.Show("That port is already in use." + Environment.NewLine + "", "Error on the Port number", MessageBoxButtons.OK, MessageBoxIcon.Error); + lblPortMarker.Visible = true; //Added red boxes to point out the errors. + setStatusLabel("Ready"); + return; + } + + + setStatusLabel("Opening the new and improved snek server..."); + enableControls(false); + + newHTTPServer = WebServer + .Create("http://"+ NetUtil.IPv4.Local + ":"+iLocalPort+"/") + .WithStaticFolderAt(ActiveDir); + + cts = new CancellationTokenSource(); + task = newHTTPServer.RunAsync(cts.Token); + + Thread.Sleep(100); + + setStatusLabel("Opening socket to send the file list..."); + + s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + + IAsyncResult result = s.BeginConnect(sConsoleIP, iConsolePort, null, null); + + result.AsyncWaitHandle.WaitOne(5000, true); + + if (!s.Connected) + { + s.Close(); + + //Stop the webServer + cts.Cancel(); + //task.Wait(); + newHTTPServer.Dispose(); + + MessageBox.Show("Failed to connect to Console", "Connection failed", MessageBoxButtons.OK, MessageBoxIcon.Error); + lblIPMarker.Visible = true; + setStatusLabel("Ready"); + enableControls(true); + return; + } + + setStatusLabel("Sending the file list..."); + + String message = ""; + + foreach (var file in FilesToBoop) + { + message += NetUtil.IPv4.Local + ":"+txtPort.Text+"/" + Uri.EscapeDataString(Path.GetFileName(file)) + "\n"; + } + + //boop the info to the console... + byte[] Largo = BitConverter.GetBytes((uint)Encoding.ASCII.GetBytes(message).Length); + byte[] Adress = Encoding.ASCII.GetBytes(message); + + Array.Reverse(Largo); //Endian fix + + s.Send(AppendTwoByteArrays(Largo, Adress)); + + setStatusLabel("Booping files... Please wait"); + s.BeginReceive(new byte[1], 0, 1, 0, new AsyncCallback(GotData), null); //Call me back when the 3ds says something. + + //#if DEBUG + } + catch (Exception ex) + { + //Hopefully, some day we can have all the different exceptions handled... One can dream, right? *-* + MessageBox.Show("Something went really wrong: " + Environment.NewLine + Environment.NewLine + "\"" + ex.Message + "\"" + Environment.NewLine + Environment.NewLine + "If this keeps happening, please take a screenshot of this message and post it on our github." + Environment.NewLine + Environment.NewLine + "The program will close now", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error); + Application.Exit(); + } + //#endif + } + + private void GotData(IAsyncResult ar) + { + + // now we unlock the controls... + //Spooky "thread safe" way to access UI from ASYNC. + this.Invoke((MethodInvoker)delegate + { + enableControls(true); + setStatusLabel("Booping complete!"); + System.Media.SystemSounds.Beep.Play(); //beep boop son. + //No more annoy message. + //MessageBox.Show("Booping complete!", "Yay!", MessageBoxButtons.OK, MessageBoxIcon.Information); + }); + + s.Close(); + //Stop the webServer + cts.Cancel(); + //task.Wait(); + newHTTPServer.Dispose(); + } + + static byte[] AppendTwoByteArrays(byte[] arrayA, byte[] arrayB) //Aux function to append the 2 byte arrays. + { + byte[] outputBytes = new byte[arrayA.Length + arrayB.Length]; + Buffer.BlockCopy(arrayA, 0, outputBytes, 0, arrayA.Length); + Buffer.BlockCopy(arrayB, 0, outputBytes, arrayA.Length, arrayB.Length); + return outputBytes; + } + + private void Form1_Load(object sender, EventArgs e) + { + cboLocalIP.DataSource = Dns.GetHostEntry(Dns.GetHostName()).AddressList.DefaultIfEmpty(IPAddress.Loopback).Where(ip => ip.AddressFamily == AddressFamily.InterNetwork).Select(ip => ip.ToString()).ToArray(); + + lblImageVersion.Text = Utils.GetCurrentVersion(); + this.Text = "Boop " + Utils.GetCurrentVersion(); + txtConsole.Text = NetUtil.IPv4.GetFirstNintendoIP() == "" ? Properties.Settings.Default["savedIP"].ToString() : NetUtil.IPv4.GetFirstNintendoIP(); + txtPort.Text = Properties.Settings.Default["savedPort"].ToString(); + } + + private void Form1_DragEnter(object sender, DragEventArgs e) + { + if (e.Data.GetDataPresent(DataFormats.FileDrop)) + { + e.Effect = DragDropEffects.Copy; + } + else + { + e.Effect = DragDropEffects.None; + } + } + + + private void Form1_DragDrop(object sender, DragEventArgs e) + { + if (e.Data.GetDataPresent(DataFormats.FileDrop)) + { + + List Boops = new List(); //Initialize a temporal list. + + string[] filePaths = (string[])(e.Data.GetData(DataFormats.FileDrop)); + foreach (string arg in filePaths) + { + + if (System.IO.File.Exists(arg)) //Is it a file? + { + if (Path.GetExtension(arg) == ".cia" || Path.GetExtension(arg) == ".tik") //Is it a supported file? + { + Boops.Add(arg); //Add it. + } + } + + } + + if (Boops.Count > 0) //If we had any supported file + { + lvFileList.Items.Clear(); + FilesToBoop = Boops.ToArray(); //Set them + ProcessFilenames(); //Add them to the list. + } + + } + } + + private void enableControls(bool enabled) + { + btnBoop.Enabled = enabled; + btnPickFiles.Enabled = enabled; + picSplash.Enabled = enabled; + } + + private void setStatusLabel(String text) + { + StatusLabel.Text = text; + //Force-update text to appear. If we still crash from #9 we should get where it crashed. + statusStrip1.Invalidate(); + statusStrip1.Refresh(); + } + + private String saveIPAddress(String newIPAddress) + { + newIPAddress = newIPAddress.Trim(); + if (NetUtil.IPv4.Validate(newIPAddress)) + { + Properties.Settings.Default["savedIP"] = newIPAddress; + Properties.Settings.Default.Save(); + } + return newIPAddress; + } + + private string savePortNumber(String newPortNumber) + { + newPortNumber = newPortNumber.Trim(); + if (NetUtil.IPv4.ValidatePort(newPortNumber)) + { + Properties.Settings.Default["savedPort"] = newPortNumber; + Properties.Settings.Default.Save(); + } + return newPortNumber; + } + + private void txt3DS_Leave(object sender, EventArgs e) + { + txtConsole.Text = saveIPAddress(txtConsole.Text); + } + + private void txt3DS_TextChanged(object sender, EventArgs e) + { + saveIPAddress(txtConsole.Text); + lblIPMarker.Visible = false; + } + + private void txtPort_TextChanged(object sender, EventArgs e) + { + savePortNumber(txtPort.Text); + lblPortMarker.Visible = false; + } + + private void linkWhat_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) //Added help picture to find IP adress. + { + MessageBox.Show("An Internet Protocol address (IP address) is a numerical label assigned to each device connected to a computer network that uses the Internet Protocol for communication." + Environment.NewLine + "You are probably wondering 'What does it look like?'" + Environment.NewLine + "It looks like X.X.X.X where your replace each X for a number between 1 and 255." + Environment.NewLine + "Get your console on the 'Remote Install' screen and it should tell you it's IP adress somewhere.", "Explaining is hard", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + private void btnGithub_Click(object sender, EventArgs e) //New cooler github button + { + Process.Start(@"https://github.com/miltoncandelero/Boop"); + } + + private void btnInfo_Click(object sender, EventArgs e) //New super cool snek about form + { + InfoBox frmInfo = new InfoBox(); + frmInfo.ShowDialog(); + } + + private void lvFileList_SelectedIndexChanged(object sender, EventArgs e) + { + //Pls no touching the snek list. + lvFileList.SelectedIndices.Clear(); + } + + private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) + { + NetUtil.IPv4.iIPIndex = cboLocalIP.SelectedIndex; + } + + private void lblPCIP_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + MessageBox.Show("To open the server for ALL networks I needed admin access and since we have to send the console only ONE adress I decieded to open the server only on that adress." + Environment.NewLine + "The picks the first IP and most of the times it grabs the correct one... and sometimes fails miserably." + Environment.NewLine + "If you are connected to more than one network make sure your IP adress is right.", "Do you even network bro?", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + MessageBox.Show("Pick a port that you know to be empty on your computer." + Environment.NewLine + "Some good examples are 8080, 8008 and 591", "Do you even network bro?", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } } diff --git a/Boop/Form1.resx b/Boop/Form1.resx index 7b05f46..02c394a 100644 --- a/Boop/Form1.resx +++ b/Boop/Form1.resx @@ -123,10 +123,644 @@ 133, 17 + + + + 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 + AAAAAElFTkSuQmCC + + 63 - AAABAAYAEBAAAAAAIABoBAAAZgAAACAgAAAAACAAqBAAAM4EAAAwMAAAAAAgAKglAAB2FQAAQEAAAAAA diff --git a/Boop/InfoBox.Designer.cs b/Boop/InfoBox.Designer.cs index 4c18ce8..ae0c823 100644 --- a/Boop/InfoBox.Designer.cs +++ b/Boop/InfoBox.Designer.cs @@ -27,121 +27,79 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { - this.lvContributors = new System.Windows.Forms.ListView(); - this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.groupBox1 = new System.Windows.Forms.GroupBox(); - this.lblTitle = new System.Windows.Forms.Label(); - this.label1 = new System.Windows.Forms.Label(); - this.lblSnekFriendly = new System.Windows.Forms.Label(); - this.pictureBox1 = new System.Windows.Forms.PictureBox(); - this.groupBox1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); - this.SuspendLayout(); - // - // lvContributors - // - this.lvContributors.BackColor = System.Drawing.SystemColors.Control; - this.lvContributors.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.lvContributors.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.columnHeader1}); - this.lvContributors.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lvContributors.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None; - this.lvContributors.HideSelection = false; - this.lvContributors.Location = new System.Drawing.Point(6, 19); - this.lvContributors.Name = "lvContributors"; - this.lvContributors.Size = new System.Drawing.Size(271, 153); - this.lvContributors.TabIndex = 3; - this.lvContributors.UseCompatibleStateImageBehavior = false; - this.lvContributors.View = System.Windows.Forms.View.Details; - this.lvContributors.ColumnWidthChanging += new System.Windows.Forms.ColumnWidthChangingEventHandler(this.lvContributors_ColumnWidthChanging); - this.lvContributors.SelectedIndexChanged += new System.EventHandler(this.lvContributors_SelectedIndexChanged); - // - // columnHeader1 - // - this.columnHeader1.Text = "Shout out to all the friends of the snek:"; - this.columnHeader1.Width = 264; - // - // groupBox1 - // - this.groupBox1.Controls.Add(this.lvContributors); - this.groupBox1.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.groupBox1.Location = new System.Drawing.Point(12, 141); - this.groupBox1.Name = "groupBox1"; - this.groupBox1.Size = new System.Drawing.Size(283, 178); - this.groupBox1.TabIndex = 4; - this.groupBox1.TabStop = false; - this.groupBox1.Text = "Shout out to all the friends of the snek:"; - // - // lblTitle - // - this.lblTitle.AutoSize = true; - this.lblTitle.Font = new System.Drawing.Font("Segoe UI", 18F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lblTitle.Location = new System.Drawing.Point(153, 21); - this.lblTitle.Name = "lblTitle"; - this.lblTitle.Size = new System.Drawing.Size(75, 32); - this.lblTitle.TabIndex = 6; - this.lblTitle.Text = "Boop"; - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label1.Location = new System.Drawing.Point(224, 40); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(41, 17); - this.label1.TabIndex = 7; - this.label1.Text = "v1.2.0"; - // - // lblSnekFriendly - // - this.lblSnekFriendly.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lblSnekFriendly.Location = new System.Drawing.Point(132, 57); - this.lblSnekFriendly.Name = "lblSnekFriendly"; - this.lblSnekFriendly.Size = new System.Drawing.Size(163, 67); - this.lblSnekFriendly.TabIndex = 8; - this.lblSnekFriendly.Text = "Boop, the snek friendly network file transfer for FBI 3DS."; - // - // pictureBox1 - // - this.pictureBox1.Image = global::Boop.Properties.Resources.snekicon1; - this.pictureBox1.Location = new System.Drawing.Point(12, 12); - this.pictureBox1.Name = "pictureBox1"; - this.pictureBox1.Size = new System.Drawing.Size(114, 112); - this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; - this.pictureBox1.TabIndex = 5; - this.pictureBox1.TabStop = false; - // - // InfoBox - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(307, 332); - this.Controls.Add(this.lblSnekFriendly); - this.Controls.Add(this.label1); - this.Controls.Add(this.lblTitle); - this.Controls.Add(this.pictureBox1); - this.Controls.Add(this.groupBox1); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "InfoBox"; - this.Padding = new System.Windows.Forms.Padding(9); - this.ShowIcon = false; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "About Boop 1.2.0"; - this.Load += new System.EventHandler(this.InfoBox_Load); - this.groupBox1.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); + this.lblTitle = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.lblSnekFriendly = new System.Windows.Forms.Label(); + this.pictureBox1 = new System.Windows.Forms.PictureBox(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + this.SuspendLayout(); + // + // lblTitle + // + this.lblTitle.AutoSize = true; + this.lblTitle.Font = new System.Drawing.Font("Segoe UI", 18F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblTitle.Location = new System.Drawing.Point(153, 5); + this.lblTitle.Name = "lblTitle"; + this.lblTitle.Size = new System.Drawing.Size(75, 32); + this.lblTitle.TabIndex = 6; + this.lblTitle.Text = "Boop"; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label1.Location = new System.Drawing.Point(224, 24); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(41, 17); + this.label1.TabIndex = 7; + this.label1.Text = "v1.2.0"; + // + // lblSnekFriendly + // + this.lblSnekFriendly.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblSnekFriendly.Location = new System.Drawing.Point(132, 41); + this.lblSnekFriendly.Name = "lblSnekFriendly"; + this.lblSnekFriendly.Size = new System.Drawing.Size(163, 83); + this.lblSnekFriendly.TabIndex = 8; + this.lblSnekFriendly.Text = "Boop, the snek friendly network file transfer for Tinfoil (Switch) and FBI (3DS)." + + ""; + // + // pictureBox1 + // + this.pictureBox1.Image = global::Boop.Properties.Resources.snek2icon; + this.pictureBox1.Location = new System.Drawing.Point(12, 12); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new System.Drawing.Size(114, 112); + this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.pictureBox1.TabIndex = 5; + this.pictureBox1.TabStop = false; + // + // InfoBox + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(307, 134); + this.Controls.Add(this.lblSnekFriendly); + this.Controls.Add(this.label1); + this.Controls.Add(this.lblTitle); + this.Controls.Add(this.pictureBox1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "InfoBox"; + this.Padding = new System.Windows.Forms.Padding(9); + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "About Boop 1.2.0"; + this.Load += new System.EventHandler(this.InfoBox_Load); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); } #endregion - private System.Windows.Forms.ListView lvContributors; - private System.Windows.Forms.ColumnHeader columnHeader1; - private System.Windows.Forms.GroupBox groupBox1; private System.Windows.Forms.PictureBox pictureBox1; private System.Windows.Forms.Label lblTitle; private System.Windows.Forms.Label label1; diff --git a/Boop/InfoBox.cs b/Boop/InfoBox.cs index e7b7ee2..1da0fe9 100644 --- a/Boop/InfoBox.cs +++ b/Boop/InfoBox.cs @@ -1,5 +1,4 @@ -using Newtonsoft.Json.Linq; -using System; +using System; using System.Drawing; using System.IO; using System.Net; @@ -19,68 +18,8 @@ public InfoBox() private void InfoBox_Load(object sender, EventArgs e) { - this.Text = "Boop " + UpdateChecker.GetCurrentVersion(); - label1.Text = UpdateChecker.GetCurrentVersion(); - new Task(LoadContributors).Start(); + this.Text = "Boop " + Utils.GetCurrentVersion(); + label1.Text = Utils.GetCurrentVersion(); } - - private void LoadContributors() - { - try - { - HttpWebRequest HttpRequestObj = (HttpWebRequest)HttpWebRequest.Create(@"https://api.github.com/repos/miltoncandelero/Boop/contributors"); - HttpRequestObj.Credentials = CredentialCache.DefaultCredentials; - HttpRequestObj.ContentType = "application/json"; - HttpRequestObj.Method = "GET"; - HttpRequestObj.Accept = "application/json"; - HttpRequestObj.UserAgent = "Boop"; // NEEDS SOMETHING WRITTEN! - HttpWebResponse response = (HttpWebResponse)HttpRequestObj.GetResponse(); - string content = new StreamReader(response.GetResponseStream()).ReadToEnd(); - - - JArray a = JArray.Parse(content); - - - this.Invoke((MethodInvoker)delegate - { - lvContributors.Items.Clear(); - foreach (JObject o in a.Children()) - { - lvContributors.Items.Add((string)o["login"]); - } - }); - - } - catch (Exception) - { - this.Invoke((MethodInvoker)delegate - { - //shrink all - this.Height = 174; - }); - } - - } - - private void lvContributors_ColumnWidthChanging(object sender, ColumnWidthChangingEventArgs e) - { - //Keep the width not changed. - e.NewWidth = ((ListView)sender).Columns[e.ColumnIndex].Width; - //Cancel the event. - e.Cancel = true; - } - - private void lvContributors_SelectedIndexChanged(object sender, EventArgs e) - { - //Pls no touching the snek list. - lvContributors.SelectedIndices.Clear(); - } - - private void lvContributors_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e) - { - e.Graphics.FillRectangle(Brushes.Red, e.Bounds); - e.DrawText(); - } - } } diff --git a/Boop/MyIP.Designer.cs b/Boop/MyIP.Designer.cs deleted file mode 100644 index 3b46100..0000000 --- a/Boop/MyIP.Designer.cs +++ /dev/null @@ -1,81 +0,0 @@ -namespace Boop -{ - partial class MyIP - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.label1 = new System.Windows.Forms.Label(); - this.pictureBox1 = new System.Windows.Forms.PictureBox(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); - this.SuspendLayout(); - // - // label1 - // - this.label1.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label1.Location = new System.Drawing.Point(12, 366); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(411, 21); - this.label1.TabIndex = 1; - this.label1.Text = "Your IP is that numeric thingy"; - this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - // - // pictureBox1 - // - this.pictureBox1.Image = global::Boop.Properties.Resources.IP; - this.pictureBox1.Location = new System.Drawing.Point(12, 12); - this.pictureBox1.Name = "pictureBox1"; - this.pictureBox1.Size = new System.Drawing.Size(411, 351); - this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; - this.pictureBox1.TabIndex = 2; - this.pictureBox1.TabStop = false; - // - // MyIP - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(435, 389); - this.Controls.Add(this.pictureBox1); - this.Controls.Add(this.label1); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "MyIP"; - this.Padding = new System.Windows.Forms.Padding(9); - this.ShowIcon = false; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Where is my IP?"; - this.Load += new System.EventHandler(this.MyIP_Load); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); - this.ResumeLayout(false); - - } - - #endregion - private System.Windows.Forms.Label label1; - private System.Windows.Forms.PictureBox pictureBox1; - } -} diff --git a/Boop/MyIP.cs b/Boop/MyIP.cs deleted file mode 100644 index 3ef707f..0000000 --- a/Boop/MyIP.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Drawing; -using System.Linq; -using System.Reflection; -using System.Threading.Tasks; -using System.Windows.Forms; - -namespace Boop -{ - partial class MyIP : Form - { - public MyIP() - { - InitializeComponent(); - } - - private void MyIP_Load(object sender, EventArgs e) - { - - } - } -} diff --git a/Boop/MyIP.resx b/Boop/MyIP.resx deleted file mode 100644 index 1af7de1..0000000 --- a/Boop/MyIP.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/Boop/MyServer.cs b/Boop/MyServer.cs deleted file mode 100644 index 6b8a799..0000000 --- a/Boop/MyServer.cs +++ /dev/null @@ -1,113 +0,0 @@ -// CsHTTPServer -// -// rmortega77@yahoo.es -// The use of this software is subject to the following agreement -// -// 1. Don't use it to kill. -// 2. Don't use to lie. -// 3. If you learned something give it back. -// 4. If you make money with it, consider sharing with the author. -// 5. If you do not complies with 1 to 5, you may not use this software. -// -// If you have money to spare, and found useful, or funny, or anything -// worth on this software, and want to contribute with future free -// software development. -// You may contact the author at rmortega77@yahoo.es -// Contributions can be from money to hardware spareparts (better), or -// a bug fix (best), or printed bibliografy, or thanks... -// just write me. - - -//I owe this guy ^ a beer. - -using System; -using System.Text; - -using System.IO; -using System.Web; - -using Microsoft.Win32; - - -namespace rmortega77.CsHTTPServer -{ - /// - /// Summary description for MyServer. - /// - public class MyServer : CsHTTPServer - { - public string Folder; - - public MyServer(): base() - { - this.Folder = "c:\\www"; - } - - public MyServer(int thePort, string theFolder): base(thePort) - { - this.Folder = theFolder; - } - - public override void OnResponse(ref HTTPRequestStruct rq, ref HTTPResponseStruct rp) - { - string path = this.Folder + rq.URL.Replace("/",@"\"); - - //path = HttpUtility.UrlDecode(path); WOT?? - //path = path.Replace("%20", " "); - - - if (Directory.Exists(path)) - { - if (File.Exists(path + "default.htm")) - path += "\\default.htm"; - else - { - string[] dirs = Directory.GetDirectories(path); - string[] files = Directory.GetFiles(path); - - string bodyStr = "\n"; - bodyStr += "\n"; - bodyStr += "\n"; - bodyStr += "\n"; - bodyStr += "

Folder listing, to do not see this add a 'default.htm' document\n

\n"; - for ( int i = 0; i[" + Path.GetFileName( dirs[i] ) + "]\n"; - for ( int i = 0; i" + Path.GetFileName( files[i] ) + "\n"; - bodyStr += "\n"; - - rp.BodyData = Encoding.ASCII.GetBytes(bodyStr); - return; - } - } - - if (File.Exists(path)) - { - //RegistryKey rk = Registry.ClassesRoot.OpenSubKey(Path.GetExtension(path), true); - - // Get the data from a specified item in the key. - - FileStream input = new FileStream(path, FileMode.Open); - // Open the stream and read it back. - rp.Headers["Content-type"] = "application / octet - stream"; - rp.Headers["Content-Length"] = input.Length.ToString(); - rp.fs = input; - } - else - { - - rp.status = (int)RespState.NOT_FOUND; - - string bodyStr = "\n"; - bodyStr += "\n"; - bodyStr += "\n"; - bodyStr += "\n"; - bodyStr += "File not found!!\n"; - - rp.BodyData = Encoding.ASCII.GetBytes(bodyStr); - - } - - } - } -} diff --git a/Boop/NetUtil.cs b/Boop/NetUtil.cs index 6186dd3..93e3366 100644 --- a/Boop/NetUtil.cs +++ b/Boop/NetUtil.cs @@ -11,94 +11,126 @@ namespace Boop { - namespace NetUtil - { - class IPv4 - { - - public static int iIPIndex = -1; - //Known Nintendo Mac adresses - public static readonly List Nontendo = new List { "E84ECE", "E0E751", "E00C7F", "D86BF7", "CCFB65", "CC9E00", "B8AE6E", "A4C0E1", "A45C27", "9CE635", "98B6E9", "8CCDE8", "8C56C5", "7CBB8A", "78A2A0", "58BDA3", "40F407", "40D28A", "34AF2C", "2C10C1", "182A7B", "002709", "002659", "0025A0", "0024F3", "002444", "00241E", "0023CC", "002331", "0022D7", "0022AA", "00224C", "0021BD", "002147", "001FC5", "001F32", "001EA9", "001E35", "001DBC", "001CBE", "001BEA", "001B7A", "001AE9", "0019FD", "00191D", "0017AB", "001656", "0009BF" }; - - - - ///

- /// Dups the result of arp -a into a list of a really neat struct. - /// Not the cleanest way but it works for me. - /// - static List GetAllMacAddressesAndIppairs() - { - List mip = new List(); - System.Diagnostics.Process pProcess = new System.Diagnostics.Process(); - pProcess.StartInfo.FileName = "arp"; - pProcess.StartInfo.Arguments = "-a "; - pProcess.StartInfo.UseShellExecute = false; - pProcess.StartInfo.RedirectStandardOutput = true; - pProcess.StartInfo.CreateNoWindow = true; - pProcess.Start(); - string cmdOutput = pProcess.StandardOutput.ReadToEnd(); - string pattern = @"(?([0-9]{1,3}\.?){4})\s*(?([a-f0-9]{2}-?){6})"; - - foreach (Match m in Regex.Matches(cmdOutput, pattern, RegexOptions.IgnoreCase)) - { - mip.Add(new MacIpPair() - { - MacAddress = m.Groups["mac"].Value, - IpAddress = m.Groups["ip"].Value - }); - } - - return mip; - } - public struct MacIpPair - { - public string MacAddress; - public string IpAddress; - } - - /// - /// Returns the first ip adress whose MAC adress matches one from the known nintendo list. - /// - public static string GetFirst3DS() - { - foreach (var item in GetAllMacAddressesAndIppairs()) - { - string MAC = ""; - MAC = item.MacAddress.Replace("-", ""); - MAC = MAC.Substring(0, 6); - MAC = MAC.ToUpper(); - if (Nontendo.Contains(MAC)) - { - return item.IpAddress; - } - } - return ""; //Empty string means "No 3ds in range". To be used by the main thread to inform the user. (should I raise an exception? :S ) - } - - /// - /// Retrieves the local IPv4 Address - /// - /// Returns your computer's Loopback if no Network detected. - public static string Local - { - get { return Dns.GetHostEntry(Dns.GetHostName()).AddressList.DefaultIfEmpty(IPAddress.Loopback).Where(ip => ip.AddressFamily == AddressFamily.InterNetwork).ElementAt(iIPIndex).ToString(); } - } - - - /// - /// Validates if the specified string is an IPv4 Address - /// - /// The string to compare - /// True if the address is valid. - public static bool Validate(string ipString) - { - if (ipString == "0.0.0.0" || ipString == "127.0.0.1") - { - return false; - } - return new Regex(@"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$").IsMatch(ipString); //Check the octets - } - - } - } + namespace NetUtil + { + class IPv4 + { + + public static int iIPIndex = -1; + + + //Known Nintendo Mac adresses //Will no longer be supported :| + public static readonly List Nontendo = new List { "0009BF", "001656", "0017AB", "00191D", "0019FD", "001AE9", "001B7A", "001BEA", "001CBE", "001DBC", "001E35", "001EA9", "001F32", "001FC5", "002147", "0021BD", "00224C", "0022AA", "0022D7", "002331", "0023CC", "00241E", "002444", "0024F3", "0025A0", "002659", "002709", "0403D6", "182A7B", "2C10C1", "34AF2C", "40D28A", "40F407", "582F40", "58BDA3", "5C521E", "606BFF", "64B5C6", "78A2A0", "7CBB8A", "8C56C5", "8CCDE8", "98B6E9", "9CE635", "A438CC", "A45C27", "A4C0E1", "B87826", "B88AEC", "B8AE6E", "CC9E00", "CCFB65", "D86BF7", "DC68EB", "E00C7F", "E0E751", "E84ECE", "ECC40D", "E84ECE" }; + + + /// + /// Dups the result of arp -a into a list of a really neat struct. + /// Not the cleanest way but it works for me. + /// + static List GetAllMacAddressesAndIppairs() + { + List mip = new List(); + System.Diagnostics.Process pProcess = new System.Diagnostics.Process(); + pProcess.StartInfo.FileName = "arp"; + pProcess.StartInfo.Arguments = "-a "; + pProcess.StartInfo.UseShellExecute = false; + pProcess.StartInfo.RedirectStandardOutput = true; + pProcess.StartInfo.CreateNoWindow = true; + pProcess.Start(); + string cmdOutput = pProcess.StandardOutput.ReadToEnd(); + string pattern = @"(?([0-9]{1,3}\.?){4})\s*(?([a-f0-9]{2}-?){6})"; + + foreach (Match m in Regex.Matches(cmdOutput, pattern, RegexOptions.IgnoreCase)) + { + mip.Add(new MacIpPair() + { + MacAddress = m.Groups["mac"].Value, + IpAddress = m.Groups["ip"].Value + }); + } + + return mip; + } + public struct MacIpPair + { + public string MacAddress; + public string IpAddress; + } + + /// + /// Returns the first ip adress whose MAC adress matches one from the known nintendo list. + /// + public static string GetFirstNintendoIP() + { + foreach (var item in GetAllMacAddressesAndIppairs()) + { + string MAC = ""; + MAC = item.MacAddress.Replace("-", ""); + MAC = MAC.Substring(0, 6); + MAC = MAC.ToUpper(); + if (Nontendo.Contains(MAC)) + { + return item.IpAddress; + } + } + return ""; //Empty string means "No 3ds in range". To be used by the main thread to inform the user. (should I raise an exception? :S ) + } + + /// + /// Retrieves the local IPv4 Address + /// + /// Returns your computer's Loopback if no Network detected. + public static string Local + { + get { return Dns.GetHostEntry(Dns.GetHostName()).AddressList.DefaultIfEmpty(IPAddress.Loopback).Where(ip => ip.AddressFamily == AddressFamily.InterNetwork).ElementAt(iIPIndex).ToString(); } + } + + + /// + /// Validates if the specified string is an IPv4 Address + /// + /// The string to compare + /// True if the address is valid. + public static bool Validate(string ipString) + { + if (ipString == "0.0.0.0" || ipString == "127.0.0.1") + { + return false; + } + return new Regex(@"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$").IsMatch(ipString); //Check the octets + } + + /// + /// Validates if the specified string is a port + /// + /// The string to compare + /// True if the port is a number. + public static bool ValidatePort(string portString) + { + return (new Regex(@"[0-9]{1,5}").IsMatch(portString)); //between 1 and 5 digits. + } + + /// + /// TestPort + /// + /// + /// + public static bool PortInUse(int port) + { + bool inUse = false; + IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties(); + IPEndPoint[] ipEndPoints = ipProperties.GetActiveTcpListeners(); + foreach (IPEndPoint endPoint in ipEndPoints) + { + if (endPoint.Port == port) + { + inUse = true; + break; + } + } + return inUse; + } + + } + } } diff --git a/Boop/Properties/AssemblyInfo.cs b/Boop/Properties/AssemblyInfo.cs index f1a1dd4..159bff0 100644 --- a/Boop/Properties/AssemblyInfo.cs +++ b/Boop/Properties/AssemblyInfo.cs @@ -6,11 +6,11 @@ // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("Boop")] -[assembly: AssemblyDescription("Network file server for FBI")] +[assembly: AssemblyDescription("Network file server for Nintendo Switch and Nintendo 3DS")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Elemental Code (Milton Candelero)")] [assembly: AssemblyProduct("Boop")] -[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyCopyright("This software is under The Unlicence. Please be good.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.4.0.0")] -[assembly: AssemblyFileVersion("1.4.0.0")] +[assembly: AssemblyVersion("2.0.0.0")] +[assembly: AssemblyFileVersion("2.0.0.0")] diff --git a/Boop/Properties/Resources.Designer.cs b/Boop/Properties/Resources.Designer.cs index 2f5116b..462208d 100644 --- a/Boop/Properties/Resources.Designer.cs +++ b/Boop/Properties/Resources.Designer.cs @@ -63,9 +63,9 @@ internal Resources() { /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// - internal static System.Drawing.Bitmap Boop1 { + internal static System.Drawing.Bitmap _3ds { get { - object obj = ResourceManager.GetObject("Boop1", resourceCulture); + object obj = ResourceManager.GetObject("_3ds", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } @@ -73,9 +73,9 @@ internal static System.Drawing.Bitmap Boop1 { /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// - internal static System.Drawing.Bitmap github { + internal static System.Drawing.Bitmap _switch { get { - object obj = ResourceManager.GetObject("github", resourceCulture); + object obj = ResourceManager.GetObject("_switch", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } @@ -83,9 +83,9 @@ internal static System.Drawing.Bitmap github { /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// - internal static System.Drawing.Bitmap info { + internal static System.Drawing.Bitmap generic { get { - object obj = ResourceManager.GetObject("info", resourceCulture); + object obj = ResourceManager.GetObject("generic", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } @@ -93,9 +93,9 @@ internal static System.Drawing.Bitmap info { /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// - internal static System.Drawing.Bitmap IP { + internal static System.Drawing.Bitmap github { get { - object obj = ResourceManager.GetObject("IP", resourceCulture); + object obj = ResourceManager.GetObject("github", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } @@ -103,9 +103,9 @@ internal static System.Drawing.Bitmap IP { /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// - internal static System.Drawing.Bitmap snekicon { + internal static System.Drawing.Bitmap info { get { - object obj = ResourceManager.GetObject("snekicon", resourceCulture); + object obj = ResourceManager.GetObject("info", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } @@ -113,9 +113,9 @@ internal static System.Drawing.Bitmap snekicon { /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// - internal static System.Drawing.Bitmap snekicon1 { + internal static System.Drawing.Bitmap snek2icon { get { - object obj = ResourceManager.GetObject("snekicon1", resourceCulture); + object obj = ResourceManager.GetObject("snek2icon", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } diff --git a/Boop/Properties/Resources.resx b/Boop/Properties/Resources.resx index 9f7ed3e..a0e8db7 100644 --- a/Boop/Properties/Resources.resx +++ b/Boop/Properties/Resources.resx @@ -118,22 +118,22 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - ..\Resources\Boop1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\snekicon.ico;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\IP.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\generic.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\info.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\3ds.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\github.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\snekicon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\switch.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\snek2icon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a \ No newline at end of file diff --git a/Boop/Properties/Settings.Designer.cs b/Boop/Properties/Settings.Designer.cs index 8f6f4e2..c3ab24f 100644 --- a/Boop/Properties/Settings.Designer.cs +++ b/Boop/Properties/Settings.Designer.cs @@ -26,24 +26,24 @@ public static Settings Default { [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("192.168.1.1")] - public string saved3DSIP { + public string savedIP { get { - return ((string)(this["saved3DSIP"])); + return ((string)(this["savedIP"])); } set { - this["saved3DSIP"] = value; + this["savedIP"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("True")] - public bool bGuess { + [global::System.Configuration.DefaultSettingValueAttribute("8080")] + public string savedPort { get { - return ((bool)(this["bGuess"])); + return ((string)(this["savedPort"])); } set { - this["bGuess"] = value; + this["savedPort"] = value; } } } diff --git a/Boop/Properties/Settings.settings b/Boop/Properties/Settings.settings index 87e3498..5ae81b6 100644 --- a/Boop/Properties/Settings.settings +++ b/Boop/Properties/Settings.settings @@ -2,11 +2,11 @@ - + 192.168.1.1 - - True + + 8080 \ No newline at end of file diff --git a/Boop/Resources/3ds.png b/Boop/Resources/3ds.png new file mode 100644 index 0000000..fdc7e66 Binary files /dev/null and b/Boop/Resources/3ds.png differ diff --git a/Boop/Resources/generic.png b/Boop/Resources/generic.png new file mode 100644 index 0000000..243d14c Binary files /dev/null and b/Boop/Resources/generic.png differ diff --git a/Boop/Resources/snek2icon.png b/Boop/Resources/snek2icon.png new file mode 100644 index 0000000..6e2eae7 Binary files /dev/null and b/Boop/Resources/snek2icon.png differ diff --git a/Boop/Resources/switch.png b/Boop/Resources/switch.png new file mode 100644 index 0000000..e22ba13 Binary files /dev/null and b/Boop/Resources/switch.png differ diff --git a/Boop/UpdateChecker.cs b/Boop/UpdateChecker.cs deleted file mode 100644 index fd24c34..0000000 --- a/Boop/UpdateChecker.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; -using System.Reflection; -using System.Diagnostics; -using System.Net; -using System.IO; -using Newtonsoft.Json.Linq; - -namespace Boop -{ - class UpdateChecker - { - int iMajor; - int iMinor; - int iFix; - - public String sUrl { get; private set; } - - public static string GetCurrentVersion() - { - Assembly assembly = Assembly.GetExecutingAssembly(); - FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(assembly.Location); - return fileVersionInfo.ProductMajorPart.ToString() + "." + fileVersionInfo.ProductMinorPart.ToString() + "." + fileVersionInfo.ProductBuildPart.ToString(); - } - - public UpdateChecker(int Major, int Minor, int Fix) - { - sUrl = ""; - iMajor = Major; - iMinor = Minor; - iFix = Fix; - } - - public UpdateChecker() - { - sUrl = ""; - Assembly assembly = Assembly.GetExecutingAssembly(); - FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(assembly.Location); - iMajor = fileVersionInfo.ProductMajorPart; - iMinor = fileVersionInfo.ProductMinorPart; - iFix = fileVersionInfo.ProductBuildPart; - } - - public bool CheckForUpdates() //To maybe do: The json object that gitgub exposes has a field that marks the release as "pre-release" or not. Maybe optional to check if release or pre release? - { - HttpWebRequest HttpRequestObj = (HttpWebRequest)HttpWebRequest.Create(@"https://api.github.com/repos/miltoncandelero/boop/releases/latest"); - HttpRequestObj.Credentials = CredentialCache.DefaultCredentials; - HttpRequestObj.ContentType = "application/json"; - HttpRequestObj.Method = "GET"; - HttpRequestObj.Accept = "application/json"; - HttpRequestObj.UserAgent = "Boop"; // NEEDS SOMETHING WRITTEN! - HttpWebResponse response = (HttpWebResponse)HttpRequestObj.GetResponse(); - string content = new StreamReader(response.GetResponseStream()).ReadToEnd(); - - JObject jObject = JObject.Parse(content); - string Ver = (string)jObject["tag_name"]; - sUrl = (string)jObject["html_url"]; - try - { - String[] SplitVer = Ver.Split('.'); - - int sMajor = int.Parse(SplitVer[0]); - int sMinor = int.Parse(SplitVer[1]); - int sFix = int.Parse(SplitVer[2]); - - //There must be a WAAAAY better way of doing this, but I can't see it right now. - if (sMajor > iMajor) return true; - if (sMajor < iMajor) return false; - - if (sMajor == iMajor) - { - if (sMinor > iMinor) return true; - if (sMinor < iMinor) return false; - if (sMinor == iMinor) - { - if (sFix > iFix) return true; else return false; - } - - } - - - return false; - } - catch (Exception) - { - throw new Exception("Probably messed up the Tags in Github"); - } - - } - - - } -} diff --git a/Boop/Utils.cs b/Boop/Utils.cs new file mode 100644 index 0000000..a9c9221 --- /dev/null +++ b/Boop/Utils.cs @@ -0,0 +1,19 @@ +using System; +using System.Reflection; +using System.Diagnostics; +using System.Net; +using System.IO; + +namespace Boop +{ + class Utils + { + public static string GetCurrentVersion() + { + Assembly assembly = Assembly.GetExecutingAssembly(); + FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(assembly.Location); + return fileVersionInfo.ProductMajorPart.ToString() + "." + fileVersionInfo.ProductMinorPart.ToString() + "." + fileVersionInfo.ProductBuildPart.ToString(); + } + + } +} diff --git a/Boop/bin/Debug/Boop.vshost.exe.config b/Boop/bin/Debug/Boop.vshost.exe.config index 5fbd0fa..265f943 100644 --- a/Boop/bin/Debug/Boop.vshost.exe.config +++ b/Boop/bin/Debug/Boop.vshost.exe.config @@ -1,21 +1,21 @@ - + - -
+ +
- + - + 192.168.1.1 - - True + + 8080 - \ No newline at end of file + diff --git a/Boop/bin/Release/Boop.vshost.exe.config b/Boop/bin/Release/Boop.vshost.exe.config index 5fbd0fa..265f943 100644 --- a/Boop/bin/Release/Boop.vshost.exe.config +++ b/Boop/bin/Release/Boop.vshost.exe.config @@ -1,21 +1,21 @@ - + - -
+ +
- + - + 192.168.1.1 - - True + + 8080 - \ No newline at end of file + diff --git a/Boop/obj/Debug/DesignTimeResolveAssemblyReferences.cache b/Boop/obj/Debug/DesignTimeResolveAssemblyReferences.cache index 536a745..900a5aa 100644 Binary files a/Boop/obj/Debug/DesignTimeResolveAssemblyReferences.cache and b/Boop/obj/Debug/DesignTimeResolveAssemblyReferences.cache differ diff --git a/Boop/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache b/Boop/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache index 4b07edf..3067353 100644 Binary files a/Boop/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache and b/Boop/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache differ diff --git a/Boop/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll b/Boop/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll index 273f47f..e60f50d 100644 Binary files a/Boop/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll and b/Boop/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll differ diff --git a/Boop/obj/Release/DesignTimeResolveAssemblyReferences.cache b/Boop/obj/Release/DesignTimeResolveAssemblyReferences.cache index c217d15..2bea62f 100644 Binary files a/Boop/obj/Release/DesignTimeResolveAssemblyReferences.cache and b/Boop/obj/Release/DesignTimeResolveAssemblyReferences.cache differ diff --git a/Boop/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache b/Boop/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache index 3118139..14ec7ad 100644 Binary files a/Boop/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache and b/Boop/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache differ diff --git a/Boop/obj/Release/TempPE/Properties.Resources.Designer.cs.dll b/Boop/obj/Release/TempPE/Properties.Resources.Designer.cs.dll index e3a8e52..626290f 100644 Binary files a/Boop/obj/Release/TempPE/Properties.Resources.Designer.cs.dll and b/Boop/obj/Release/TempPE/Properties.Resources.Designer.cs.dll differ diff --git a/Boop/packages.config b/Boop/packages.config index 9d64bf3..f2ca19d 100644 --- a/Boop/packages.config +++ b/Boop/packages.config @@ -1,4 +1,5 @@  - + + \ No newline at end of file diff --git a/Boop/snek2icon.ico b/Boop/snek2icon.ico new file mode 100644 index 0000000..64ca97c Binary files /dev/null and b/Boop/snek2icon.ico differ diff --git a/README.md b/README.md index d00649b..883c71b 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,11 @@ # Boop -***Become a friend of the snek*** +***Become a friend of the sneks*** -Current release: **1.4.0** +**NOW WITH SWITCH SUPPORT!** -Boop is a C# implementation of the [servefiles.py from FBI](https://github.com/Steveice10/FBI/tree/2.4.5/servefiles) +Current release: **2.0.0** + +Boop is a C# implementation of the [servefiles.py from FBI](https://github.com/Steveice10/FBI/tree/2.4.5/servefiles) and [remote_install_pc.py from Tinfoil](https://github.com/Adubbz/Tinfoil/blob/master/tools/remote_install_pc.py) Boop is completely rewritten in C# and thus is snek friendly (No python needed). @@ -11,14 +13,15 @@ Enough talk! Take me to the [download page!](https://github.com/miltoncandelero/ ## Features: +* Switch .nsp and 3DS .cia support! * Easy to use GUI. * Full Drag and Drop support. * Multi-File Booping. -* We host using TCPListener. *The snek won!* +* We host using EmbedIO. (HTTP 2.0 supported!) * Doesn't require administrator rights. * Selecting an IP address if you are connected to multiple networks. -* Sneks looking after you. +* Sneks (one with a top hat) looking after you. ## Screenshot: -![Snek Screenshot](/Screenshot1.2.PNG?raw=true "Boop v1.4.0") +![Snek Screenshot](/boop2.png?raw=true "Boop v2.0.0") diff --git a/Screenshot1.2.PNG b/Screenshot1.2.PNG deleted file mode 100644 index fdc8497..0000000 Binary files a/Screenshot1.2.PNG and /dev/null differ diff --git a/boop2.png b/boop2.png new file mode 100644 index 0000000..aa80b93 Binary files /dev/null and b/boop2.png differ