]> git.deb.at Git - rhonda/impostor.git/commitdiff
Improve client
authorAeonLucid <aeonlucid@gmail.com>
Mon, 21 Sep 2020 17:51:46 +0000 (19:51 +0200)
committerAeonLucid <aeonlucid@gmail.com>
Mon, 21 Sep 2020 17:51:46 +0000 (19:51 +0200)
src/Impostor.Client/Core/AmongUsModifier.cs [new file with mode: 0644]
src/Impostor.Client/Core/Events/ErrorEventArgs.cs [new file with mode: 0644]
src/Impostor.Client/Core/Events/SavedEventArgs.cs [new file with mode: 0644]
src/Impostor.Client/Forms/FrmMain.Designer.cs
src/Impostor.Client/Forms/FrmMain.cs
src/Impostor.Client/Forms/FrmMain.resx

diff --git a/src/Impostor.Client/Core/AmongUsModifier.cs b/src/Impostor.Client/Core/AmongUsModifier.cs
new file mode 100644 (file)
index 0000000..4c6d75b
--- /dev/null
@@ -0,0 +1,140 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading.Tasks;
+using Impostor.Client.Core.Events;
+using Impostor.Shared.Innersloth;
+using ErrorEventArgs = Impostor.Client.Core.Events.ErrorEventArgs;
+
+namespace Impostor.Client.Core
+{
+    public class AmongUsModifier
+    {
+        private const string RegionName = "Impostor";
+        
+        private readonly string _amongUsDir;
+        private readonly string _regionFile;
+        
+        public AmongUsModifier()
+        {
+            var appData = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "..\\LocalLow");
+            var amongUsDir = Path.Combine(appData, "Innersloth", "Among Us");
+
+            _amongUsDir = amongUsDir;
+            _regionFile = Path.Combine(amongUsDir, "regionInfo.dat");
+        }
+        
+        public async Task SaveIp(string ip)
+        {
+            // Filter out whitespace.
+            ip = ip.Trim();
+            
+            // Check if a valid IP address was entered.
+            if (!IPAddress.TryParse(ip, out var ipAddress))
+            {
+                // Attempt to resolve DNS.
+                try
+                {
+                    var hostAddresses = await Dns.GetHostAddressesAsync(ip);
+                    if (hostAddresses.Length == 0)
+                    {
+                        OnError("Invalid IP Address entered");
+                        return;
+                    }
+                    
+                    // Use first IPv4 result.
+                    ipAddress = hostAddresses.First(x => x.AddressFamily == AddressFamily.InterNetwork);
+                }
+                catch (SocketException)
+                {
+                    OnError("Failed to resolve hostname.");
+                    return;
+                }
+            }
+            
+            // Only IPv4.
+            if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
+            {
+                OnError("Invalid IP Address entered, only IPv4 is allowed.");
+                return;
+            }
+
+            WriteIp(ipAddress);
+        }
+
+        /// <summary>
+        ///     Writes an IP Address to the Among Us region file.
+        /// </summary>
+        /// <param name="ipAddress">The IPv4 address to write.</param>
+        private void WriteIp(IPAddress ipAddress)
+        {
+            if (ipAddress == null || 
+                ipAddress.AddressFamily != AddressFamily.InterNetwork)
+            {
+                throw new ArgumentException(nameof(ipAddress));
+            }
+            
+            if (!Directory.Exists(_amongUsDir))
+            {
+                OnError("Among Us directory was not found, is it installed? Try running it once.");
+                return;
+            }
+            
+            using (var file = File.Open(_regionFile, FileMode.Create, FileAccess.Write))
+            using (var writer = new BinaryWriter(file))
+            {
+                var ip = ipAddress.ToString();
+                var region = new RegionInfo(RegionName, ip, new[]
+                {
+                    new ServerInfo($"{RegionName}-Master-1", ip, 22023)
+                });
+                    
+                region.Serialize(writer);
+
+                OnSaved(ip);
+            }
+        }
+
+        /// <summary>
+        ///     Loads the existing IP Address from the Among Us region file
+        ///     if it was set by Impostor before.
+        /// </summary>
+        public bool TryLoadIp(out string ipAddress)
+        {
+            ipAddress = null;
+            
+            if (!File.Exists(_regionFile))
+            {
+                return false;
+            }
+
+            using (var file = File.Open(_regionFile, FileMode.Open, FileAccess.Read))
+            using (var reader = new BinaryReader(file))
+            {
+                var region = RegionInfo.Deserialize(reader);
+                if (region.Name == RegionName && region.Servers.Count >= 1)
+                {
+                    ipAddress = region.Servers[0].Ip;
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        private void OnError(string message)
+        {
+            Error?.Invoke(this, new ErrorEventArgs(message));
+        }
+
+        private void OnSaved(string ipAddress)
+        {
+            Saved?.Invoke(this, new SavedEventArgs(ipAddress));
+        }
+            
+        public event EventHandler<ErrorEventArgs> Error;
+        public event EventHandler<SavedEventArgs> Saved;
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Client/Core/Events/ErrorEventArgs.cs b/src/Impostor.Client/Core/Events/ErrorEventArgs.cs
new file mode 100644 (file)
index 0000000..939a364
--- /dev/null
@@ -0,0 +1,14 @@
+using System;
+
+namespace Impostor.Client.Core.Events
+{
+    public class ErrorEventArgs : EventArgs
+    {
+        public ErrorEventArgs(string message)
+        {
+            Message = message;
+        }
+        
+        public string Message { get; }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Client/Core/Events/SavedEventArgs.cs b/src/Impostor.Client/Core/Events/SavedEventArgs.cs
new file mode 100644 (file)
index 0000000..b3ffa0f
--- /dev/null
@@ -0,0 +1,14 @@
+using System;
+
+namespace Impostor.Client.Core.Events
+{
+    public class SavedEventArgs : EventArgs
+    {
+        public SavedEventArgs(string ipAddress)
+        {
+            IpAddress = ipAddress;
+        }
+        
+        public string IpAddress { get; }
+    }
+}
\ No newline at end of file
index c5511d881250e8900afb14c1dceeb725ac02f8d9..ca2be07af03f2e1353584719a9887f3298a45096 100644 (file)
             this.label2 = new System.Windows.Forms.Label();
             this.buttonLaunch = new System.Windows.Forms.Button();
             this.textIp = new System.Windows.Forms.TextBox();
+            this.lblUrl = new System.Windows.Forms.Label();
+            this.label3 = new System.Windows.Forms.Label();
             this.SuspendLayout();
             // 
             // label1
             // 
             this.label1.AutoSize = true;
-            this.label1.Location = new System.Drawing.Point(12, 90);
+            this.label1.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+            this.label1.Location = new System.Drawing.Point(28, 139);
             this.label1.Name = "label1";
-            this.label1.Size = new System.Drawing.Size(62, 15);
+            this.label1.Size = new System.Drawing.Size(60, 13);
             this.label1.TabIndex = 0;
             this.label1.Text = "IP Address";
             // 
             // label2
             // 
             this.label2.AutoSize = true;
-            this.label2.Location = new System.Drawing.Point(12, 9);
+            this.label2.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+            this.label2.Location = new System.Drawing.Point(28, 23);
             this.label2.Name = "label2";
-            this.label2.Size = new System.Drawing.Size(230, 60);
+            this.label2.Size = new System.Drawing.Size(225, 91);
             this.label2.TabIndex = 1;
             this.label2.Text = "Welcome to Impostor\r\n\r\nPlease enter in the IP Address of the \r\nserver you would l" +
-    "ike to use for Among Us";
+    "ike to use for Among Us\r\n\r\nIf you want to stop playing on the server, \r\nsimply s" +
+    "elect another region";
             // 
             // buttonLaunch
             // 
-            this.buttonLaunch.Location = new System.Drawing.Point(168, 123);
+            this.buttonLaunch.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+            this.buttonLaunch.Location = new System.Drawing.Point(179, 155);
             this.buttonLaunch.Name = "buttonLaunch";
-            this.buttonLaunch.Size = new System.Drawing.Size(79, 23);
+            this.buttonLaunch.Size = new System.Drawing.Size(74, 22);
             this.buttonLaunch.TabIndex = 2;
             this.buttonLaunch.Text = "Save";
             this.buttonLaunch.UseVisualStyleBackColor = true;
             // 
             // textIp
             // 
-            this.textIp.Location = new System.Drawing.Point(12, 123);
+            this.textIp.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+            this.textIp.Location = new System.Drawing.Point(31, 155);
             this.textIp.Name = "textIp";
-            this.textIp.Size = new System.Drawing.Size(150, 23);
+            this.textIp.Size = new System.Drawing.Size(141, 22);
             this.textIp.TabIndex = 3;
+            this.textIp.KeyDown += new System.Windows.Forms.KeyEventHandler(this.textIp_KeyDown);
+            // 
+            // lblUrl
+            // 
+            this.lblUrl.AutoSize = true;
+            this.lblUrl.Cursor = System.Windows.Forms.Cursors.Hand;
+            this.lblUrl.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+            this.lblUrl.ForeColor = System.Drawing.SystemColors.Highlight;
+            this.lblUrl.Location = new System.Drawing.Point(39, 215);
+            this.lblUrl.Name = "lblUrl";
+            this.lblUrl.Size = new System.Drawing.Size(212, 13);
+            this.lblUrl.TabIndex = 4;
+            this.lblUrl.Text = "https://github.com/AeonLucid/Impostor";
+            this.lblUrl.Click += new System.EventHandler(this.lblUrl_Click);
+            // 
+            // label3
+            // 
+            this.label3.AutoSize = true;
+            this.label3.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+            this.label3.Location = new System.Drawing.Point(54, 199);
+            this.label3.Name = "label3";
+            this.label3.Size = new System.Drawing.Size(182, 13);
+            this.label3.TabIndex = 5;
+            this.label3.Text = "Source code and latest versions at\r\n";
             // 
             // FrmMain
             // 
-            this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-            this.ClientSize = new System.Drawing.Size(259, 161);
+            this.ClientSize = new System.Drawing.Size(283, 253);
+            this.Controls.Add(this.label3);
+            this.Controls.Add(this.lblUrl);
             this.Controls.Add(this.textIp);
             this.Controls.Add(this.buttonLaunch);
             this.Controls.Add(this.label2);
             this.ForeColor = System.Drawing.SystemColors.ControlText;
             this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
             this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
-            this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
             this.MaximizeBox = false;
             this.Name = "FrmMain";
+            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
             this.Text = "Impostor";
             this.Load += new System.EventHandler(this.FrmMain_Load);
+            this.Shown += new System.EventHandler(this.FrmMain_Shown);
             this.ResumeLayout(false);
             this.PerformLayout();
 
 
         private System.Windows.Forms.Label label1;
         private System.Windows.Forms.Label label2;
-        private System.Windows.Forms.Button buttonL;
-        private System.Windows.Forms.TextBox txtIp;
         private System.Windows.Forms.Button buttonLaunch;
         private System.Windows.Forms.TextBox textIp;
+        private System.Windows.Forms.Label lblUrl;
+        private System.Windows.Forms.Label label3;
     }
 }
\ No newline at end of file
index 6b413b957d603992f4c1509b04e14c6255b1aebd..b180e926a7049d1dc1bf2dd0e3daf1a5acedc564 100644 (file)
@@ -1,68 +1,85 @@
 using System;
-using System.IO;
-using System.Net;
-using System.Net.Sockets;
+using System.Diagnostics;
+using System.Threading.Tasks;
 using System.Windows.Forms;
-using Impostor.Shared.Innersloth;
+using Impostor.Client.Core;
+using Impostor.Client.Core.Events;
 
 namespace Impostor.Client.Forms
 {
     public partial class FrmMain : Form
     {
+        private readonly AmongUsModifier _modifier;
+        
         public FrmMain()
         {
             InitializeComponent();
+
+            AcceptButton = buttonLaunch;
+            
+            _modifier = new AmongUsModifier();
+            _modifier.Error += ModifierOnError;
+            _modifier.Saved += ModifierOnSaved;
         }
 
-        private void FrmMain_Load(object sender, EventArgs e)
+        private void ModifierOnError(object sender, ErrorEventArgs e)
         {
-            // TODO: Load old IP.
+            MessageBox.Show(e.Message, "Error",
+                MessageBoxButtons.OK,
+                MessageBoxIcon.Error);
+
+            textIp.Text = string.Empty;
+            textIp.Focus();
+            
+            textIp.Enabled = true;
+            buttonLaunch.Enabled = true;
         }
 
-        private void buttonLaunch_Click(object sender, EventArgs e)
+        private void ModifierOnSaved(object sender, SavedEventArgs e)
         {
-            var ipText = textIp.Text;
-            
-            if (!IPAddress.TryParse(ipText, out var ipAddress))
+            MessageBox.Show("The IP Address was saved, please (re)start Among Us.", "Success", 
+                MessageBoxButtons.OK, 
+                MessageBoxIcon.Information);
+
+            textIp.Text = e.IpAddress;
+            textIp.Enabled = true;
+            buttonLaunch.Enabled = true;
+        }
+
+        private void FrmMain_Load(object sender, EventArgs e)
+        {
+            if (_modifier.TryLoadIp(out var ipAddress))
             {
-                MessageBox.Show("Invalid IP Address entered", "Error", 
-                    MessageBoxButtons.OK, 
-                    MessageBoxIcon.Error);
-                
-                textIp.Text = string.Empty;
-                textIp.Focus();
-                return;
+                textIp.Text = ipAddress;
             }
+        }
+
+        private void FrmMain_Shown(object sender, EventArgs e)
+        {
+            textIp.Focus();
+        }
 
-            if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
+        private void textIp_KeyDown(object sender, KeyEventArgs e)
+        {
+            if (e.KeyCode == Keys.Enter)
             {
-                MessageBox.Show("Invalid IP Address entered, only IPv4 is allowed.", "Error", 
-                    MessageBoxButtons.OK, 
-                    MessageBoxIcon.Error);
+                e.Handled = true;
                 
-                textIp.Text = string.Empty;
-                textIp.Focus();
-                return;
+                buttonLaunch_Click(this, EventArgs.Empty);
             }
-            
-            // TODO: Clean up, move to somewhere else & error handling.
-            
-            var appData = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "..\\LocalLow");
-            var regionFile = Path.Combine(appData, "Innersloth", "Among Us", "regionInfo.dat");
-            var region = new RegionInfo("Private", ipText, new []
-            {
-                new ServerInfo("Private-Master-1", ipText, 22023)
-            });
-            
-            using (var file = File.Open(regionFile, FileMode.Create, FileAccess.Write))
-            using (var writer = new BinaryWriter(file))
-            {
-                region.Serialize(writer);
-            }
-            
-            MessageBox.Show("The IP Address was saved, please (re)start Among Us.", "Success", 
-                MessageBoxButtons.OK, 
-                MessageBoxIcon.Information);
+        }
+
+        private async void buttonLaunch_Click(object sender, EventArgs e)
+        {
+            textIp.Enabled = false;
+            buttonLaunch.Enabled = false;
+
+            await _modifier.SaveIp(textIp.Text);
+        }
+
+        private void lblUrl_Click(object sender, EventArgs e)
+        {
+            Process.Start("https://github.com/AeonLucid/Impostor");
         }
     }
 }
\ No newline at end of file
index 427078fe3ffc98b58f2ef0ce2b16040d36b81ab1..839a9c4f7df255625e201c981ebc89b8a4a21f31 100644 (file)
@@ -1,4 +1,64 @@
-<root>
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
   <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
     <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
     <xsd:element name="root" msdata:IsDataSet="true">
   <resheader name="writer">
     <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
-  <assembly alias="System.Drawing.Common" name="System.Drawing.Common, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" />
-  <data name="$this.Icon" type="System.Drawing.Icon, System.Drawing.Common" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+  <data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         AAABAAYAAAAAAAEAIAAUgQAAZgAAAICAAAABACAAKAgBAHqBAABAQAAAAQAgAChCAACiiQEAMDAAAAEA
         IACoJQAAyssBACAgAAABACAAqBAAAHLxAQAQEAAAAQAgAGgEAAAaAgIAiVBORw0KGgoAAAANSUhEUgAA