diff --git a/PortProxyGUI/Data/Rule.cs b/PortProxyGUI/Data/Rule.cs index a777399..8d75ea6 100644 --- a/PortProxyGUI/Data/Rule.cs +++ b/PortProxyGUI/Data/Rule.cs @@ -13,6 +13,7 @@ namespace PortProxyGUI.Data public int ConnectPort { get; set; } public string Comment { get; set; } public string Group { get; set; } + public string PingStatus { get; set; } = "Not checked"; public bool Valid => ListenPort > 0 && ConnectPort > 0; diff --git a/PortProxyGUI/PortProxyGUI.Designer.cs b/PortProxyGUI/PortProxyGUI.Designer.cs index 7c0962c..276fff1 100644 --- a/PortProxyGUI/PortProxyGUI.Designer.cs +++ b/PortProxyGUI/PortProxyGUI.Designer.cs @@ -37,12 +37,14 @@ this.columnHeader4 = new System.Windows.Forms.ColumnHeader(); this.columnHeader5 = new System.Windows.Forms.ColumnHeader(); this.columnHeader6 = new System.Windows.Forms.ColumnHeader(); + this.columnPingStatus = new System.Windows.Forms.ColumnHeader(); this.columnHeader7 = new System.Windows.Forms.ColumnHeader(); this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); this.toolStripMenuItem_Enable = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItem_Disable = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); this.toolStripMenuItem_Refresh = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem_RefreshPingStatus = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItem_FlushDnsCache = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); this.toolStripMenuItem_New = new System.Windows.Forms.ToolStripMenuItem(); @@ -64,6 +66,7 @@ this.columnHeader4, this.columnHeader5, this.columnHeader6, + this.columnPingStatus, this.columnHeader7}); this.listViewProxies.ContextMenuStrip = this.contextMenuStrip1; resources.ApplyResources(this.listViewProxies, "listViewProxies"); @@ -104,6 +107,10 @@ this.columnHeader6.Tag = ""; resources.ApplyResources(this.columnHeader6, "columnHeader6"); // + // columnPingStatus + // + resources.ApplyResources(this.columnPingStatus, "columnPingStatus"); + // // columnHeader7 // resources.ApplyResources(this.columnHeader7, "columnHeader7"); @@ -115,6 +122,7 @@ this.toolStripMenuItem_Disable, this.toolStripSeparator3, this.toolStripMenuItem_Refresh, + this.toolStripMenuItem_RefreshPingStatus, this.toolStripMenuItem_FlushDnsCache, this.toolStripSeparator2, this.toolStripMenuItem_New, @@ -146,6 +154,11 @@ this.toolStripMenuItem_Refresh.Name = "toolStripMenuItem_Refresh"; resources.ApplyResources(this.toolStripMenuItem_Refresh, "toolStripMenuItem_Refresh"); // + // toolStripMenuItem_RefreshPingStatus + // + this.toolStripMenuItem_RefreshPingStatus.Name = "toolStripMenuItem_RefreshPingStatus"; + resources.ApplyResources(this.toolStripMenuItem_RefreshPingStatus, "toolStripMenuItem_RefreshPingStatus"); + // // toolStripMenuItem_FlushDnsCache // this.toolStripMenuItem_FlushDnsCache.Name = "toolStripMenuItem_FlushDnsCache"; @@ -224,6 +237,8 @@ private System.Windows.Forms.ColumnHeader columnHeader7; internal System.Windows.Forms.ListView listViewProxies; private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem_FlushDnsCache; + private System.Windows.Forms.ColumnHeader columnPingStatus; + private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem_RefreshPingStatus; } } diff --git a/PortProxyGUI/PortProxyGUI.cs b/PortProxyGUI/PortProxyGUI.cs index af4aa82..5db85ba 100644 --- a/PortProxyGUI/PortProxyGUI.cs +++ b/PortProxyGUI/PortProxyGUI.cs @@ -1,7 +1,10 @@ using NStandard; using System; +using System.Collections.Generic; using System.Data; +using System.Drawing; using System.Linq; +using System.Net.NetworkInformation; using System.Windows.Forms; using static System.Windows.Forms.ListViewItem; @@ -12,7 +15,7 @@ namespace PortProxyGUI public SetProxy SetProxyForm; public About AboutForm; private ListViewColumnSorter lvwColumnSorter; - + private List> hostStatus { get; set; } = new List>(); public PortProxyGUI() { InitializeComponent(); @@ -46,7 +49,8 @@ namespace PortProxyGUI ListenPort = listenPort, ConnectTo = subItems[4].Text.Trim(), ConnectPort = connectPort, - Comment = subItems[6].Text.Trim(), + PingStatus = subItems[6].Text.Trim(), + Comment = subItems[7].Text.Trim(), Group = item.Group?.Header.Trim(), }; return rule; @@ -154,7 +158,14 @@ namespace PortProxyGUI new ListViewSubItem(item, rule.ListenPort.ToString()) { Tag = "Number" }, new ListViewSubItem(item, rule.ConnectTo), new ListViewSubItem(item, rule.ConnectPort.ToString ()) { Tag = "Number" }, - new ListViewSubItem(item, rule.Comment ?? ""), + new ListViewSubItem(item, rule.PingStatus ?? string.Empty) + { + Tag ="Connect To Ping Status", + ForeColor = rule.PingStatus.Equals("Success") ? Color.Green + : rule.PingStatus.Equals("Pending") ? Color.DarkGray + : Color.MediumVioletRed + }, + new ListViewSubItem(item, rule.Comment ?? string.Empty) }); if (rule.Group.IsNullOrWhiteSpace()) item.Group = null; @@ -172,28 +183,36 @@ namespace PortProxyGUI public void RefreshProxyList() { - var proxies = CmdUtil.GetProxies(); - var rules = Program.SqliteDbScope.Rules.ToArray(); - foreach (var proxy in proxies) + try { - var matchedRule = rules.FirstOrDefault(r => r.EqualsWithKeys(proxy)); - proxy.Id = matchedRule?.Id; + + var proxies = CmdUtil.GetProxies(); + var rules = Program.SqliteDbScope.Rules.ToArray(); + foreach (var proxy in proxies) + { + var matchedRule = rules.FirstOrDefault(r => r.EqualsWithKeys(proxy)); + proxy.Id = matchedRule?.Id; + } + + var pendingAdds = proxies.Where(x => x.Valid && x.Id == null); + var pendingUpdates = + from proxy in proxies + let exsist = rules.FirstOrDefault(r => r.Id == proxy.Id) + where exsist is not null + where proxy.Valid && proxy.Id is not null + select proxy; + + Program.SqliteDbScope.AddRange(pendingAdds); + Program.SqliteDbScope.UpdateRange(pendingUpdates); + + rules = Program.SqliteDbScope.Rules.ToArray(); + InitProxyGroups(rules); + InitProxyItems(rules, proxies); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "Error Refreshing"); } - - var pendingAdds = proxies.Where(x => x.Valid && x.Id == null); - var pendingUpdates = - from proxy in proxies - let exsist = rules.FirstOrDefault(r => r.Id == proxy.Id) - where exsist is not null - where proxy.Valid && proxy.Id is not null - select proxy; - - Program.SqliteDbScope.AddRange(pendingAdds); - Program.SqliteDbScope.UpdateRange(pendingUpdates); - - rules = Program.SqliteDbScope.Rules.ToArray(); - InitProxyGroups(rules); - InitProxyItems(rules, proxies); } public void FlushDnsCache() @@ -237,6 +256,9 @@ namespace PortProxyGUI case ToolStripMenuItem item when item == toolStripMenuItem_Refresh: RefreshProxyList(); break; + case ToolStripMenuItem item when item == toolStripMenuItem_RefreshPingStatus: + RefreshConnectHostPingStatus(); + break; case ToolStripMenuItem item when item == toolStripMenuItem_FlushDnsCache: FlushDnsCache(); break; @@ -314,5 +336,42 @@ namespace PortProxyGUI if (e.KeyCode == Keys.Delete) DeleteSelectedProxies(); } } + + private void RefreshConnectHostPingStatus() + { + try + { + var items = listViewProxies.Items.OfType(); + hostStatus = new List>(); + foreach (var item in items) + { + try + { + //Custom Color for cells + item.UseItemStyleForSubItems = false; + //Proceed + Data.Rule rule = ParseRule(item); + //Check if host already pinged host + var alreadyChkdHost = hostStatus.FirstOrDefault(x => x.Key.Equals(rule.ConnectTo, StringComparison.OrdinalIgnoreCase)); + if (!string.IsNullOrEmpty(alreadyChkdHost.Key)) + { + //Skip Checking Status since already checked + rule.PingStatus = alreadyChkdHost.Value.ToString(); + UpdateListViewItem(item, rule, item.ImageIndex); + } + else + { + //If not yet checked + PingCheckerUtil.GetPingResult(rule.ConnectTo, 2, out IPStatus ipStatus, out _, out _); + hostStatus.Add(new KeyValuePair(rule.ConnectTo, ipStatus)); + rule.PingStatus = ipStatus.ToString(); + UpdateListViewItem(item, rule, item.ImageIndex); + } + } + catch { } + } + } + catch { } + } } } diff --git a/PortProxyGUI/PortProxyGUI.resx b/PortProxyGUI/PortProxyGUI.resx index 55babf0..b7f58c4 100644 --- a/PortProxyGUI/PortProxyGUI.resx +++ b/PortProxyGUI/PortProxyGUI.resx @@ -94,6 +94,12 @@ 100 + + Ping Status + + + 104 + Comment @@ -125,6 +131,18 @@ Refresh (&F) + + Refresh Port Proxies + + + 180, 22 + + + Refresh Ping Status + + + Refresh Host Ping Statuses + 180, 22 @@ -132,7 +150,7 @@ Flush DNS Cache - Will perform ipconfig/flushDNS + Perform ipconfig/flushDNS 177, 6 @@ -165,7 +183,7 @@ About - 181, 220 + 181, 242 contextMenuStrip1 @@ -184,10 +202,10 @@ 0, 0 - 4, 3, 4, 3 + 5, 3, 5, 3 - 704, 456 + 797, 456 182, 17 @@ -197,7 +215,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAA3AgAAAJNU0Z0AUkBTAIBAQIB - AAEwAQEBMAEBARABAAEQAQAE/wEJAQAI/wFCAU0BNgEEBgABNgEEAgABKAMAAUADAAEQAwABAQEAAQgG + AAF4AQEBeAEBARABAAEQAQAE/wEJAQAI/wFCAU0BNgEEBgABNgEEAgABKAMAAUADAAEQAwABAQEAAQgG AAEEGAABgAIAAYADAAKAAQABgAMAAYABAAGAAQACgAIAA8ABAAHAAdwBwAEAAfABygGmAQABMwUAATMB AAEzAQABMwEAAjMCAAMWAQADHAEAAyIBAAMpAQADVQEAA00BAANCAQADOQEAAYABfAH/AQACUAH/AQAB kwEAAdYBAAH/AewBzAEAAcYB1gHvAQAB1gLnAQABkAGpAa0CAAH/ATMDAAFmAwABmQMAAcwCAAEzAwAC @@ -256,10 +274,13 @@ True - 6, 13 + 7, 15 - 704, 456 + 797, 456 + + + Segoe UI, 9pt @@ -2464,6 +2485,12 @@ System.Windows.Forms.ColumnHeader, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + columnPingStatus + + + System.Windows.Forms.ColumnHeader, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 + columnHeader7 @@ -2494,6 +2521,12 @@ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + toolStripMenuItem_RefreshPingStatus + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 + toolStripMenuItem_FlushDnsCache diff --git a/PortProxyGUI/~DS/PingCheckerUtil.cs b/PortProxyGUI/~DS/PingCheckerUtil.cs new file mode 100644 index 0000000..c986cbf --- /dev/null +++ b/PortProxyGUI/~DS/PingCheckerUtil.cs @@ -0,0 +1,31 @@ +using System.Net; +using System.Net.NetworkInformation; +using System.Text; + +namespace PortProxyGUI +{ + public static class PingCheckerUtil + { + // Adapted from https://docs.microsoft.com/en-us/dotnet/api/system.net.networkinformation.ping.send + public static bool GetPingResult(string ipAddress, int timeout, out IPStatus responseStatus, out IPAddress responseIpAddress, out long responseTime) + { + //Defaults + responseIpAddress = null; + responseTime = 0; + responseStatus = IPStatus.Unknown; + try + { + //Sending 32bytes + byte[] buffer = Encoding.ASCII.GetBytes("12345678901234567890123456789012"); + Ping pingSender = new Ping(); + PingOptions options = new PingOptions(64, true); + PingReply reply = pingSender.Send(ipAddress, timeout, buffer, options); + responseIpAddress = reply.Address; + responseTime = reply.RoundtripTime; + responseStatus = reply.Status; + return (reply.Status == IPStatus.Success) ? true : false; + } + catch { return false; } + } + } +}