-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathForm1.vb
3250 lines (2434 loc) · 121 KB
/
Form1.vb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
Imports Newtonsoft.Json.Linq
Imports System.ComponentModel
Imports System.IO
Imports System.Net
Imports System.Net.Mail
Imports System.Text.RegularExpressions
Imports Tulpep.NotificationWindow
Public Class Form1
'New class based on webclient that allows timeout to be changed
Public Class WebDownload
Inherits WebClient
Public Property Timeout As Integer
Public Sub New()
Me.New(60000)
End Sub
Public Sub New(ByVal timeout As Integer)
Me.Timeout = timeout
End Sub
Protected Overrides Function GetWebRequest(ByVal address As Uri) As WebRequest
Dim request = MyBase.GetWebRequest(address)
If request IsNot Nothing Then
request.Timeout = Me.Timeout
End If
Return request
End Function
End Class
'Declare global variables
Dim parsejson As JObject 'JSON Object to hold API data
Dim json As String
Dim MaxBlockHeight As Integer
Dim CurrentAgentVersion As String
Dim LastAPIUpdate As Date
Dim ForceCloseFlag As Boolean
Dim StatusColour As String
Dim UpToDateColour As String
Dim CurrentColour As String
Dim LogFileName As String
Dim MapCacheFileName As String
Dim JSONFileName As String
Dim IPLocations(,) As String
Dim CacheCounter As Integer = 0
Dim MapRefreshCounter As Integer = 0
Dim FileWriteThread As Threading.Thread
Dim FormLoadComplete As Boolean = False
Dim PortArray(,) As Integer
Dim imageMarker As Image
ReadOnly All As String = "- All -"
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try
'Create an instance of the splashscreen
Dim SplashScreen As Splash = New Splash
'Show the splashscreen
SplashScreen.Show()
'Initialise logging
Setup_Logging()
'Load persistent notification settings required for logging
chkApplicationNotification.Checked = My.Settings.ApplicationNotification
chkWindowsNotification.Checked = My.Settings.WindowsNotification
chkAllowLogging.Checked = My.Settings.AllowLogging
chkAllowEmailNotification.Checked = My.Settings.AllowEmailNotification
comAppNotifLvl.Text = My.Settings.ApplicationNotificationLevel
comWinNotifLvl.Text = My.Settings.WindowsNotificationLevel
comLogLvl.Text = My.Settings.LoggingLevel
comEmailNotifLvl.Text = My.Settings.EmailNotificationLevel
Notification_Display("Information", "Application Load has started")
'Load remaining persistent settings
CurrentAgentVersion = My.Settings.CurrentAgentVersion
comStatistics.Text = My.Settings.Statistics
lblGreenToYellow.Text = My.Settings.GreenToYellow
lblYellowToRed.Text = My.Settings.YellowToRed
txtIPAddress.Text = My.Settings.IPAddress
txtPort.Text = My.Settings.NodePort
chkHideTrayIcon.Checked = My.Settings.HideTrayIcon
chkMinimiseToTray.Checked = My.Settings.MinimiseToTray
chkMinimiseOnClose.Checked = My.Settings.MinimiseOnClose
comStartup.Text = My.Settings.StartupTab
txtSMTPHost.Text = My.Settings.SMTPHost
txtSMTPPort.Text = My.Settings.SMTPPort
txtSMTPUsername.Text = My.Settings.SMTPUsername
txtSMTPPassword.Text = My.Settings.SMTPPassword
chkUseSSL.Checked = My.Settings.UseSSL
txtEmailAddress.Text = My.Settings.EmailAddress
chkStartMinimised.Checked = My.Settings.StartMinimised
chkStartWithWindows.Checked = My.Settings.StartWithWindows
chkDesktopShortcut.Checked = My.Settings.DesktopShortcut
chkShowTooltips.Checked = My.Settings.ShowTooltips
chkHighlightCurrentNode.Checked = My.Settings.HighlightNode
'check if help file present and then update visibility of inline help section on Help tab
If File.Exists(Application.StartupPath() + "/DogeNodes.chm") Then
gbxInlineHelp.Visible = True
Else
gbxInlineHelp.Visible = False
End If
'Update sliders to persistent values
trkGreenToYellow.Value = lblGreenToYellow.Text
trkYellowToRed.Value = lblYellowToRed.Text
'Display application version information and prompt user if a new version is available
DogeNodes_Version()
If btnUpdateNow.Enabled = True Then
MessageBox.Show("A new version of DogeNodes is available. Please click on the 'Update Now' button in settings to update", "DogeNodes - Update Available", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
'Configure map control on node map tab
Configure_Map_Control()
'Get map tile cache size
Check_Map_Cache_size()
'Set up map location cache
Set_Up_Map_Cache()
'Initialise JSON Persistence
Set_Up_JSON_Persistence()
'Load IP Locations into array
Read_IP_Locations()
'Read last json string into global variable
Read_JSON_String()
'Get current agent version (Not Blockchair API dependent)
Get_Current_Agent_Version()
'Load data from web URL into the JSON Object and populate application fields
Load_JSON()
'Configure shortcuts
Configure_Desktop_Shortcut()
Configure_Startup_Shortcut()
'Center application on screen
Me.CenterToScreen()
'Check if set to start minimised
If chkStartMinimised.Checked = True Then
WindowState = FormWindowState.Minimized
Else
WindowState = FormWindowState.Normal
End If
'Set visibility of tray icon
Notify_Icon_Display()
'set up timer
timReloadData.Interval = 5000
timReloadData.Enabled = True
'Initial Check (Will be repeated at each timer tick)
Check_For_API_Update()
'Enable or disable the Force Close Button in settings
Set_Force_Close_Button_Visibility()
'Set Force close flag to false
ForceCloseFlag = False
'Update enabled controls in settings based on checkbox values
Disable_Logging_Settings()
Disable_Application_Notification_Settings()
Disable_Windows_Notification_Settings()
Disable_Email_Notification_Settings()
'Open startup tab
Open_Startup_Tab()
'Start cache update process
timUpdateCache.Enabled = True
'Set up tooltips
Configure_Tooltips()
'Flag to indicate if form has finished loading.
FormLoadComplete = True
'Close the splashscreen
SplashScreen.Close()
Notification_Display("Information", "Application load completed successfully")
Catch ex As Exception
Notification_Display("Error", "There was an error in the application load", ex)
End Try
End Sub
Private Sub Load_JSON()
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
Try
Notification_Display("Information", "The latest API download from blockchair has started")
json = New WebDownload(2000).DownloadString("https://api.blockchair.com/dogecoin/nodes")
Notification_Display("Information", "The latest API download from blockchair has completed successfully")
Catch ex As Exception
If json <> "" Then
Notification_Display("Error", "Blockchair API is unreachable. Please check network connection", ex)
'Carry on with rest of subroutine using the last value of json stored in the global variable
Else
'No global variable, so put out message and close application
MessageBox.Show("Internet connection required for application. Please try again later. Application will close", "DogeNodes - Critical Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End
End If
End Try
Try
'Create JSON Object from string
parsejson = JObject.Parse(json)
'Save Last Updated date
LastAPIUpdate = Convert.ToDateTime(Get_Token("context.cache.since"))
'Update the last updated date in status bar in local time
sslLastUpdate.Text = "Last Updated: " + LastAPIUpdate.ToLocalTime.ToString
'Create the array for use in port statistics and port filter dropdown
Create_Port_Array()
'Store maximum block height
Get_Maximum_Block_Height()
'Populate total node count on summary tab
lblTotalNodesValue.Text = Get_Token("data.count")
'populate controls on node status tab
Populate_NodeStatusTab()
'populate Statistics
Display_Statistics()
'Load country dropdown list
Load_Country_Dropdown()
'Load height dropdown list
Load_Height_Dropdown()
'Load version dropdown list
Load_Version_Dropdown()
'Load network dropdown list
Load_Network_Dropdown()
'Load port dropdown list
Load_Port_Dropdown()
'Reset Filters as new data may not contain selections
comCountry.Text = All
comHeight.Text = All
ComVersion.Text = All
comNetwork.Text = All
comPort.Text = All
'populate Node List
Load_Nodes_Datagrid()
Notification_Display("Information", "The JSON Load has completed successfully")
Catch ex As Exception
Notification_Display("Error", "There was an error in the JSON load", ex)
End Try
End Sub
Private Sub Populate_NodeStatusTab()
Dim NodeList As String
Dim ParseNode As JObject
Dim Status As Boolean
Dim Lag As Integer
Dim Protocol As String
Try
Protocol = Validate_IPAddress(txtIPAddress.Text)
'Check if both IP Address and Port are supplied with valid contents
If txtIPAddress.Text = "" Or txtPort.Text = "" Or Protocol = "Invalid" Or Validate_Port(txtPort.Text) = False Then
'Clear Details
lblVersionValue.Text = ""
lblCountryValue.Text = ""
lblHeightValue.Text = ""
lblProtocolValue.Text = ""
'Clear Status indicators
pbxStatus.Image = My.Resources.Grey
StatusColour = "Grey"
pbxUpToDate.Image = My.Resources.Grey
UpToDateColour = "Grey"
pbxCurrent.Image = My.Resources.Grey
CurrentColour = "Grey"
Notification_Display("Warning", "IP Address or Port are invalid")
Else
Notification_Display("Information", "IP Address and Port are valid")
'IP Address valid, so call routine to get additional IP Address information
Populate_IP_Address_Details()
'Return the data about an individual Node
NodeList = parsejson.SelectToken("data.nodes").ToString
ParseNode = JObject.Parse(NodeList)
'Update Details
If ParseNode.ContainsKey(txtIPAddress.Text + ":" + txtPort.Text) Then
'Save Status for later
Status = True
'Populate Details
lblVersionValue.Text = Get_Token("data.nodes.['" + txtIPAddress.Text + ":" + txtPort.Text + "'].version")
lblCountryValue.Text = Get_Token("data.nodes.['" + txtIPAddress.Text + ":" + txtPort.Text + "'].country")
lblHeightValue.Text = Get_Token("data.nodes.['" + txtIPAddress.Text + ":" + txtPort.Text + "'].height")
lblProtocolValue.Text = Protocol
Else
'Save Status for later
Status = False
'Clear Details
lblVersionValue.Text = ""
lblCountryValue.Text = ""
lblHeightValue.Text = ""
lblProtocolValue.Text = ""
End If
'Update Status Indicator
If Status = True Then
pbxStatus.Image = My.Resources.Green
StatusColour = "Green"
Notification_Display("Information", "Node is online")
Else
pbxStatus.Image = My.Resources.Red
StatusColour = "Red"
Notification_Display("Warning", "Node is offline")
End If
'Update Up-To-Date Indicator
If Status = True Then
Lag = MaxBlockHeight - lblHeightValue.Text
If Lag < 0 Then
pbxUpToDate.Image = My.Resources.Grey
UpToDateColour = "Grey"
Notification_Display("Warning", "Node block height is invalid")
ElseIf Lag >= 0 And Lag < lblGreenToYellow.Text Then
pbxUpToDate.Image = My.Resources.Green
UpToDateColour = "Green"
Notification_Display("Information", "Node block height is up to date")
ElseIf Lag >= lblGreenToYellow.Text And Lag < lblYellowToRed.Text Then
pbxUpToDate.Image = My.Resources.Yellow
UpToDateColour = "Yellow"
Notification_Display("Warning", "Node block height is slightly behind")
Else
pbxUpToDate.Image = My.Resources.Red
UpToDateColour = "Red"
Notification_Display("Warning", "Node block height is significantly behind")
End If
Else
pbxUpToDate.Image = My.Resources.Grey
UpToDateColour = "Grey"
End If
'Update Current Indicator
If Status = True Then
Dim AgentVersion As String = lblVersionValue.Text
If AgentVersion.Length < 12 Then
pbxCurrent.Image = My.Resources.Grey
CurrentColour = "Grey"
Notification_Display("Warning", "Agent version not recognised")
ElseIf AgentVersion.Remove(12) <> "/Shibetoshi:" Then
pbxCurrent.Image = My.Resources.Grey
CurrentColour = "Grey"
Notification_Display("Warning", "Agent version not recognised")
ElseIf AgentVersion.Length < CurrentAgentVersion.Length Then
pbxCurrent.Image = My.Resources.Red
CurrentColour = "Red"
Notification_Display("Warning", "Agent version is out of date")
ElseIf AgentVersion.Remove(CurrentAgentVersion.Length) <> CurrentAgentVersion Then
pbxCurrent.Image = My.Resources.Red
CurrentColour = "Red"
Notification_Display("Warning", "Agent version is out of date")
Else
pbxCurrent.Image = My.Resources.Green
CurrentColour = "Green"
Notification_Display("Information", "Agent version is up to date")
End If
Else
pbxCurrent.Image = My.Resources.Grey
CurrentColour = "Grey"
End If
End If
're-populate the node map if current node is displayed on map
If chkHighlightCurrentNode.Checked = True Then
Populate_Node_Map()
End If
'Set the tray icon appearance dependent on status
Set_Tray_Icon_Appearance()
Notification_Display("Information", "Population of the node status tab has completed successfully")
Catch ex As Exception
Notification_Display("Error", "There was an error populating the node status tab", ex)
End Try
End Sub
Private Sub sslError_Click(sender As Object, e As EventArgs) Handles sslError.Click
'clear error message in the status bar
Clear_Application_Notification()
End Sub
Private Sub Notification_Display(Severity As String, Message As String, Optional ex As Exception = Nothing)
Try
'display notification in the appropriate places
If chkApplicationNotification.Checked = True Then
If comAppNotifLvl.Text = "Warning and Error" And Severity <> "Information" Then Display_Application_Notification(Severity, Message)
If comAppNotifLvl.Text = "Error Only" And Severity = "Error" Then Display_Application_Notification(Severity, Message)
End If
If chkWindowsNotification.Checked = True Then
If comWinNotifLvl.Text = "Warning and Error" And Severity <> "Information" Then Display_Windows_Notification(Severity, Message)
If comWinNotifLvl.Text = "Error Only" And Severity = "Error" Then Display_Windows_Notification(Severity, Message)
End If
If chkAllowLogging.Checked = True Then
If comLogLvl.Text = "Everything" Then Log_Notification(Severity, Message)
If comLogLvl.Text = "Warning and Error" And Severity <> "Information" Then Log_Notification(Severity, Message)
If comLogLvl.Text = "Error Only" And Severity = "Error" Then Log_Notification(Severity, Message)
If comLogLvl.Text = "Debug" And Severity = "Error" And Not ex Is Nothing Then Log_Notification(Severity, Message, ex)
End If
If chkAllowEmailNotification.Checked = True Then
If comEmailNotifLvl.Text = "Warning and Error" And Severity <> "Information" Then Send_Email_Notification(Severity, Message)
If comEmailNotifLvl.Text = "Error Only" And Severity = "Error" Then Send_Email_Notification(Severity, Message)
End If
Catch
sslError.Text = "There has been a critical error in the notification display flow"
sslError.BackColor = Color.Red
sslError.ForeColor = Color.White
End Try
End Sub
Private Sub Display_Application_Notification(Severity As String, Message As String)
Try
'display notification in the status bar
sslError.Text = Message
Select Case Severity
Case "Warning"
sslError.BackColor = Color.Yellow
sslError.ForeColor = Color.Black
Case "Error"
sslError.BackColor = Color.Red
sslError.ForeColor = Color.White
End Select
'Set Timer to 8 seconds to clear notification
timClearError.Interval = 8000
'Reset timer in case its already running
timClearError.Enabled = False
timClearError.Enabled = True
Catch
sslError.Text = "There has been a critical error in the application notification display"
sslError.BackColor = Color.Red
sslError.ForeColor = Color.White
End Try
End Sub
Private Sub Clear_Application_Notification()
'Clear notification in the status bar
sslError.Text = ""
sslError.BackColor = Control.DefaultBackColor
End Sub
Private Function Get_Token(Token As String) As String
Dim Value As String
Try
'Get a single token from the JSON object
Value = parsejson.SelectToken(Token).ToString
Notification_Display("Information", "The value of " + Value + " was returned successfully for token " + Token)
Catch ex As Exception
Notification_Display("Error", "There was a problem retrieving a value for token " + Token, ex)
Value = ""
End Try
Return Value
End Function
Private Sub txtIPAddress_TextChanged(sender As Object, e As EventArgs) Handles txtIPAddress.TextChanged
'Only refresh if user making change
If TabControl1.SelectedTab Is tabNodestatus Then
'Reset timer. Node status tab will be refreshed when the timer elapsed
timTextbox.Enabled = False
timTextbox.Enabled = True
End If
End Sub
Private Sub txtPort_TextChanged(sender As Object, e As EventArgs) Handles txtPort.TextChanged
'Only refresh if user making change
If TabControl1.SelectedTab Is tabNodestatus Then
'Reset timer. Node status tab will be refreshed when the timer elapsed
timTextbox.Enabled = False
timTextbox.Enabled = True
End If
End Sub
Private Function Validate_IPAddress(Input As String) As String
Dim Result As String
Try
'Check if supplied string is a valid IP Address
If Regex.IsMatch(Input, "\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b") Then
Result = "IPv4"
ElseIf Regex.IsMatch(Input, "(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))") Then
Result = "IPv6"
Else
Result = "Invalid"
End If
Notification_Display("Information", "The IP Address " + Input + " was found to be " + Result)
Catch ex As Exception
Notification_Display("Error", "There was an error in validating the IP Address " + Input, ex)
Result = ""
End Try
Return Result
End Function
Private Function Validate_Port(Input As String) As Boolean
Dim Valid As Boolean
Try
'Check if supplied string is a valid Port
Valid = Regex.IsMatch(Input, "^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$")
Notification_Display("Information", "The port " + Input + " was found to be " + Valid.ToString)
Catch ex As Exception
Notification_Display("Error", "There was an error in validating the port " + Input, ex)
Valid = Nothing
End Try
Return Valid
End Function
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles timReloadData.Tick
Check_For_API_Update()
End Sub
Private Sub Load_Country_Datagrid()
'Local Variables
Dim Country As String()
Dim Count As Integer = 0
Dim MaxResult As Integer
Try
Dim parsecountry As JObject = parsejson.SelectToken("data.countries")
Dim countries As List(Of JToken) = parsecountry.Children().ToList()
'Set appropriate column header
grdStatistics.Columns(0).HeaderText = "Country"
'Populate data to rows and columns
For Each JToken In countries
Country = JToken.ToString.Split(New Char() {":"c})
Country(0) = Country(0).Trim("""")
grdStatistics.Rows.Add()
grdStatistics.Rows(Count).Cells(0).Value = Country(0)
grdStatistics.Rows(Count).Cells(1).Value = Country(1)
If Count = 0 Then MaxResult = Country(1)
'Display Status Bar
grdStatistics.Rows(Count).Cells(2).Value = BarChartText(MaxResult, Country(1))
Count += 1
Next
'Display Row Count
lblRowCount.Text = Count.ToString
lblRows.Text = "Countries"
Notification_Display("Information", "The country datagrid was loaded successfully with " + Count.ToString + " rows")
Catch ex As Exception
Notification_Display("Error", "There was an error in loading the country datagrid", ex)
End Try
End Sub
Private Sub Load_Height_Datagrid()
'Local Variables
Dim Height As String()
Dim Count As Integer = 0
Dim MaxResult As Integer
Try
Dim parseheight As JObject = parsejson.SelectToken("data.heights")
Dim heights As List(Of JToken) = parseheight.Children().ToList()
'Set appropriate column header
grdStatistics.Columns(0).HeaderText = "Height"
'Populate data to rows and columns
For Each JToken In heights
Height = JToken.ToString.Split(New Char() {":"c})
Height(0) = Height(0).Trim("""")
grdStatistics.Rows.Add()
grdStatistics.Rows(Count).Cells(0).Value = Height(0)
grdStatistics.Rows(Count).Cells(1).Value = Height(1)
If Count = 0 Then MaxResult = Height(1)
'Display Status Bar
grdStatistics.Rows(Count).Cells(2).Value = BarChartText(MaxResult, Height(1))
Count += 1
Next
'Display Row Count
lblRowCount.Text = Count.ToString
lblRows.Text = "Heights"
Notification_Display("Information", "The height datagrid was loaded successfully with " + Count.ToString + " rows")
Catch ex As Exception
Notification_Display("Error", "There was an error in loading the height datagrid", ex)
End Try
End Sub
Private Sub Load_Version_Datagrid()
'Local Variables
Dim VersionString As String
Dim Version As String()
Dim Count As Integer = 0
Dim MaxResult As Integer
Try
Dim parseversion As JObject = parsejson.SelectToken("data.versions")
Dim versions As List(Of JToken) = parseversion.Children().ToList()
grdStatistics.Columns(0).HeaderText = "Version"
'Populate data to rows and columns
For Each JToken In versions
VersionString = JToken.ToString.Replace(": ", ":" + ChrW(&H2588))
Version = VersionString.Split(New Char() {ChrW(&H2588)})
Version(0) = Version(0).Trim(":")
Version(0) = Version(0).Trim("""")
grdStatistics.Rows.Add()
grdStatistics.Rows(Count).Cells(0).Value = Version(0)
grdStatistics.Rows(Count).Cells(1).Value = Version(1)
If Count = 0 Then MaxResult = Version(1)
'Display Status Bar
grdStatistics.Rows(Count).Cells(2).Value = BarChartText(MaxResult, Version(1))
Count += 1
Next
'Display Row Count
lblRowCount.Text = Count.ToString
lblRows.Text = "Versions"
Notification_Display("Information", "The version datagrid was loaded successfully with " + Count.ToString + " rows")
Catch ex As Exception
Notification_Display("Error", "There was an error in loading the version datagrid", ex)
End Try
End Sub
Private Sub Load_Protocol_Datagrid()
'Local Variables
Dim Token As String()
Dim IPv6 As Integer = 0
Dim IPv4 As Integer = 0
Dim MaxResult As Integer
Try
Dim parsenodes As JObject = parsejson.SelectToken("data.nodes")
Dim nodes As List(Of JToken) = parsenodes.Children().ToList()
grdStatistics.Columns(0).HeaderText = "Protocol"
'Calculate counts of protocols
For Each JToken In nodes
Token = JToken.ToString.Split(New Char() {""""c})
If Token(1).Contains(".") Then
IPv4 += 1
Else
IPv6 += 1
End If
Next
grdStatistics.Rows.Add(2)
If IPv4 > IPv6 Then
MaxResult = IPv4
grdStatistics.Rows(0).Cells(0).Value = "IPv4"
grdStatistics.Rows(0).Cells(1).Value = IPv4
grdStatistics.Rows(0).Cells(2).Value = BarChartText(MaxResult, IPv4)
grdStatistics.Rows(1).Cells(0).Value = "IPv6"
grdStatistics.Rows(1).Cells(1).Value = IPv6
grdStatistics.Rows(1).Cells(2).Value = BarChartText(MaxResult, IPv6)
Else
MaxResult = IPv6
grdStatistics.Rows(0).Cells(0).Value = "IPv6"
grdStatistics.Rows(0).Cells(1).Value = IPv6
grdStatistics.Rows(0).Cells(2).Value = BarChartText(MaxResult, IPv6)
grdStatistics.Rows(1).Cells(0).Value = "IPv4"
grdStatistics.Rows(1).Cells(1).Value = IPv4
grdStatistics.Rows(1).Cells(2).Value = BarChartText(MaxResult, IPv4)
End If
'Display Row Count
lblRowCount.Text = 2
lblRows.Text = "Protocols"
Notification_Display("Information", "The protocol datagrid was loaded successfully with 2 rows")
Catch ex As Exception
Notification_Display("Error", "There was an error in loading the protocol datagrid", ex)
End Try
End Sub
Private Sub Load_Port_Datagrid()
'Local Variables
Dim Count As Integer
Dim MaxResult As Integer = 0
Try
'Set appropriate column header
grdStatistics.Columns(0).HeaderText = "Port"
'Populate data to rows and columns and get the highest count of ports
For Count = 0 To PortArray.GetLength(1) - 2 'Last row in array is blank
grdStatistics.Rows.Add()
grdStatistics.Rows(Count).Cells(0).Value = PortArray(0, Count)
grdStatistics.Rows(Count).Cells(1).Value = PortArray(1, Count)
If PortArray(1, Count) > MaxResult Then MaxResult = PortArray(1, Count)
Next
'Sort datagrid on count descending
grdStatistics.Sort(grdStatistics.Columns(1), ListSortDirection.Descending)
'Display Status Bars
For i As Integer = 0 To Count - 1
grdStatistics.Rows(i).Cells(2).Value = BarChartText(MaxResult, grdStatistics.Rows(i).Cells(1).Value)
Next
'Display Row Count
lblRowCount.Text = Count.ToString
lblRows.Text = "Ports"
Notification_Display("Information", "The port datagrid was loaded successfully with " + Count.ToString + " rows")
Catch ex As Exception
Notification_Display("Error", "There was an error in loading the port datagrid", ex)
End Try
End Sub
Private Sub Display_Statistics()
Try
'Clear Datagrid
grdStatistics.Rows.Clear()
'Choose correct method to populate datagrid
If comStatistics.Text = "Country" Then
Load_Country_Datagrid()
ElseIf comStatistics.Text = "Height" Then
Load_Height_Datagrid()
ElseIf comStatistics.Text = "Version" Then
Load_Version_Datagrid()
ElseIf comStatistics.Text = "Protocol" Then
Load_Protocol_Datagrid()
ElseIf comStatistics.Text = "Port" Then
Load_Port_Datagrid()
Else
'If selection not recognised then default to Country
comStatistics.Text = "Country"
Load_Country_Datagrid()
End If
Notification_Display("Information", "The statistics datagrid has been successfully selected as " + comStatistics.Text)
Catch ex As Exception
Notification_Display("Error", "There was an error in selecting the statistics datagrid", ex)
End Try
End Sub
Private Sub comStatistics_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles comStatistics.SelectionChangeCommitted
Display_Statistics()
'Remove Focus from dropdown by setting focus to label (Any non editable control would do)
lblStatisticsSelect.Focus()
End Sub
Private Function BarChartText(Maximum As Integer, Value As Integer) As String
'Return a string of blocks whose length relates to the percentage of maximum value
Dim BarChart As String = ""
Try
Dim Count As Decimal = 27 * Value / Maximum
Dim CountInt As Integer = Math.Truncate(Count)
Count -= CountInt
While CountInt > 0
BarChart += ChrW(&H2589)
CountInt -= 1
End While
If CountInt = 0 And Count < 0.25 Then BarChart += ChrW(&H258F)
If Count > 0.25 And Count <= 0.5 Then BarChart += ChrW(&H258F)
If Count > 0.5 And Count <= 0.75 Then BarChart += ChrW(&H258E)
If Count > 0.75 And Count < 1 Then BarChart += ChrW(&H258D)
Catch ex As Exception
Notification_Display("Error", "There was an error generating the barchart text", ex)
End Try
Return BarChart
End Function
Private Sub Load_Nodes_Datagrid()
'Local Variables
Dim Token As String()
Dim Node As String()
Dim Height As String = ""
Dim Count As Integer = 0
Dim Include As Boolean
Dim IPAddress As String
Dim Port As String
Dim n As Integer
Try
Dim parsenodes As JObject = parsejson.SelectToken("data.nodes")
Dim nodes As List(Of JToken) = parsenodes.Children().ToList()
'Clear Node List
grdNodeList.Rows.Clear()
'Populate data to rows and columns
For Each JToken In nodes
Token = JToken.ToString.Split(New Char() {""""c})
Include = True
'Filter By country, height and version
If comCountry.Text <> All And Token(9) <> comCountry.Text Then Include = False
If comHeight.Text <> All Then Height = Regex.Replace(Token(12), "[^\d]", "")
If comHeight.Text <> All And Height <> comHeight.Text Then Include = False
If ComVersion.Text <> All And Token(5) <> ComVersion.Text Then Include = False
'Continue if meets country, height and version filters
If Include = True Then
Node = Token(1).Split(New Char() {":"c})
IPAddress = Node(0)
For n = 1 To Node.Length - 2
IPAddress += ":" + Node(n)
Next
Port = Node(Node.Length - 1)
IPAddress = IPAddress.Trim("""")
Port = Port.Trim("""")
'Filter by network protocol and port
If comNetwork.Text = All Or (comNetwork.Text = "IPv4" And IPAddress.Contains(".")) Or (comNetwork.Text = "IPv6" And IPAddress.Contains(":")) Then
If comPort.Text = All Or comPort.Text = Port Then
grdNodeList.Rows.Add()
grdNodeList.Rows(Count).Cells(0).Value = IPAddress
grdNodeList.Rows(Count).Cells(1).Value = Port
Count += 1
End If
End If
End If
Next
'Display number of nodes found
lblNodeRowsCount.Text = Count.ToString
'Redraw the nodes map
Populate_Node_Map()
Notification_Display("Information", "The nodes datagrid was loaded successfully with " + Count.ToString + " rows")
Catch ex As Exception
Notification_Display("Error", "There was an error in loading the nodes datagrid", ex)
End Try
End Sub
Private Sub Load_Country_Dropdown()
'Local Variables
Dim Country As String()
Try
Dim parsecountry As JObject = parsejson.SelectToken("data.countries")
Dim countries As List(Of JToken) = parsecountry.Children().ToList()
'Clear existing list
comCountry.Items.Clear()
'Add an All option at start of list
comCountry.Items.Add(All)
'Populate data to dropdown list
For Each JToken In countries
Country = JToken.ToString.Split(New Char() {":"c})
Country(0) = Country(0).Trim("""")
comCountry.Items.Add(Country(0))
Next
Notification_Display("Information", "The country dropdown has been populated successfully")
Catch ex As Exception
Notification_Display("Error", "There was an error populating the country dropdown", ex)
End Try
End Sub
Private Sub Load_Height_Dropdown()
'Local Variables
Dim Height As String()
Try
Dim parseheight As JObject = parsejson.SelectToken("data.heights")
Dim heights As List(Of JToken) = parseheight.Children().ToList()
'Clear existing list
comHeight.Items.Clear()
'Add an All option at start of list
comHeight.Items.Add(All)