Skip to content

Commit

Permalink
refactor: Now uses the new array-like collections initializers everyw…
Browse files Browse the repository at this point in the history
…here.

fix: Improved the bandwidth chart logic (which was buggy and probably still is ?).
  • Loading branch information
wokhan committed Jan 3, 2025
1 parent 2008ec0 commit dbe37c7
Show file tree
Hide file tree
Showing 19 changed files with 212 additions and 85 deletions.
18 changes: 9 additions & 9 deletions Common.Tests/Helpers/DnsResolverTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ public class DnsResolverTest : NUnitTestBase
public void TestDnsResolverResolveIpAddresses()
{
// Hostname -> IP lookup: https://whatismyipaddress.com/hostname-ip
List<string> ipList = new List<string>
{
List<string> ipList =
[
"52.200.121.83", // origin on ec2-52-200-121-83.compute-1.amazonaws.com
"52.200.121.83", // duplicate
"8.8.8.8", // dns.google
"2001:4860:4860::8888", // dns.google
Dns.GetHostAddresses("www.google.ch").FirstOrDefault().ToString()
};
];

WriteDebugOutput("Resolve first 3 entries:");
_ = ResolvedIPInformation.ResolveIpAddressAsync(ipList[0]).ConfigureAwait(true);
Expand All @@ -34,13 +34,13 @@ public void TestDnsResolverResolveIpAddresses()
Assert.That(ResolvedIPInformation.CachedIPHostEntryDict["8.8.8.8"].resolvedHost, Is.EqualTo("dns.google"));
Assert.True(ResolvedIPInformation.CachedIPHostEntryDict.Values.Count == 4);

ipList = new List<string>
{
ipList =
[
"2001:4860:4860::8888", // dns.google
"172.217.5.195", // lax28s10-in-f195.1e100.net (www.google.ch)
"23.211.5.15", // a23-211-5-15.deploy.static.akamaitechnologies.com
"1.78.64.10", // sp1-78-64-10.msa.spmode.ne.jp
};
];
WriteDebugOutput("Resolve next 3 entries:");
_ = ResolvedIPInformation.ResolveIpAddressAsync(ipList[0]).ConfigureAwait(false);
_ = ResolvedIPInformation.ResolveIpAddressAsync(ipList[1]).ConfigureAwait(false);
Expand All @@ -57,11 +57,11 @@ public void TestDnsResolverResolveIpAddresses()
//[Test, ManualTestCategory]
public void TestDnsResolverResolveIpAddresses_unresolved()
{
List<string> ipList = new List<string>
{
List<string> ipList =
[
// unresolvable ips
"1.9.1.9", // cdns01.tm.net.my
};
];
WriteDebugOutput("Unresolvabe IPs:");

_ = ResolvedIPInformation.ResolveIpAddressAsync("1.9.1.9").ConfigureAwait(false);
Expand Down
2 changes: 1 addition & 1 deletion Common/Net/IP/IPHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ internal static int GetRealPort(uint _remotePort)
return (int)(BitConverter.IsLittleEndian ? BinaryPrimitives.ReverseEndianness((ushort)_remotePort) : (ushort)_remotePort);
}

internal static Dictionary<Connection, MIB_TCPROW_LH> TCP4MIBCACHE = new();
internal static Dictionary<Connection, MIB_TCPROW_LH> TCP4MIBCACHE = [];

public static string MergePorts(IEnumerable<int> ports)
{
Expand Down
2 changes: 1 addition & 1 deletion Common/Processes/ProcessHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public static Dictionary<uint, ServiceInfoResult> GetAllServicesByPidWMI()
{
// use WMI "Win32_Service" query to get service names by pid
// https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-service
Dictionary<uint, ServiceInfoResult> dict = new Dictionary<uint, ServiceInfoResult>();
Dictionary<uint, ServiceInfoResult> dict = [];
using (var searcher = new ManagementObjectSearcher("SELECT ProcessId, Name, DisplayName, PathName FROM Win32_Service WHERE ProcessId != 0"))
{
using var results = searcher.Get();
Expand Down
2 changes: 1 addition & 1 deletion Common/Security/EventLogAsyncReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public EventLogAsyncReader(string eventLogName, Func<EventLogEntry, int, T?> pro

private readonly Func<EventLogEntry, int, T?> _projection;
public Func<int, T>? PlaceHolderCreator { get; set; }
private readonly Dictionary<int, int> filteredPagesMap = new Dictionary<int, int>();
private readonly Dictionary<int, int> filteredPagesMap = [];

public int Count => eventLog.Entries.Count;

Expand Down
3 changes: 3 additions & 0 deletions Common/UI/Themes/Dark.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,16 @@

<SolidColorBrush x:Key="{x:Static SystemColors.WindowBrushKey}" Color="Black" />
<SolidColorBrush x:Key="{x:Static SystemColors.WindowTextBrushKey}" Color="White" />
<Color x:Key="{x:Static SystemColors.WindowTextColorKey}">White</Color>
<SolidColorBrush x:Key="{x:Static SystemColors.ActiveCaptionBrushKey}" Color="#202020" />
<SolidColorBrush x:Key="{x:Static SystemColors.ScrollBarBrushKey}" Color="#202020" />
<SolidColorBrush x:Key="{x:Static SystemColors.MenuBarBrushKey}" Color="#101010" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="White" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="#202020" />
<SolidColorBrush x:Key="{x:Static SystemColors.InfoBrushKey}" Color="Gray" />
<Color x:Key="{x:Static SystemColors.InfoColorKey}">Gray</Color>
<SolidColorBrush x:Key="{x:Static SystemColors.InfoTextBrushKey}" Color="Black" />
<Color x:Key="{x:Static SystemColors.InfoTextColorKey}">Black</Color>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Gray" />
<!--<SolidColorBrush x:Key="{x:Static SystemColors.ButtonHighlightBrushKey}" Color="#202020" />-->

Expand Down
3 changes: 3 additions & 0 deletions Common/UI/Themes/Light.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,16 @@

<SolidColorBrush x:Key="{x:Static SystemColors.WindowBrushKey}" Color="WhiteSmoke" />
<SolidColorBrush x:Key="{x:Static SystemColors.WindowTextBrushKey}" Color="Black" />
<Color x:Key="{x:Static SystemColors.WindowTextColorKey}">Black</Color>
<SolidColorBrush x:Key="{x:Static SystemColors.ActiveCaptionBrushKey}" Color="LightGray" />
<SolidColorBrush x:Key="{x:Static SystemColors.ScrollBarBrushKey}" Color="WhiteSmoke" />
<SolidColorBrush x:Key="{x:Static SystemColors.MenuBarBrushKey}" Color="LightGray" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="Black" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="White" />
<SolidColorBrush x:Key="{x:Static SystemColors.InfoBrushKey}" Color="LightYellow" />
<Color x:Key="{x:Static SystemColors.InfoColorKey}">LightYellow</Color>
<SolidColorBrush x:Key="{x:Static SystemColors.InfoTextBrushKey}" Color="Black" />
<Color x:Key="{x:Static SystemColors.InfoTextColorKey}">Black</Color>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Gray" />
<!--<SolidColorBrush x:Key="{x:Static SystemColors.ButtonHighlightBrushKey}" Color="#202020" />-->

Expand Down
17 changes: 17 additions & 0 deletions Console/Helpers/ColorGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Windows.Media;

namespace Wokhan.WindowsFirewallNotifier.Console.Helpers;

public static class ColorGenerator
{
public static readonly List<Color> Variations = [
Color.FromRgb(0x00, 0x3f, 0x5c),
Color.FromRgb(0x2f, 0x4b, 0x7c),
Color.FromRgb(0x66, 0x51, 0x91),
Color.FromRgb(0xa0, 0x51, 0x95),
Color.FromRgb(0xd4, 0x50, 0x87),
Color.FromRgb(0xf9, 0x5d, 0x6a),
Color.FromRgb(0xff, 0x7c, 0x43),
Color.FromRgb(0xff, 0xa6, 0x00)
];
}
6 changes: 4 additions & 2 deletions Console/UI/Controls/BandwidthDateTimePoint.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
namespace Wokhan.WindowsFirewallNotifier.Console.UI.Controls;
using Wokhan.WindowsFirewallNotifier.Console.ViewModels;

public record BandwidthDateTimePoint(DateTime DateTime, ulong? BandwidthIn = null, ulong? BandwidthOut = null);
namespace Wokhan.WindowsFirewallNotifier.Console.UI.Controls;

public record BandwidthDateTimePoint(DateTime DateTime, ulong? BandwidthIn = null, ulong? BandwidthOut = null, GroupedMonitoredConnections? Source = null);
5 changes: 4 additions & 1 deletion Console/UI/Controls/BandwidthGraph.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
xmlns:controls="clr-namespace:Wokhan.WindowsFirewallNotifier.Console.UI.Controls"
mc:Ignorable="d" x:Name="me"
d:DesignHeight="450" d:DesignWidth="800" ClipToBounds="True">
<UserControl.Resources>
<controls:BandwidthGraphTooltip x:Key="CustomTooltip" />
</UserControl.Resources>
<DockPanel>
<ContentControl Style="{StaticResource ToolBarPanel}">
<StackPanel>
Expand Down Expand Up @@ -37,6 +40,6 @@
</ScrollBar.Template>
</ScrollBar>
</Grid>
<charts:CartesianChart x:Name="chart" MouseEnter="chart_MouseEnter" MouseLeave="chart_MouseLeave" ZoomMode="X" TooltipTextSize="10" Series="{Binding Series}" DataContext="{Binding ElementName=me}" Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" Background="Transparent" />
<charts:CartesianChart x:Name="chart" Tooltip="{StaticResource CustomTooltip}" MouseEnter="chart_MouseEnter" MouseLeave="chart_MouseLeave" ZoomMode="X" TooltipTextSize="10" TooltipFindingStrategy="CompareOnlyX" TooltipPosition="Left" Series="{Binding Series}" DataContext="{Binding ElementName=me}" Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" Background="Transparent" />
</DockPanel>
</UserControl>
78 changes: 33 additions & 45 deletions Console/UI/Controls/BandwidthGraph.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using LiveChartsCore;
using LiveChartsCore.Drawing;
using LiveChartsCore.Kernel;
using LiveChartsCore.SkiaSharpView;
using LiveChartsCore.SkiaSharpView.Drawing.Geometries;
Expand Down Expand Up @@ -28,15 +29,15 @@ public partial class BandwidthGraph : UserControl, INotifyPropertyChanged

private const int MAX_DURATION_SEC = 10;

private ObservableDictionary<string, Tuple<ObservableCollection<BandwidthDateTimePoint>, ObservableCollection<BandwidthDateTimePoint>>> allSeries = new();
private readonly ObservableDictionary<string, Tuple<ObservableCollection<BandwidthDateTimePoint>, ObservableCollection<BandwidthDateTimePoint>>> allSeries = [];

private DateTime datetime = DateTime.Now;

private bool isXPanned;

private ObservableCollection<BandwidthDateTimePoint> seriesInTotal = new();
private readonly ObservableCollection<BandwidthDateTimePoint> seriesInTotal = [];

private ObservableCollection<BandwidthDateTimePoint> seriesOutTotal = new();
private readonly ObservableCollection<BandwidthDateTimePoint> seriesOutTotal = [];

private Axis xAxis;
private Axis yAxis;
Expand All @@ -55,16 +56,16 @@ public BandwidthGraph()

private void InitMiniGraph()
{
MiniSeries = new List<ISeries> {
new LineSeries<BandwidthDateTimePoint>() { Name = "In", Stroke = new SolidColorPaint(SKColors.LightGreen), GeometryStroke = null, GeometryFill = null, Values = seriesInTotal, Mapping = logMapper },
new LineSeries<BandwidthDateTimePoint>() { Name = "Out", Stroke = new SolidColorPaint(SKColors.OrangeRed), GeometryStroke = null, GeometryFill = null, Values = seriesOutTotal, Mapping = logMapper }
};
MiniSeries = [
new LineSeries<BandwidthDateTimePoint>() { Name = "In", Stroke = new SolidColorPaint(SKColors.LightGreen), GeometryStroke = null, GeometryFill = null, Values = seriesInTotal, Mapping = LogMapper },
new LineSeries<BandwidthDateTimePoint>() { Name = "Out", Stroke = new SolidColorPaint(SKColors.OrangeRed), GeometryStroke = null, GeometryFill = null, Values = seriesOutTotal, Mapping = LogMapper }
];
}


private void InitAxes()
{
var skAxisPaint = new SolidColorPaint(((SolidColorBrush)Application.Current.Resources[System.Windows.SystemColors.WindowTextBrushKey]).Color.ToSKColor());
var skAxisPaint = new SolidColorPaint(((Color)Application.Current.Resources[SystemColors.WindowTextColorKey]).ToSKColor());
crosshairPaint = new SolidColorPaint(SKColors.Red) { StrokeThickness = 1 };

xAxis = (Axis)chart.XAxes.First();
Expand All @@ -77,14 +78,15 @@ private void InitAxes()

yAxis = (Axis)chart.YAxes.First();
yAxis.MinLimit = 0;
yAxis.MinStep = 10;
yAxis.TextSize = 10;
yAxis.MinStep = 1;
yAxis.Labeler = (value) => value == 0 ? "0bps" : UnitFormatter.FormatValue(Math.Pow(10, value), "bps");
yAxis.LabelsPaint = skAxisPaint;
yAxis.CrosshairPaint = crosshairPaint;

var miniYAxis = miniChart.YAxes.First();
miniYAxis.MinLimit = 0;
miniYAxis.MinStep = 10;
miniYAxis.TextSize = 10;
miniYAxis.Padding = new LiveChartsCore.Drawing.Padding(0);
miniYAxis.ShowSeparatorLines = false;
Expand Down Expand Up @@ -123,31 +125,16 @@ public double CurrentStart
}
}
public IEnumerable<ISeries> MiniSeries { get; private set; }
public ObservableCollection<ISeries> Series { get; } = new();
public ObservableCollection<ISeries> Series { get; } = [];
public double ThumbSize => (xAxis is not null ? (xAxis.MaxLimit - xAxis.MinLimit) * scrollArea.Track.ActualWidth / (xAxis.DataBounds.Max - xAxis.DataBounds.Min) : 0) ?? 0;

private string tooltipFormatter(ChartPoint<BandwidthDateTimePoint, CircleGeometry, LabelGeometry> arg)
private Coordinate LogMapper(BandwidthDateTimePoint dateTimePoint, int _)
{
return $"{((LineSeries<BandwidthDateTimePoint>)arg.Context.Series).Tag} - In: {UnitFormatter.FormatValue(arg.PrimaryValue, "bps")} / Out: {UnitFormatter.FormatValue(arg.TertiaryValue, "bps")}";
var value = dateTimePoint.BandwidthIn ?? dateTimePoint.BandwidthOut ?? 0;
return new Coordinate(dateTimePoint.DateTime.Ticks, value == 0 ? 0 : Math.Log10(value));
}

private Coordinate logMapper(BandwidthDateTimePoint dateTimePoint, int _)
{
var value = (long)(dateTimePoint.BandwidthIn ?? dateTimePoint.BandwidthOut)!;

// Only points in the first series (IN bandwidth) have to store the secondary values for the legend
// We keep both in / out values since we don't want the log10 for them but the original values.
if (dateTimePoint.BandwidthIn is not null)
{
return new Coordinate(value == 0 ? 0 : Math.Log10(value), dateTimePoint.DateTime.Ticks, dateTimePoint.BandwidthIn ?? 0, dateTimePoint.BandwidthOut ?? 0, 0, 0, Error.Empty);
}
else
{
return new Coordinate(value == 0 ? 0 : Math.Log10(value), dateTimePoint.DateTime.Ticks);
}
}

readonly DashEffect outDashEffect = new DashEffect(new[] { 2f, 2f });
readonly DashEffect outDashEffect = new([2f, 2f]);

public void UpdateGraph()
{
Expand All @@ -170,19 +157,18 @@ public void UpdateGraph()
{
seriesInValues = [];
seriesOutValues = [];

var color = connectionGroup.Key.Color.ToSKColor();
var inStroke = new SolidColorPaint(color) { StrokeThickness = 2 };
var outStroke = new SolidColorPaint(color) { StrokeThickness = 2, PathEffect = outDashEffect };

Series.Add(new LineSeries<BandwidthDateTimePoint>() { Tag = connectionGroup.Key.Path, Name = $"{connectionGroup.Key} - In", XToolTipLabelFormatter = tooltipFormatter, Fill = null, Stroke = inStroke, GeometryStroke = inStroke, Values = seriesInValues, LineSmoothness = 0, Mapping = logMapper });
Series.Add(new LineSeries<BandwidthDateTimePoint>() { Tag = connectionGroup.Key.Path, Name = $"{connectionGroup.Key} - Out", IsVisibleAtLegend = false, IsHoverable = false, Fill = null, Stroke = outStroke, GeometryStroke = outStroke, Values = seriesOutValues, LineSmoothness = 0, Mapping = logMapper });

Series.Add(new LineSeries<BandwidthDateTimePoint>() { Tag = connectionGroup.Key, Name = $"{connectionGroup.Key.FileName} ({connectionGroup.Key.ProcessId}) - In", Fill = null, Stroke = inStroke, GeometryStroke = inStroke, Values = seriesInValues, LineSmoothness = 0, Mapping = LogMapper });
Series.Add(new LineSeries<BandwidthDateTimePoint, SquareGeometry>() { Name = $"{connectionGroup.Key.FileName} ({connectionGroup.Key.ProcessId}) - Out", Fill = null, Stroke = outStroke, GeometryStroke = outStroke, Values = seriesOutValues, LineSmoothness = 0, Mapping = LogMapper });
allSeries.Add(connectionGroup.Key.Path, Tuple.Create(seriesInValues, seriesOutValues));
}

AddAndMergePoints(seriesInValues, connectionGroup.Key.InboundBandwidth, connectionGroup.Key.OutboundBandwidth);
AddAndMergePoints(seriesOutValues, bandwidthOut: connectionGroup.Key.OutboundBandwidth);
AddAndMergePoints(connectionGroup.Key, seriesInValues, seriesOutValues);

totalIn += connectionGroup.Key.InboundBandwidth;
totalOut += connectionGroup.Key.OutboundBandwidth;
Expand All @@ -208,17 +194,19 @@ public void UpdateGraph()
}
}

private void AddAndMergePoints(ObservableCollection<BandwidthDateTimePoint> series, ulong? bandwidthIn = null, ulong? bandwidthOut = null)

private void AddAndMergePoints(GroupedMonitoredConnections group, ObservableCollection<BandwidthDateTimePoint> seriesIn, ObservableCollection<BandwidthDateTimePoint> seriesOut)
{
if (series.Count == 0
|| (bandwidthIn == 0 && (series[^1].BandwidthIn != 0 || bandwidthOut is not null and not 0))
|| (bandwidthOut == 0 && series[^1].BandwidthOut != 0))
bool isOut = group.OutboundBandwidth != 0 || (seriesOut.Count > 0 && seriesOut[^1].BandwidthOut != 0);
if (isOut || group.OutboundBandwidth != 0 || group.InboundBandwidth != 0 || (seriesIn.Count > 0 && seriesIn[^1].BandwidthIn != 0))
{
// Adding both inbound and outbound bandwidth as they will be used in the tooltip
seriesIn.Add(new BandwidthDateTimePoint(datetime, group.InboundBandwidth, group.OutboundBandwidth, group));
}

if (isOut)
{
series.Add(new BandwidthDateTimePoint(datetime, bandwidthIn, bandwidthOut));
//if (series.Count > 3 && series[^2].Value == sum && series[^3].Value == sum)
//{
// series.RemoveAt(series.Count - 2);
//}
seriesOut.Add(new BandwidthDateTimePoint(datetime, BandwidthOut: group.OutboundBandwidth));
}
}

Expand Down
Loading

0 comments on commit dbe37c7

Please sign in to comment.